From f411b203467cd71f1578111ae6c7456d49f4d478 Mon Sep 17 00:00:00 2001
From: fspreck <f.spreckelsen@indiscale.com>
Date: Thu, 12 Oct 2023 17:18:46 +0200
Subject: [PATCH] DRAFT: Begin json schema exporter

---
 src/caosadvancedtools/json_schema_exporter.py | 94 +++++++++++++++++++
 1 file changed, 94 insertions(+)
 create mode 100644 src/caosadvancedtools/json_schema_exporter.py

diff --git a/src/caosadvancedtools/json_schema_exporter.py b/src/caosadvancedtools/json_schema_exporter.py
new file mode 100644
index 00000000..546022e0
--- /dev/null
+++ b/src/caosadvancedtools/json_schema_exporter.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+# encoding: utf-8
+#
+# This file is a part of the CaosDB Project.
+#
+# Copyright (C) 2023 Indiscale GmbH <info@indiscale.com>
+# Copyright (C) 2023 Florian Spreckelsen <f.spreckelsen@indiscale.com>
+#
+# This program is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Affero General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Affero General Public License along
+# with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+
+import json
+
+import linkahead as db
+
+
+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 _make_text_property(description="", text_format=None, text_pattern=None):
+
+    prop = {
+        "type": "string"
+    }
+    if description:
+        prop["description"] = description
+    if text_format is not None:
+        prop["format"] = text_format
+    if text_pattern is not None:
+        prop["pattern"] = text_pattern
+
+    return prop
+
+
+def recordtype_to_json_schema(rt: db.RecordType, additional_properties: bool = True,
+                              name_and_description_in_properties: bool = True):
+    """Create a jsonschema from a given RecordType that can be used, e.g., to
+    validate a json specifying a record of the given type.
+
+    Parameters
+    ----------
+    rt : RecordType
+        The RecordType from which a json schema will be created.
+    additional_properties : bool, optional
+        Whether additional propeties will be admitted in the resulting
+        schema. Optional, default is True.
+    name_and_description_in_properties : bool, optional
+        Whether to include name and description in the `properties` section of
+        the schema to be exported. Optional, default is True.
+
+    Returns
+    -------
+    schema : dict
+        A dict containing the json schema created from the given RecordType's properties.
+
+    """
+
+    schema = {
+        "$schema": "https://json-schema.org/draft/2019-09/schema",
+        "type": "object"
+    }
+    if rt.name:
+        schema["title"] = rt.name
+    if rt.description:
+        schema["description"] = rt.description
+
+    schema["required"] = _make_required_list(rt)
+    schema["additionalProperties"] = additional_properties
+
+    props = {}
+    if name_and_description_in_properties:
+        props["name"] = _make_text_property("The name of the Record to be created")
+        props["description"] = _make_text_property("The description of the Record to be created")
+
+    schema["properties"] = props
+    return schema
-- 
GitLab