Skip to content
Snippets Groups Projects
Commit 224fa6a3 authored by florian's avatar florian
Browse files

WIP: Separate original behavior into top_level_recordtype=True

parent db1ccf4b
No related branches found
No related tags found
2 merge requests!73MAINT: change wording of TableImporter argument and allow converters and...,!72Extend json-schema model parser
Pipeline #35576 passed
......@@ -152,13 +152,17 @@ def parse_model_from_string(string):
return parser.parse_model_from_string(string)
def parse_model_from_json_schema(filename: str):
def parse_model_from_json_schema(filename: str, top_level_recordtype: bool = True):
"""Return a datamodel parsed from a json schema definition.
Parameters
----------
filename : str
The path of the json schema file that is to be parsed
top_level_recordtype : bool, optional
Whether there is a record type defined at the top level of the
schema. Default is true.
Returns
-------
......@@ -623,7 +627,7 @@ class JsonSchemaParser(Parser):
# @date 2022-02-17
# @review Timm Fitschen 2022-02-30
def parse_model_from_json_schema(self, filename: str):
def parse_model_from_json_schema(self, filename: str, top_level_recordtype: bool = True):
"""Return a datamodel created from the definition in the json schema in
`filename`.
......@@ -631,6 +635,9 @@ class JsonSchemaParser(Parser):
----------
filename : str
The path to the json-schema file containing the datamodel definition
top_level_recordtype : bool, optional
Whether there is a record type defined at the top level of the
schema. Default is true.
Returns
-------
......@@ -643,9 +650,9 @@ class JsonSchemaParser(Parser):
with open(filename, 'r') as schema_file:
model_dict = json.load(schema_file)
return self._create_model_from_dict(model_dict)
return self._create_model_from_dict(model_dict, top_level_recordtype=top_level_recordtype)
def _create_model_from_dict(self, model_dict: [dict, List[dict]]):
def _create_model_from_dict(self, model_dict: [dict, List[dict]], top_level_recordtype: bool = True):
"""Parse a dictionary and return the Datamodel created from it.
The dictionary was typically created from the model definition in a json schema file.
......@@ -654,6 +661,9 @@ class JsonSchemaParser(Parser):
----------
model_dict : dict or list[dict]
One or several dictionaries read in from a json-schema file
top_level_recordtype : bool, optional
Whether there is a record type defined at the top level of the
schema. Default is true.
Returns
-------
......@@ -665,23 +675,43 @@ class JsonSchemaParser(Parser):
model_dict = [model_dict]
for ii, elt in enumerate(model_dict):
if "title" not in elt:
raise JsonSchemaDefinitionError(
f"Object {ii+1} is lacking the `title` key word")
if "type" not in elt:
raise JsonSchemaDefinitionError(
f"Object {ii+1} is lacking the `type` key word")
# Check if this is a valid Json Schema
try:
jsonschema.Draft202012Validator.check_schema(elt)
except jsonschema.SchemaError as err:
key = elt["title"] if "title" in elt else f"element {ii}"
raise JsonSchemaDefinitionError(
f"Json Schema error in {elt['title']}:\n{str(err)}") from err
name = self._stringify(elt["title"], context=elt)
self._treat_element(elt, name)
f"Json Schema error in {key}:\n{str(err)}") from err
if top_level_recordtype:
if "title" not in elt:
raise JsonSchemaDefinitionError(
f"Object {ii+1} is lacking the `title` key word")
if "type" not in elt:
raise JsonSchemaDefinitionError(
f"Object {ii+1} is lacking the `type` key word")
# Check if this is a valid Json Schema
name = self._stringify(elt["title"], context=elt)
self._treat_element(elt, name)
elif "properties" in elt:
for key, prop in elt["properties"]:
name = self._get_name_from_property(key, prop)
self._treat_element(prop, name)
else:
# Neither RecordType itself, nor further properties in schema,
# so nothing to do here. Maybe add something in the future.
continue
return DataModel(self.model.values())
def _get_name_from_property(self, key: str, prop: dict):
if "title" in prop:
name = self._stringify(prop["title"])
else:
name = self._stringify(key)
return name
def _get_atomic_datatype(self, elt):
# @review Timm Fitschen 2022-02-30
if elt["type"] == "string":
......@@ -745,10 +775,7 @@ class JsonSchemaParser(Parser):
required = []
if "properties" in elt:
for key, prop in elt["properties"].items():
if "title" in prop:
name = self._stringify(prop["title"])
else:
name = self._stringify(key)
name = self._get_name_from_property(key, prop)
prop_ent, force_list = self._treat_element(prop, name)
if prop_ent is None:
# Nothing to be appended since the property has to be
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment