linkml 1.5.6__py3-none-any.whl → 1.5.7__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.
Files changed (79) hide show
  1. linkml/__init__.py +2 -6
  2. linkml/_version.py +1 -1
  3. linkml/generators/__init__.py +26 -5
  4. linkml/generators/common/type_designators.py +27 -22
  5. linkml/generators/csvgen.py +4 -10
  6. linkml/generators/docgen/class.md.jinja2 +7 -0
  7. linkml/generators/docgen/class_diagram.md.jinja2 +0 -6
  8. linkml/generators/docgen/subset.md.jinja2 +54 -13
  9. linkml/generators/docgen.py +92 -90
  10. linkml/generators/dotgen.py +5 -9
  11. linkml/generators/erdiagramgen.py +56 -51
  12. linkml/generators/excelgen.py +10 -16
  13. linkml/generators/golanggen.py +11 -21
  14. linkml/generators/golrgen.py +4 -13
  15. linkml/generators/graphqlgen.py +3 -11
  16. linkml/generators/javagen.py +8 -15
  17. linkml/generators/jsonldcontextgen.py +7 -36
  18. linkml/generators/jsonldgen.py +14 -12
  19. linkml/generators/jsonschemagen.py +177 -133
  20. linkml/generators/markdowngen.py +40 -89
  21. linkml/generators/namespacegen.py +1 -2
  22. linkml/generators/oocodegen.py +22 -25
  23. linkml/generators/owlgen.py +34 -49
  24. linkml/generators/prefixmapgen.py +5 -13
  25. linkml/generators/projectgen.py +7 -14
  26. linkml/generators/protogen.py +3 -5
  27. linkml/generators/pydanticgen.py +85 -73
  28. linkml/generators/pythongen.py +86 -154
  29. linkml/generators/rdfgen.py +5 -11
  30. linkml/generators/shaclgen.py +32 -18
  31. linkml/generators/shexgen.py +19 -24
  32. linkml/generators/sparqlgen.py +4 -12
  33. linkml/generators/sqlalchemy/__init__.py +3 -2
  34. linkml/generators/sqlalchemy/sqlalchemy_declarative_template.py +7 -7
  35. linkml/generators/sqlalchemy/sqlalchemy_imperative_template.py +3 -3
  36. linkml/generators/sqlalchemygen.py +29 -27
  37. linkml/generators/sqlddlgen.py +34 -26
  38. linkml/generators/sqltablegen.py +21 -21
  39. linkml/generators/sssomgen.py +11 -13
  40. linkml/generators/summarygen.py +2 -4
  41. linkml/generators/terminusdbgen.py +7 -19
  42. linkml/generators/typescriptgen.py +10 -18
  43. linkml/generators/yamlgen.py +0 -2
  44. linkml/generators/yumlgen.py +23 -71
  45. linkml/linter/cli.py +4 -11
  46. linkml/linter/config/datamodel/config.py +17 -47
  47. linkml/linter/linter.py +2 -4
  48. linkml/linter/rules.py +34 -48
  49. linkml/reporting/__init__.py +2 -0
  50. linkml/reporting/model.py +9 -24
  51. linkml/transformers/relmodel_transformer.py +20 -33
  52. linkml/transformers/schema_renamer.py +14 -10
  53. linkml/utils/converter.py +15 -13
  54. linkml/utils/datautils.py +6 -22
  55. linkml/utils/datavalidator.py +2 -2
  56. linkml/utils/execute_tutorial.py +10 -12
  57. linkml/utils/generator.py +73 -91
  58. linkml/utils/helpers.py +4 -2
  59. linkml/utils/ifabsent_functions.py +23 -15
  60. linkml/utils/mergeutils.py +19 -35
  61. linkml/utils/rawloader.py +2 -6
  62. linkml/utils/schema_builder.py +31 -19
  63. linkml/utils/schema_fixer.py +28 -18
  64. linkml/utils/schemaloader.py +44 -89
  65. linkml/utils/schemasynopsis.py +49 -72
  66. linkml/utils/sqlutils.py +40 -30
  67. linkml/utils/typereferences.py +9 -6
  68. linkml/utils/validation.py +4 -5
  69. linkml/validators/__init__.py +2 -0
  70. linkml/validators/jsonschemavalidator.py +28 -18
  71. linkml/validators/sparqlvalidator.py +5 -15
  72. linkml/workspaces/datamodel/workspaces.py +13 -30
  73. linkml/workspaces/example_runner.py +74 -67
  74. {linkml-1.5.6.dist-info → linkml-1.5.7.dist-info}/METADATA +1 -1
  75. linkml-1.5.7.dist-info/RECORD +109 -0
  76. linkml-1.5.6.dist-info/RECORD +0 -109
  77. {linkml-1.5.6.dist-info → linkml-1.5.7.dist-info}/LICENSE +0 -0
  78. {linkml-1.5.6.dist-info → linkml-1.5.7.dist-info}/WHEEL +0 -0
  79. {linkml-1.5.6.dist-info → linkml-1.5.7.dist-info}/entry_points.txt +0 -0
