Skip to content
Snippets Groups Projects
Commit 9f452450 authored by Henrik tom Wörden's avatar Henrik tom Wörden
Browse files

MAITN: refactoring

parent 9d5cb9bd
No related branches found
No related tags found
2 merge requests!89ENH: JsonSchemaExporter accepts do_not_create parameter.,!80F simple schema export
Pipeline #42294 failed
......@@ -21,47 +21,31 @@
#
import re
from typing import Optional
import linkahead as db
from linkahead.common.datatype import is_list_datatype, get_list_datatype
def _make_required_list(rt: db.RecordType):
"""Return the list of names of properties with importance db.OBLIGATORY."""
required = []
for prop in rt.properties:
importance = rt.get_importance(prop.name)
if importance == db.OBLIGATORY:
required.append(prop.name)
return required
def _extract_elemet_dtyp_from_list_dtype(list_dtype):
if not list_dtype.lower().startswith("list"):
return [prop.name for prop in rt.properties
if rt.get_importance(prop.name) == db.OBLIGATORY]
raise ValueError(f"Not a list dtype: {list_dtype}")
pattern = r"^[Ll][Ii][Ss][Tt](<(?P<dtype1>.*)>|\((?P<dtype2>.*)\))$"
comp = re.compile(pattern)
mtch = comp.match(list_dtype)
if mtch is None:
def _make_prop_from_prop(prop: db.Property, additional_options_for_text_props: Optional[dict]):
"""Return the JSON Schema segment for the given property
raise ValueError(f"Not a list dtype: {list_dtype}")
elif "dtype1" in mtch.groupdict() and mtch.groupdict()["dtype1"] is not None:
return mtch.groupdict()["dtype1"]
elif "dtype2" in mtch.groupdict() and mtch.groupdict()["dtype2"] is not None:
return mtch.groupdict()["dtype2"]
else:
raise ValueError(f"Not a list dtype: {list_dtype}")
def _make_prop_from_prop(prop, additional_options_for_text_props):
Parameters
----------
prop : db.Property
the property to be transformed
additional_options_for_text_props : Optional[dict]
dict that may contain the keys 'pattern' and 'format' to
further define the rules for the JSON Schema segment
"""
if prop.is_reference():
raise NotImplementedError(
"Reference properties are not supported in this version of the json schema exporter."
)
......@@ -69,11 +53,11 @@ def _make_prop_from_prop(prop, additional_options_for_text_props):
if prop.datatype == db.TEXT or prop.datatype == db.DATETIME:
text_format = None
text_pattern = None
if prop.name in additional_options_for_text_props:
if "pattern" in additional_options_for_text_props[prop.name]:
text_pattern = additional_options_for_text_props[prop.name]["pattern"]
if "format" in additional_options_for_text_props[prop.name]:
text_format = additional_options_for_text_props[prop.name]["format"]
if additional_options_for_text_props:
if "pattern" in additional_options_for_text_props:
text_pattern = additional_options_for_text_props["pattern"]
if "format" in additional_options_for_text_props:
text_format = additional_options_for_text_props["format"]
elif prop.datatype == db.DATETIME:
# Set the date or datetime format if only a pattern is given ...
text_format = ["date", "date-time"]
......@@ -94,10 +78,10 @@ def _make_prop_from_prop(prop, additional_options_for_text_props):
json_prop["type"] = "integer"
elif prop.datatype == db.DOUBLE:
json_prop["type"] = "number"
elif isinstance(prop.datatype, str) and prop.datatype.startswith("LIST"):
elif is_list_datatype(prop.datatype):
json_prop["type"] = "array"
list_element_prop = db.Property(
name=prop.name, datatype=_extract_elemet_dtyp_from_list_dtype(prop.datatype))
name=prop.name, datatype=get_list_datatype(prop.datatype, strict=True))
json_prop["items"] = _make_prop_from_prop(
list_element_prop, additional_options_for_text_props)
else:
......@@ -127,7 +111,7 @@ def _make_text_property(description="", text_format=None, text_pattern=None):
def recordtype_to_json_schema(rt: db.RecordType, additional_properties: bool = True,
name_and_description_in_properties: bool = False,
additional_options_for_text_props: dict = {}):
additional_options_for_text_props: Optional[dict] = None):
"""Create a jsonschema from a given RecordType that can be used, e.g., to
validate a json specifying a record of the given type.
......@@ -152,6 +136,9 @@ def recordtype_to_json_schema(rt: db.RecordType, additional_properties: bool = T
"""
if additional_options_for_text_props is None:
additional_options_for_text_props = {}
schema = {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object"
......@@ -176,7 +163,9 @@ def recordtype_to_json_schema(rt: db.RecordType, additional_properties: bool = T
"Creating a schema for multi-properties is not specified. "
f"Property {prop.name} occurs more than once."
)
props[prop.name] = _make_prop_from_prop(prop, additional_options_for_text_props)
props[prop.name] = _make_prop_from_prop(prop, additional_options_for_text_props[prop.name]
if prop.name in additional_options_for_text_props
else None)
schema["properties"] = props
return schema
......@@ -38,6 +38,7 @@ def test_empty_rt():
assert schema["description"] == rt.description
assert len(schema["properties"]) == 0
assert len(schema["required"]) == 0
assert schema["additionalProperties"] is True
schema = rtjs(rt, additional_properties=False)
......
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