Skip to content
Snippets Groups Projects
Verified Commit 33560217 authored by Daniel Hornung's avatar Daniel Hornung
Browse files

ENH: Json schema exporter now can merge schemata and arrayize them.

parent d4183d54
No related branches found
No related tags found
2 merge requests!89ENH: JsonSchemaExporter accepts do_not_create parameter.,!83ENH: JsonSchemaExporter can merge schemata and arrayize them
Pipeline #43191 failed
......@@ -22,8 +22,8 @@
"""Module for converting a data model into a json schema compatible dictionary.
"""
from typing import Any, List, Optional
from collections import OrderedDict
from typing import Any, Iterable, List, Optional, Union
import linkahead as db
from linkahead.common.datatype import get_list_datatype, is_list_datatype
......@@ -318,3 +318,93 @@ def recordtype_to_json_schema(rt: db.RecordType, additional_properties: bool = T
do_not_create=do_not_create,
)
return exporter.recordtype_to_json_schema(rt)
def make_array(schema: dict) -> dict:
"""Create an array of the given schema.
The result will look like this:
.. code:: js
{ "type": "array",
"items": {
// the schema
}
}
Parameters
----------
schema : dict
The JSON schema which shall be packed into an array.
Returns
-------
out : dict
A JSON schema dict with a top-level array which contains instances of the given schema.
"""
result = {
"type": "array",
"items": schema,
"$schema": "https://json-schema.org/draft/2019-09/schema",
}
return result
def merge_schemas(schemas: Union[dict[str, dict], Iterable[dict]]) -> dict:
"""Merge the given schemata into a single schema.
The result will look like this:
.. code:: js
{
"type": "object",
"properties": {
// A, B, C
},
"required": [
// "A", "B", "C"
],
"additionalProperties": false
}
Parameters
----------
schemas : dict[str, dict] | Iterable[dict]
A dict or iterable of schemata which shall be merged together. If this is a dict, the keys will
be used as property names, otherwise the titles of the submitted schemata. If they have no title,
numbers will be used as a fallback. Note that even with a dict, the original schema's "title" is
not changed.
Returns
-------
out : dict
A JSON schema dict with a top-level object which contains the given schemata as properties.
"""
sub_schemas: dict[str, dict] = OrderedDict()
required = []
if isinstance(schemas, dict):
sub_schemas = schemas
required = [str(k) for k in schemas.keys()]
else:
for i, schema in enumerate(schemas, start=1):
title = schema.get("title", str(i))
sub_schemas[title] = schema
required.append(title)
result = {
"type": "object",
"properties": sub_schemas,
"required": required,
"additionalProperties": False,
"$schema": "https://json-schema.org/draft/2019-09/schema",
}
return result
......@@ -25,6 +25,7 @@
import json
import linkahead as db
import caosadvancedtools.json_schema_exporter as jsex
from jsonschema import FormatChecker, validate, ValidationError
from pytest import raises
......@@ -681,3 +682,44 @@ RT2:
"$schema": "https://json-schema.org/draft/2019-09/schema",
"title": "RT2"
}"""
def test_schema_modification():
"""Testing functions which modify json schema dicts:
- make_array()
- merge_schemas().
"""
model_str = """
some_date:
datatype: DATETIME
RT1:
obligatory_properties:
some_date:
some_text:
datatype: TEXT
RT2:
obligatory_properties:
some_text:
"""
model = parse_model_from_string(model_str)
schema_RT1 = rtjs(model.get_deep("RT1"), additional_properties=False)
schema_RT2 = rtjs(model.get_deep("RT2"), additional_properties=False)
# Merge the schemata
merged_list = jsex.merge_schemas([schema_RT1, schema_RT2])
assert merged_list["type"] == "object"
assert merged_list["properties"]["RT1"]["title"] == "RT1"
assert merged_list["properties"]["RT2"]["properties"]["some_text"]["type"] == "string"
merged_dict = jsex.merge_schemas({"schema1": schema_RT1, "schema2": schema_RT2})
assert merged_dict["type"] == "object"
assert merged_dict["properties"]["schema1"]["title"] == "RT1"
assert merged_dict["properties"]["schema2"]["properties"]["some_text"]["type"] == "string"
# Make an array
array = jsex.make_array(schema_RT1)
assert array["type"] == "array"
assert array["items"] == schema_RT1
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