linkml/__init__.py CHANGED
@@ -20,9 +20,7 @@ MODULE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
20
20
  LOCAL_METAMODEL_YAML_FILE = linkml_files.LOCAL_PATH_FOR(Source.META, Format.YAML)
21
21
  LOCAL_TYPES_YAML_FILE = linkml_files.LOCAL_PATH_FOR(Source.TYPES, Format.YAML)
22
22
  LOCAL_MAPPINGS_YAML_FILE = linkml_files.LOCAL_PATH_FOR(Source.MAPPINGS, Format.YAML)
23
- LOCAL_ANNOTATIONS_YAML_FILE = linkml_files.LOCAL_PATH_FOR(
24
- Source.ANNOTATIONS, Format.YAML
25
- )
23
+ LOCAL_ANNOTATIONS_YAML_FILE = linkml_files.LOCAL_PATH_FOR(Source.ANNOTATIONS, Format.YAML)
26
24
  LOCAL_EXTENSIONS_YAML_FILE = linkml_files.LOCAL_PATH_FOR(Source.EXTENSIONS, Format.YAML)
27
25
 
28
26
  # Local location of jsonld and context.jsonld files
@@ -30,9 +28,7 @@ LOCAL_METAMODEL_LDCONTEXT_FILE = linkml_files.LOCAL_PATH_FOR(Source.META, Format
30
28
  LOCAL_METAMODEL_JSONLD_FILE = linkml_files.LOCAL_PATH_FOR(Source.META, Format.JSON)
31
29
  LOCAL_TYPES_LDCONTEXT_FILE = linkml_files.LOCAL_PATH_FOR(Source.TYPES, Format.JSONLD)
32
30
  LOCAL_TYPES_JSONLD_FILE = linkml_files.LOCAL_PATH_FOR(Source.TYPES, Format.JSON)
33
- LOCAL_MAPPINGS_LDCONTEXT_FILE = linkml_files.LOCAL_PATH_FOR(
34
- Source.MAPPINGS, Format.JSONLD
35
- )
31
+ LOCAL_MAPPINGS_LDCONTEXT_FILE = linkml_files.LOCAL_PATH_FOR(Source.MAPPINGS, Format.JSONLD)
36
32
  LOCAL_MAPPINGS_JSONLD_FILE = linkml_files.LOCAL_PATH_FOR(Source.MAPPINGS, Format.JSON)
37
33
 
38
34
  # Local location of metamodel shex file
linkml/_version.py CHANGED
@@ -3,7 +3,7 @@ try:
3
3
  except ImportError:
4
4
  # Python < 3.8
5
5
  import importlib_metadata as metadata # pragma: no cover
6
-
6
+
7
7
  try:
8
8
  __version__ = metadata.version(__package__)
9
9
  except metadata.PackageNotFoundError:
@@ -2,7 +2,17 @@
2
2
  Generators translate between a SchemaDefinition and an alternative
3
3
  representation such as JsonSchema
4
4
  """
5
- # Generator version numbers
5
+
6
+ from linkml.generators.javagen import JavaGenerator
7
+ from linkml.generators.jsonschemagen import JsonSchemaGenerator
8
+ from linkml.generators.owlgen import OwlSchemaGenerator
9
+ from linkml.generators.pydanticgen import PydanticGenerator
10
+ from linkml.generators.pythongen import PythonGenerator
11
+ from linkml.generators.shaclgen import ShaclGenerator
12
+ from linkml.generators.shexgen import ShExGenerator
13
+ from linkml.generators.sqlalchemygen import SQLAlchemyGenerator
14
+ from linkml.generators.sqltablegen import SQLTableGenerator
15
+
6
16
  __all__ = [
7
17
  "csvgen",
8
18
  "dotgen",
@@ -18,15 +28,26 @@ __all__ = [
18
28
  "owlgen",
19
29
  "protogen",
20
30
  "pythongen",
31
+ "pydanticgen",
21
32
  "rdfgen",
22
33
  "shexgen",
34
+ "shaclgen",
23
35
  "sssomgen",
24
36
  "summarygen",
25
37
  "yamlgen",
26
38
  "yumlgen",
27
- "PYTHON_GEN_VERSION",
39
+ "OwlSchemaGenerator",
40
+ "PydanticGenerator",
41
+ "PythonGenerator",
42
+ "JavaGenerator",
43
+ "JsonSchemaGenerator",
44
+ "ShaclGenerator",
45
+ "ShExGenerator",
46
+ "SQLAlchemyGenerator",
47
+ "SQLTableGenerator",
28
48
  ]
29
- GENERATOR_BASE = "0.9"
30
49
 
31
- PYTHON_GEN_VERSION = GENERATOR_BASE + ".0"
32
- JAVA_GEN_VERSION = GENERATOR_BASE + ".0"
50
+ # TODO: deprecate usage of these
51
+ # GENERATOR_BASE = "0.9"
52
+
53
+ # PYTHON_GEN_VERSION = GENERATOR_BASE + ".0"
@@ -1,44 +1,49 @@
1
- from linkml_runtime.linkml_model.meta import SlotDefinition, ClassDefinition
1
+ from typing import List
2
+
3
+ from linkml_runtime.linkml_model.meta import ClassDefinition, SlotDefinition
2
4
  from linkml_runtime.utils.schemaview import SchemaView
3
- from linkml_runtime.utils.formatutils import camelcase
4
- from typing import List, Tuple
5
5
 
6
- def get_type_designator_value(sv: SchemaView, type_designator_slot: SlotDefinition, class_def: ClassDefinition) -> str:
6
+
7
+ def get_type_designator_value(
8
+ sv: SchemaView, type_designator_slot: SlotDefinition, class_def: ClassDefinition
9
+ ) -> str:
7
10
  """
8
- returns the correct value for a type designator field for a given class, depending on its range
9
- this implements the logic described in https://github.com/linkml/linkml/issues/945:
11
+ returns the correct value for a type designator field for a given class, depending on its range
12
+ this implements the logic described in https://github.com/linkml/linkml/issues/945:
10
13
  """
11
14
  slot_types = set(sv.type_ancestors(type_designator_slot.range))
12
- if 'uri' in slot_types:
13
- return sv.get_uri(class_def,expand=True,native=False)
14
- elif 'uriorcurie' in slot_types:
15
- return sv.get_uri(class_def,expand=False, native=False)
16
- elif 'string' in slot_types:
15
+ if "uri" in slot_types:
16
+ return sv.get_uri(class_def, expand=True, native=False)
17
+ elif "uriorcurie" in slot_types:
18
+ return sv.get_uri(class_def, expand=False, native=False)
19
+ elif "string" in slot_types:
17
20
  return class_def.name
18
21
  else:
19
- return sv.get_uri(class_def,expand=False, native=False)
22
+ return sv.get_uri(class_def, expand=False, native=False)
20
23
 
21
24
 
22
- def get_accepted_type_designator_values(sv: SchemaView, type_designator_slot: SlotDefinition, class_def: ClassDefinition) -> List[str]:
25
+ def get_accepted_type_designator_values(
26
+ sv: SchemaView, type_designator_slot: SlotDefinition, class_def: ClassDefinition
27
+ ) -> List[str]:
23
28
  """
24
- returns the accepted values for a type designator field for a given class, depending on its range
25
- this implements the logic described in https://github.com/linkml/linkml/issues/945:
29
+ returns the accepted values for a type designator field for a given class, depending on its range
30
+ this implements the logic described in https://github.com/linkml/linkml/issues/945:
26
31
  """
27
32
  accepted_uri_values = [
28
- sv.get_uri(class_def, expand=True, native=True),
29
- sv.get_uri(class_def, expand=True, native=False),
30
- sv.get_uri(class_def, expand=False, native=True),
31
- sv.get_uri(class_def, expand=False, native=False),
32
- ]
33
+ sv.get_uri(class_def, expand=True, native=True),
34
+ sv.get_uri(class_def, expand=True, native=False),
35
+ sv.get_uri(class_def, expand=False, native=True),
36
+ sv.get_uri(class_def, expand=False, native=False),
37
+ ]
33
38
  # unique, but with order preserved (https://stackoverflow.com/a/17016257)
34
39
  accepted_uri_values = list(dict.fromkeys(accepted_uri_values))
35
40
 
36
41
  slot_types = set(sv.type_ancestors(type_designator_slot.range))
37
- uri_types = ['uri', 'uriorcurie']
42
+ uri_types = ["uri", "uriorcurie"]
38
43
 
39
44
  if slot_types.intersection(uri_types):
40
45
  return accepted_uri_values
41
- elif type_designator_slot.range == 'string':
46
+ elif type_designator_slot.range == "string":
42
47
  return [class_def.name]
43
48
  else:
44
49
  return accepted_uri_values
@@ -5,12 +5,10 @@ import os
5
5
  import sys
6
6
  from csv import DictWriter
7
7
  from dataclasses import dataclass
8
- from typing import List, Optional, Set, TextIO, Union
8
+ from typing import List, Optional, Set
9
9
 
10
10
  import click
11
- from linkml_runtime.linkml_model.meta import (ClassDefinition,
12
- ClassDefinitionName,
13
- SchemaDefinition)
11
+ from linkml_runtime.linkml_model.meta import ClassDefinition, ClassDefinitionName
14
12
  from linkml_runtime.utils.formatutils import be, underscore
15
13
 
16
14
  from linkml._version import __version__
@@ -37,9 +35,7 @@ class CsvGenerator(Generator):
37
35
  sep: Optional[str] = None
38
36
  """Separator for columns"""
39
37
 
40
- closure: Optional[
41
- Set[ClassDefinitionName]
42
- ] = None
38
+ closure: Optional[Set[ClassDefinitionName]] = None
43
39
  """List of classes to include in output"""
44
40
 
45
41
  writer: Optional[DictWriter] = None
@@ -69,9 +65,7 @@ class CsvGenerator(Generator):
69
65
  self.closure.update(self.ancestors(self.schema.classes[clsname]))
70
66
 
71
67
  dialect: str = "excel" if self.format == "csv" else "excel-tab"
72
- self.writer = DictWriter(
73
- sys.stdout, ["id", "mappings", "description"], dialect=dialect
74
- )
68
+ self.writer = DictWriter(sys.stdout, ["id", "mappings", "description"], dialect=dialect)
75
69
  self.writer.writeheader()
76
70
 
77
71
  def visit_class(self, cls: ClassDefinition) -> bool:
@@ -18,7 +18,14 @@ _{{ element_description_line }}_
18
18
 
19
19
  URI: {{ gen.uri_link(element) }}
20
20
 
21
+
22
+ {% if diagram_type == "er_diagram" %}
23
+ ```{{ gen.mermaid_directive() }}
24
+ {{ gen.mermaid_diagram([element.name]) }}
25
+ ```
26
+ {% else %}
21
27
  {% include "class_diagram.md.jinja2" %}
28
+ {% endif %}
22
29
 
23
30
  {% if schemaview.class_parents(element.name) or schemaview.class_children(element.name, mixins=False) %}
24
31
 
@@ -1,8 +1,3 @@
1
- {% if diagram_type == "er_diagram" %}
2
- ```{{ gen.mermaid_directive() }}
3
- {{ gen.mermaid_diagram([element.name]) }}
4
- ```
5
- {% else %}
6
1
  {% if schemaview.class_parents(element.name) and schemaview.class_children(element.name) %}
7
2
  ```{{ gen.mermaid_directive() }}
8
3
  classDiagram
@@ -61,5 +56,4 @@
61
56
  {% endif %}
62
57
  {% endfor %}
63
58
  ```
64
- {% endif %}
65
59
  {% endif %}
@@ -1,7 +1,7 @@
1
1
  # Subset: {{ gen.name(element) }}
2
2
 
3
3
  {%- if header -%}
4
- {{header}}
4
+ {{ header }}
5
5
  {%- endif -%}
6
6
 
7
7
  {% if element.description %}
@@ -13,9 +13,32 @@ _{{ element_description_line }}_
13
13
 
14
14
  URI: {{ gen.uri_link(element) }}
15
15
 
16
-
17
16
  {% include "common_metadata.md.jinja2" %}
18
17
 
18
+ {% set classes_in_subset = [] %}
19
+ {% set slots_in_subset = [] %}
20
+ {% set enums_in_subset = [] %}
21
+
22
+ {# Collect classes, slots, and enumerations in subset #}
23
+ {% for c in gen.all_class_objects()|sort(attribute=sort_by) %}
24
+ {%- if element.name in c.in_subset %}
25
+ {% set _ = classes_in_subset.append(c) %}
26
+ {%- endif %}
27
+ {% endfor %}
28
+
29
+ {% for s in gen.all_slot_objects()|sort(attribute=sort_by) %}
30
+ {%- if element.name in s.in_subset %}
31
+ {% set _ = slots_in_subset.append(s) %}
32
+ {%- endif %}
33
+ {% endfor %}
34
+
35
+ {% for e in schemaview.all_enums().values() %}
36
+ {%- if element.name in e.in_subset %}
37
+ {% set _ = enums_in_subset.append(e) %}
38
+ {%- endif %}
39
+ {% endfor %}
40
+
41
+ {% if classes_in_subset %}
19
42
  ## Classes in subset
20
43
 
21
44
  | Class | Description |
@@ -32,34 +55,52 @@ URI: {{ gen.uri_link(element) }}
32
55
 
33
56
  {{c.description}}
34
57
 
58
+ {%- set filtered_slots = [] -%}
59
+
60
+ {%- for s in induced_slots|sort(attribute=sort_by) -%}
61
+ {%- if element.name in s.in_subset or element.name in schemaview.get_slot(s.name).in_subset -%}
62
+ {% set _ = filtered_slots.append(s) %}
63
+ {%- endif -%}
64
+ {%- endfor %}
65
+
66
+ {%- if filtered_slots|length > 0 -%}
35
67
  | Name | Cardinality and Range | Description |
36
68
  | --- | --- | --- |
37
- {% for s in gen.class_induced_slots(c.name)|sort(attribute=sort_by) -%}
38
- {% if element.name in s.in_subset or element.name in schemaview.get_slot(s.name).in_subset -%}
69
+ {% for s in filtered_slots -%}
39
70
  | {{gen.link(s)}} | {{ gen.cardinality(s) }} <br/> {{gen.link(s.range)}} | {{s.description|enshorten}} {% if s.identifier %}**identifier**{% endif %} |
40
- {% endif -%}
41
71
  {% endfor %}
72
+ {%- endif %}
42
73
 
43
- {% endif -%}
74
+
75
+ {%- endif %}
44
76
  {% endfor %}
45
77
 
78
+ {%- endif %}
79
+
80
+
81
+ {% if slots_in_subset %}
46
82
  ## Slots in subset
47
83
 
48
84
  | Slot | Description |
49
85
  | --- | --- |
50
- {% for s in gen.all_slot_objects()|sort(attribute=sort_by) -%}
86
+ {% for s in slots_in_subset|sort(attribute=sort_by) -%}
51
87
  {%- if element.name in s.in_subset -%}
52
- | {{gen.link(s)}} | {{s.description|enshorten}} |
53
- {% endif -%}
88
+ | {{ gen.link(s) }} | {{ s.description|enshorten }} |
89
+ {%- endif %}
54
90
  {% endfor %}
55
91
 
92
+ {%- endif %}
93
+
94
+
95
+ {% if enums_in_subset %}
56
96
  ## Enumerations in subset
57
97
 
58
98
  | Enumeration | Description |
59
99
  | --- | --- |
60
- {% for e in schemaview.all_enums().values()|sort(attribute='name') -%}
61
- {%- if element.name in e.in_subset -%}
62
- | {{gen.link(e)}} | {{e.description|enshorten}} |
63
- {% endif -%}
100
+ {% for e in enums_in_subset|sort(attribute='name') -%}
101
+ {%- if element.name in e.in_subset %}
102
+ | {{ gen.link(e) }} | {{ e.description|enshorten }} |
103
+ {%- endif %}
64
104
  {% endfor %}
65
105
 
106
+ {%- endif %}