From 87cc7b143435e5427b2e4447247b7d03f316c6fa Mon Sep 17 00:00:00 2001 From: Daniel <d.hornung@indiscale.com> Date: Wed, 8 Nov 2023 16:24:31 +0100 Subject: [PATCH] MAINT: jsex: ui schema export: boolean param, variadic return value --- src/caosadvancedtools/json_schema_exporter.py | 37 +++++++++------- unittests/test_json_schema_exporter.py | 44 ++++++++----------- 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/caosadvancedtools/json_schema_exporter.py b/src/caosadvancedtools/json_schema_exporter.py index c4af88ce..b699c233 100644 --- a/src/caosadvancedtools/json_schema_exporter.py +++ b/src/caosadvancedtools/json_schema_exporter.py @@ -300,7 +300,8 @@ class JsonSchemaExporter: return schema, ui_schema - def recordtype_to_json_schema(self, rt: db.RecordType, rjsf_uischema: Optional[dict] = None): + def recordtype_to_json_schema(self, rt: db.RecordType, rjsf: bool = False) -> Union[ + dict, Tuple[dict, dict]]: """Create a jsonschema from a given RecordType that can be used, e.g., to validate a json specifying a record of the given type. @@ -308,28 +309,31 @@ class JsonSchemaExporter: ---------- rt : RecordType The RecordType from which a json schema will be created. - rjsf_uischema : dict, optional - If given, uiSchema definitions for react-jsonschema-forms will be appended to this dict - at ``[rt.name]``. + rjsf : bool, optional + If True, uiSchema definitions for react-jsonschema-forms will be output as the second + return value. Default is False Returns ------- schema : dict A dict containing the json schema created from the given RecordType's properties. + + ui_schema : dict, optional + A ui schema. Only if a parameter asks for it (e.g. ``rjsf``). """ if rt is None: raise ValueError( "recordtype_to_json_schema(...) cannot be called with a `None` RecordType.") - if rjsf_uischema is None: - rjsf_uischema = {} - schema, inner_uischema = self._make_segment_from_recordtype(rt) - if inner_uischema: - rjsf_uischema[rt.name] = inner_uischema schema["$schema"] = "https://json-schema.org/draft/2020-12/schema" if rt.description: schema["description"] = rt.description + if rjsf: + uischema = {} + if inner_uischema: + uischema = inner_uischema + return schema, uischema return schema @@ -342,8 +346,8 @@ def recordtype_to_json_schema(rt: db.RecordType, additional_properties: bool = T do_not_retrieve: List[str] = None, no_remote: bool = False, multiple_choice: List[str] = None, - rjsf_uischema: Optional[dict] = None, - ): + rjsf: bool = False, + ) -> Union[dict, Tuple[dict, dict]]: """Create a jsonschema from a given RecordType that can be used, e.g., to validate a json specifying a record of the given type. @@ -385,14 +389,17 @@ def recordtype_to_json_schema(rt: db.RecordType, additional_properties: bool = T A list of reference Property names which shall be denoted as multiple choice properties. This means that each option in this property may be selected at most once. This is not implemented yet if the Property is not in ``do_not_create`` as well. - rjsf_uischema : dict, optional - If given, uiSchema definitions for react-jsonschema-forms will be appended to this dict. + rjsf : bool, optional + If True, uiSchema definitions for react-jsonschema-forms will be output as the second return + value. Default is False. Returns ------- schema : dict A dict containing the json schema created from the given RecordType's properties. + ui_schema : dict, optional + A ui schema. Only if a parameter asks for it (e.g. ``rjsf``). """ exporter = JsonSchemaExporter( @@ -406,10 +413,10 @@ def recordtype_to_json_schema(rt: db.RecordType, additional_properties: bool = T no_remote=no_remote, multiple_choice=multiple_choice, ) - return exporter.recordtype_to_json_schema(rt, rjsf_uischema=rjsf_uischema) + return exporter.recordtype_to_json_schema(rt, rjsf=rjsf) -def make_array(schema: dict, rjsf_uischema: dict = None) -> Union[dict, tuple[dict, dict]]: +def make_array(schema: dict, rjsf_uischema: dict = None) -> Union[dict, Tuple[dict, dict]]: """Create an array of the given schema. The result will look like this: diff --git a/unittests/test_json_schema_exporter.py b/unittests/test_json_schema_exporter.py index 3176d89c..f7e84c38 100644 --- a/unittests/test_json_schema_exporter.py +++ b/unittests/test_json_schema_exporter.py @@ -835,7 +835,7 @@ RT3: uischema = {} schema_noexist_noretrieve = rtjs(model.get_deep("RT2"), do_not_retrieve=["RT1"], - rjsf_uischema=uischema) + rjsf=uischema) assert schema_noexist_noretrieve["properties"]["RT1"].get("type") == "object" assert "some_date" in schema_noexist_noretrieve["properties"]["RT1"].get("properties") assert not uischema @@ -860,27 +860,23 @@ RT4: """ model = parse_model_from_string(model_str) # generate a multiple choice, in first level - uischema = {} - schema = rtjs(model.get_deep("RT21"), additional_properties=False, do_not_create=["RT1"], - multiple_choice=["RT1"], rjsf_uischema=uischema) + schema, uischema = rtjs(model.get_deep("RT21"), additional_properties=False, + do_not_create=["RT1"], multiple_choice=["RT1"], rjsf=True) assert schema["properties"]["RT1"]["uniqueItems"] is True - assert (str(uischema["RT21"]) == - "{'RT1': {'ui:widget': 'checkboxes', 'ui:options': {'inline': True}}}") + assert str(uischema) == "{'RT1': {'ui:widget': 'checkboxes', 'ui:options': {'inline': True}}}" # second level - uischema = {} - schema = rtjs(model.get_deep("RT3"), additional_properties=False, do_not_create=["RT1"], - multiple_choice=["RT1"], rjsf_uischema=uischema) + schema, uischema = rtjs(model.get_deep("RT3"), additional_properties=False, + do_not_create=["RT1"], multiple_choice=["RT1"], rjsf=True) assert schema["properties"]["RT21"]["properties"]["RT1"]["uniqueItems"] is True - assert (str(uischema["RT3"]) == - "{'RT21': {'RT1': {'ui:widget': 'checkboxes', 'ui:options': {'inline': True}}}}") + assert (str(uischema) + == "{'RT21': {'RT1': {'ui:widget': 'checkboxes', 'ui:options': {'inline': True}}}}") # second level with lists - uischema = {} - schema = rtjs(model.get_deep("RT4"), additional_properties=False, do_not_create=["RT1"], - multiple_choice=["RT1"], rjsf_uischema=uischema) + schema, uischema = rtjs(model.get_deep("RT4"), additional_properties=False, + do_not_create=["RT1"], multiple_choice=["RT1"], rjsf=True) assert schema["properties"]["RT21"]["items"]["properties"]["RT1"]["uniqueItems"] is True - assert (str(uischema["RT4"]) == + assert (str(uischema) == "{'RT21': {'items': {'RT1': {'ui:widget': 'checkboxes', " "'ui:options': {'inline': True}}}}}") @@ -899,17 +895,15 @@ RT3: datatype: LIST<RT1> """ model = parse_model_from_string(model_str) - uischema_2 = {} - schema_2 = rtjs(model.get_deep("RT2"), additional_properties=False, do_not_create=["RT1"], - multiple_choice=["RT1"], rjsf_uischema=uischema_2) - uischema_3 = {} - schema_3 = rtjs(model.get_deep("RT3"), additional_properties=False, do_not_create=["RT1"], - multiple_choice=["RT1"], rjsf_uischema=uischema_3) + schema_2, uischema_2 = rtjs(model.get_deep("RT2"), additional_properties=False, + do_not_create=["RT1"], multiple_choice=["RT1"], rjsf=True) + schema_3, uischema_3 = rtjs(model.get_deep("RT3"), additional_properties=False, + do_not_create=["RT1"], multiple_choice=["RT1"], rjsf=True) # Merging ################################################################# # Using dictionaries schemas_dict = {"schema_2": schema_2, "schema_3": schema_3} - uischemas_dict = {"schema_2": uischema_2["RT2"], "schema_3": uischema_3["RT3"]} + uischemas_dict = {"schema_2": uischema_2, "schema_3": uischema_3} merged_dict, merged_dict_ui = jsex.merge_schemas(schemas_dict, uischemas_dict) assert merged_dict_ui["schema_2"] == merged_dict_ui["schema_3"] assert (str(merged_dict_ui["schema_2"]) @@ -917,7 +911,7 @@ RT3: # Using lists schemas_list = [schema_2, schema_3] - uischemas_list = [uischema_2["RT2"], uischema_3["RT3"]] + uischemas_list = [uischema_2, uischema_3] merged_list, merged_list_ui = jsex.merge_schemas(schemas_list, uischemas_list) assert merged_list["properties"]["RT2"] == merged_dict["properties"]["schema_2"] assert merged_list_ui["RT2"] == merged_list_ui["RT3"] @@ -930,8 +924,8 @@ RT3: jsex.merge_schemas(schemas_list, uischemas_dict) # Arraying ################################################################ - array2, array2_ui = jsex.make_array(schema_2, uischema_2["RT2"]) + array2, array2_ui = jsex.make_array(schema_2, uischema_2) assert array2["items"] == schema_2 - assert array2_ui["items"] == uischema_2["RT2"] + assert array2_ui["items"] == uischema_2 assert (str(array2_ui["items"]) == "{'RT1': {'ui:widget': 'checkboxes', 'ui:options': {'inline': True}}}") -- GitLab