dump-things-service 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- datalad-concepts/patches/jsonschemagen_mixins.diff +28 -0
- datalad-concepts/patches/jsonschemavalidator_plainyaml.diff +34 -0
- datalad-concepts/patches/linkml_runtime_utils_yamlutils.diff +29 -0
- datalad-concepts/patches/rdflib_dumper_canonical.diff +22 -0
- datalad-concepts/patches/rdflib_loader_typedesignator.diff +27 -0
- datalad-concepts/patches/shacl_ifabsent.diff +14 -0
- datalad-concepts/patches/shaclgen_annotations.diff +63 -0
- datalad-concepts/tools/patch_linkml +18 -0
- dump_things_service/__about__.py +1 -0
- dump_things_service/__init__.py +38 -0
- dump_things_service/config.py +413 -0
- dump_things_service/conftest.py +11 -0
- dump_things_service/convert.py +178 -0
- dump_things_service/dynamic_endpoints.py +56 -0
- dump_things_service/main.py +402 -0
- dump_things_service/model.py +75 -0
- dump_things_service/record.py +327 -0
- dump_things_service/resolve_curie.py +23 -0
- dump_things_service/tests/__init__.py +0 -0
- dump_things_service/tests/create_store.py +118 -0
- dump_things_service/tests/fixtures.py +214 -0
- dump_things_service/tests/test_basic.py +241 -0
- dump_things_service/tests/test_config.py +70 -0
- dump_things_service/tests/test_extract_inline.py +313 -0
- dump_things_service/tests/test_mapping.py +46 -0
- dump_things_service/tests/test_modes.py +148 -0
- dump_things_service/tests/test_permission_fetching.py +71 -0
- dump_things_service/tests/test_roundtrip.py +118 -0
- dump_things_service/tests/test_roundtrip_trr379.py +133 -0
- dump_things_service/tests/test_utils.py +40 -0
- dump_things_service/tests/test_web_interface.py +84 -0
- dump_things_service/tests/testschema.yaml +73 -0
- dump_things_service/utils.py +54 -0
- dump_things_service-0.2.0.dist-info/METADATA +286 -0
- dump_things_service-0.2.0.dist-info/RECORD +36 -0
- dump_things_service-0.2.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
This patch has been proposed for inclusion into linkml
|
|
2
|
+
https://github.com/linkml/linkml/pull/1935
|
|
3
|
+
However, it may be a too simple approach.
|
|
4
|
+
|
|
5
|
+
Specifically, the JSON schema output generated from our
|
|
6
|
+
datalad-dataset-components schema referenced any base classes that were not
|
|
7
|
+
abstract, but did not include definitions for mixin classes.
|
|
8
|
+
|
|
9
|
+
This change aligns the criterion to exclude abstract, but not mixin
|
|
10
|
+
classes.
|
|
11
|
+
|
|
12
|
+
It may be possible to exclude the references to mixin classes in the JSON
|
|
13
|
+
schema output, and thereby be able to continue to exclude definitions
|
|
14
|
+
for mixin classes too. However, an attempt to address this in
|
|
15
|
+
`get_type_info_for_slot_subschema()` was not fully successful for me,
|
|
16
|
+
but was impacted by generator parametrization.
|
|
17
|
+
--- jsonschemagen.py 2024-02-21 08:55:38.699043981 +0100
|
|
18
|
+
+++ jsonschemagen.py 2024-02-21 08:55:10.127030454 +0100
|
|
19
|
+
@@ -225,7 +225,8 @@
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
def handle_class(self, cls: ClassDefinition) -> None:
|
|
23
|
+
- if cls.mixin or cls.abstract:
|
|
24
|
+
+ #if cls.mixin or cls.abstract:
|
|
25
|
+
+ if cls.abstract:
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
subschema_type = "object"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
See https://github.com/linkml/linkml/issues/1806 for
|
|
2
|
+
problem and rationale re this patch
|
|
3
|
+
--- jsonschemavalidator.py 2024-02-23 16:19:45.946867800 +0100
|
|
4
|
+
+++ jsonschemavalidator.py 2024-02-23 16:18:26.363624044 +0100
|
|
5
|
+
@@ -187,7 +187,27 @@
|
|
6
|
+
inargs["fmt"] = input_format
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
- data_as_dict = loader.load_as_dict(source=input, **inargs)
|
|
10
|
+
+ if input_format == 'yaml':
|
|
11
|
+
+ from io import StringIO
|
|
12
|
+
+ from hbreader import FileInfo
|
|
13
|
+
+ import os
|
|
14
|
+
+ import yaml
|
|
15
|
+
+ metadata = FileInfo()
|
|
16
|
+
+ data = loader._read_source(
|
|
17
|
+
+ input,
|
|
18
|
+
+ metadata=metadata,
|
|
19
|
+
+ accept_header="text/yaml, application/yaml;q=0.9",
|
|
20
|
+
+ )
|
|
21
|
+
+ if isinstance(data, str):
|
|
22
|
+
+ data = StringIO(data)
|
|
23
|
+
+ if metadata and metadata.source_file:
|
|
24
|
+
+ data.name = os.path.relpath(metadata.source_file,
|
|
25
|
+
+ metadata.base_path)
|
|
26
|
+
+ data_as_dict = yaml.load(data, yaml.BaseLoader)
|
|
27
|
+
+ else:
|
|
28
|
+
+ data_as_dict = data
|
|
29
|
+
+ else:
|
|
30
|
+
+ data_as_dict = loader.load_as_dict(source=input, **inargs)
|
|
31
|
+
except NotImplementedError:
|
|
32
|
+
obj = loader.load(source=input, target_class=py_target_class, **inargs)
|
|
33
|
+
data_as_dict = as_simple_dict(obj)
|
|
34
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
This patch has been proposed for inclusion in linkml-runtime
|
|
2
|
+
in https://github.com/linkml/linkml-runtime/pull/392
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
fix type instantiation in _normalize_inlined
|
|
6
|
+
|
|
7
|
+
This commit fixes a problem that was discovered while
|
|
8
|
+
converting between TTL and JSON using the schema
|
|
9
|
+
https://concepts.inm7.de/s/simpleinput/unreleased.yaml
|
|
10
|
+
|
|
11
|
+
The original code used a dictionary as argument to
|
|
12
|
+
the constructor of a pydantic-class, when it should
|
|
13
|
+
have used the **-operator to cnvert the dictionary
|
|
14
|
+
into keyword arguments.
|
|
15
|
+
|
|
16
|
+
diff --git a/linkml_runtime/utils/yamlutils.py b/linkml_runtime/utils/yamlutils.py
|
|
17
|
+
index 8ca8b30..d309091 100644
|
|
18
|
+
--- a/linkml_runtime/utils/yamlutils.py
|
|
19
|
+
+++ b/linkml_runtime/utils/yamlutils.py
|
|
20
|
+
@@ -169,7 +169,7 @@ class YAMLRoot(JsonObj):
|
|
21
|
+
for lek, lev in items(list_entry):
|
|
22
|
+
if lek == key_name and not isinstance(lev, (list, dict, JsonObj)):
|
|
23
|
+
# key_name:value
|
|
24
|
+
- order_up(list_entry[lek], slot_type(list_entry))
|
|
25
|
+
+ order_up(list_entry[lek], slot_type(**list_entry))
|
|
26
|
+
break # Not strictly necessary, but
|
|
27
|
+
elif not isinstance(lev, (list, dict, JsonObj)):
|
|
28
|
+
# key: value --> slot_type(key, value)
|
|
29
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Make linkml-convert produce deterministic RDF output.
|
|
2
|
+
See https://github.com/linkml/linkml/issues/1943 for details
|
|
3
|
+
and caveats
|
|
4
|
+
--- rdflib_dumper.py 2024-02-24 07:36:07.532183567 +0100
|
|
5
|
+
+++ rdflib_dumper.py 2024-02-24 07:36:26.279874637 +0100
|
|
6
|
+
@@ -6,6 +6,7 @@
|
|
7
|
+
|
|
8
|
+
from curies import Converter
|
|
9
|
+
from rdflib import Graph, URIRef, XSD
|
|
10
|
+
+from rdflib.compare import to_canonical_graph
|
|
11
|
+
from rdflib.term import Node, BNode, Literal
|
|
12
|
+
from rdflib.namespace import RDF
|
|
13
|
+
|
|
14
|
+
@@ -66,7 +67,7 @@
|
|
15
|
+
if schemaview.namespaces()._base:
|
|
16
|
+
g.base = schemaview.namespaces()._base
|
|
17
|
+
self.inject_triples(element, schemaview, g)
|
|
18
|
+
- return g
|
|
19
|
+
+ return to_canonical_graph(g)
|
|
20
|
+
|
|
21
|
+
def inject_triples(self, element: Any, schemaview: SchemaView, graph: Graph, target_type: ElementName = None) -> Node:
|
|
22
|
+
"""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Populate type-designator slots from graph
|
|
2
|
+
# (for inlined blank-nodes -- but actuallu unclear how the issue reaches).
|
|
3
|
+
#
|
|
4
|
+
# Example of a record it could not handle without this patch (failing to
|
|
5
|
+
# encode `IssuedIdentifier` being the actual type of the identifier.
|
|
6
|
+
#
|
|
7
|
+
# @prefix dlidentifiers: <https://concepts.datalad.org/s/identifiers/unreleased/> .
|
|
8
|
+
# @prefix dlsocial: <https://concepts.datalad.org/s/social/unreleased/> .
|
|
9
|
+
# @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
10
|
+
#
|
|
11
|
+
# <https://trr379.de/contributors/michael-hanke> a dlsocial:Person ;
|
|
12
|
+
# dlidentifiers:identifier [ a dlidentifiers:IssuedIdentifier ;
|
|
13
|
+
# dlidentifiers:creator "https://orcid.org"^^xsd:anyURI ;
|
|
14
|
+
# dlidentifiers:notation "0000-0001-6398-6370" ;
|
|
15
|
+
# dlidentifiers:schema_agency "Open Researcher and Contributor ID organization" ] ;
|
|
16
|
+
# dlsocial:given_name "Michael" ;
|
|
17
|
+
#
|
|
18
|
+
--- rdflib_loader.py 2025-02-10 01:09:21.627350190 +0100
|
|
19
|
+
+++ rdflib_loader.py 2025-02-10 01:10:15.593488451 +0100
|
|
20
|
+
@@ -106,6 +106,7 @@
|
|
21
|
+
raise ValueError(f'Ambiguous types for {subject} == {type_classes}')
|
|
22
|
+
logger.info(f'Replacing {subject_class} with {type_classes}')
|
|
23
|
+
subject_class = type_classes[0].name
|
|
24
|
+
+ dict_obj[type_designator_slot.name] = type_classes[0].class_uri
|
|
25
|
+
# process all triples for this node
|
|
26
|
+
for (_, p, o) in graph.triples((subject, None, None)):
|
|
27
|
+
processed_triples.add((subject,p,o))
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
This patches shacl_ifabsent_processor.py by adding ifabsent handling for the
|
|
2
|
+
uriorcurie type, which is needed for the 'creator' slot in the identifiers schema
|
|
3
|
+
--- shacl_ifabsent_processor.py
|
|
4
|
+
+++ shacl_ifabsent_processor.py
|
|
5
|
+
@@ -62,7 +62,8 @@ class ShaclIfAbsentProcessor(IfAbsentProcessor):
|
|
6
|
+
return Literal(f"{year}-{month}-{day}T{hour}:{minutes}:{seconds}", datatype=ShaclDataType.DATETIME.uri_ref)
|
|
7
|
+
|
|
8
|
+
def map_uri_or_curie_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
|
9
|
+
- raise NotImplementedError()
|
|
10
|
+
+ uri = URIRef(self.schema_view.expand_curie(default_value))
|
|
11
|
+
+ return Literal(uri, datatype=ShaclDataType.URI.uri_ref)
|
|
12
|
+
|
|
13
|
+
def map_curie_default_value(self, default_value: str, slot: SlotDefinition, cls: ClassDefinition):
|
|
14
|
+
return Literal(default_value, datatype=ShaclDataType.CURIE.uri_ref)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
This patches shaclgen.py to allow improved handling of slot annotations and sh:order.
|
|
2
|
+
Firstly, it introduces the --exclude-order flag that allows to completely disable the
|
|
3
|
+
automatic assignment of the sh:order field to exported property shapes. See:
|
|
4
|
+
https://github.com/psychoinformatics-de/shacl-vue/issues/107#issuecomment-2866073117
|
|
5
|
+
Secondly, if the --exclude-order flag is not used, the patch prevents creation of faulty
|
|
6
|
+
sh:order lists by prioritizing sh:order provided via annotation, since sh:order should
|
|
7
|
+
just be a single numerical value. See for context:
|
|
8
|
+
https://github.com/linkml/linkml/pull/2111#issuecomment-2116208229
|
|
9
|
+
Lastlt, and for a similar reason as before, it only sets sh:path automatically if the
|
|
10
|
+
value has not already been set via annotation.
|
|
11
|
+
--- shaclgen.py
|
|
12
|
+
+++ shaclgen.py
|
|
13
|
+
@@ -30,6 +30,8 @@ class ShaclGenerator(Generator):
|
|
14
|
+
"""parameterized suffix to be appended. No suffix per default."""
|
|
15
|
+
include_annotations: bool = False
|
|
16
|
+
"""True means include all class / slot / type annotations in generated Node or Property shapes"""
|
|
17
|
+
+ exclude_order: bool = False
|
|
18
|
+
+ """True means exclude the automatic addition of sh:order to Property shapes"""
|
|
19
|
+
exclude_imports: bool = False
|
|
20
|
+
"""If True, elements from imported ontologies won't be included in the generator's output"""
|
|
21
|
+
generatorname = os.path.basename(__file__)
|
|
22
|
+
@@ -114,8 +116,6 @@ class ShaclGenerator(Generator):
|
|
23
|
+
g.add((pnode, p, Literal(v)))
|
|
24
|
+
|
|
25
|
+
prop_pv(SH.path, slot_uri)
|
|
26
|
+
- prop_pv_literal(SH.order, order)
|
|
27
|
+
- order += 1
|
|
28
|
+
prop_pv_literal(SH.name, s.title)
|
|
29
|
+
prop_pv_literal(SH.description, s.description)
|
|
30
|
+
# minCount
|
|
31
|
+
@@ -223,6 +223,18 @@ class ShaclGenerator(Generator):
|
|
32
|
+
default_value = ifabsent_processor.process_slot(s, c)
|
|
33
|
+
if default_value:
|
|
34
|
+
prop_pv(SH.defaultValue, default_value)
|
|
35
|
+
+
|
|
36
|
+
+ # Add the order automatically unless the --exclude-order flag was supplied
|
|
37
|
+
+ if not self.exclude_order:
|
|
38
|
+
+ # sh:order may already have been added to the graph via annotations
|
|
39
|
+
+ if not (pnode, SH.order, None) in g:
|
|
40
|
+
+ prop_pv_literal(SH.order, order)
|
|
41
|
+
+ order += 1
|
|
42
|
+
+
|
|
43
|
+
+ # sh:path may already have been added to the graph via annotations
|
|
44
|
+
+ if not (pnode, SH.path, None) in g:
|
|
45
|
+
+ prop_pv(SH.path, slot_uri)
|
|
46
|
+
+
|
|
47
|
+
|
|
48
|
+
return g
|
|
49
|
+
|
|
50
|
+
@@ -366,6 +378,13 @@ def add_simple_data_type(func: Callable, r: ElementName) -> None:
|
|
51
|
+
show_default=True,
|
|
52
|
+
help="Use --include-annotations to include annotations of slots, types, and classes in the generated SHACL shapes.",
|
|
53
|
+
)
|
|
54
|
+
+@click.option(
|
|
55
|
+
+ "--exclude-order/--include-order",
|
|
56
|
+
+ default=False,
|
|
57
|
+
+ show_default=True,
|
|
58
|
+
+ help="Use --exclude-order to exclude sh:order from being added automatically to generated SHACL property shapes. "
|
|
59
|
+
+ "Default behavior adds order. This flag has no influence on sh:order being added via annotations.",
|
|
60
|
+
+)
|
|
61
|
+
@click.option(
|
|
62
|
+
"--exclude-imports/--include-imports",
|
|
63
|
+
default=False,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# This script applies patches to the active linkml installation.
|
|
4
|
+
# It is to be executed in the root of the repository.
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
# make JSON schema generation work with mixins
|
|
8
|
+
patch -d $(python -c 'import os; import linkml.generators.jsonschemagen as m; print(os.path.dirname(m.__file__))') < patches/jsonschemagen_mixins.diff
|
|
9
|
+
#patch -d $(python -c 'import os; import linkml.validators.jsonschemavalidator as m; print(os.path.dirname(m.__file__))') < patches/jsonschemavalidator_plainyaml.diff
|
|
10
|
+
#patch -d $(python -c 'import os; import linkml_runtime.dumpers as m; print(os.path.dirname(m.__file__))') < patches/rdflib_dumper_canonical.diff
|
|
11
|
+
# Create correct 'order' properties when generating SHACL
|
|
12
|
+
patch -d $(python -c 'import os; import linkml.generators.shaclgen as m; print(os.path.dirname(m.__file__))') < patches/shaclgen_annotations.diff
|
|
13
|
+
# Allow ifabsent handling of uriorcurie type during SHACL generation
|
|
14
|
+
patch -d $(python -c 'import os; import linkml.generators.shacl.shacl_ifabsent_processor as m; print(os.path.dirname(m.__file__))') < patches/shacl_ifabsent.diff
|
|
15
|
+
# Honor type-designator slots when loading graphs
|
|
16
|
+
patch -d $(python -c 'import os; import linkml_runtime.loaders as m; print(os.path.dirname(m.__file__))') < patches/rdflib_loader_typedesignator.diff
|
|
17
|
+
# Use correct constructor arguments when normalizing inlined objects
|
|
18
|
+
patch -d $(python -c 'import os; import linkml_runtime.utils.yamlutils as m; print(os.path.dirname(m.__file__))') < patches/linkml_runtime_utils_yamlutils.diff
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.2.0'
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import (
|
|
3
|
+
Any,
|
|
4
|
+
Union,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
from starlette.status import (
|
|
8
|
+
HTTP_200_OK,
|
|
9
|
+
HTTP_400_BAD_REQUEST,
|
|
10
|
+
HTTP_401_UNAUTHORIZED,
|
|
11
|
+
HTTP_403_FORBIDDEN,
|
|
12
|
+
HTTP_404_NOT_FOUND,
|
|
13
|
+
HTTP_500_INTERNAL_SERVER_ERROR,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
'Format',
|
|
18
|
+
'HTTP_200_OK',
|
|
19
|
+
'HTTP_400_BAD_REQUEST',
|
|
20
|
+
'HTTP_401_UNAUTHORIZED',
|
|
21
|
+
'HTTP_403_FORBIDDEN',
|
|
22
|
+
'HTTP_404_NOT_FOUND',
|
|
23
|
+
'HTTP_500_INTERNAL_SERVER_ERROR',
|
|
24
|
+
'JSON',
|
|
25
|
+
'YAML',
|
|
26
|
+
'config_file_name',
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Format(str, Enum):
|
|
31
|
+
json = 'json'
|
|
32
|
+
ttl = 'ttl'
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
JSON = Union[dict[str, Any], list[Any], str, int, float, None]
|
|
36
|
+
YAML = JSON
|
|
37
|
+
|
|
38
|
+
config_file_name = '.dumpthings.yaml'
|