rdf-construct 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.
Files changed (88) hide show
  1. rdf_construct/__init__.py +12 -0
  2. rdf_construct/__main__.py +0 -0
  3. rdf_construct/cli.py +1762 -0
  4. rdf_construct/core/__init__.py +33 -0
  5. rdf_construct/core/config.py +116 -0
  6. rdf_construct/core/ordering.py +219 -0
  7. rdf_construct/core/predicate_order.py +212 -0
  8. rdf_construct/core/profile.py +157 -0
  9. rdf_construct/core/selector.py +64 -0
  10. rdf_construct/core/serialiser.py +232 -0
  11. rdf_construct/core/utils.py +89 -0
  12. rdf_construct/cq/__init__.py +77 -0
  13. rdf_construct/cq/expectations.py +365 -0
  14. rdf_construct/cq/formatters/__init__.py +45 -0
  15. rdf_construct/cq/formatters/json.py +104 -0
  16. rdf_construct/cq/formatters/junit.py +104 -0
  17. rdf_construct/cq/formatters/text.py +146 -0
  18. rdf_construct/cq/loader.py +300 -0
  19. rdf_construct/cq/runner.py +321 -0
  20. rdf_construct/diff/__init__.py +59 -0
  21. rdf_construct/diff/change_types.py +214 -0
  22. rdf_construct/diff/comparator.py +338 -0
  23. rdf_construct/diff/filters.py +133 -0
  24. rdf_construct/diff/formatters/__init__.py +71 -0
  25. rdf_construct/diff/formatters/json.py +192 -0
  26. rdf_construct/diff/formatters/markdown.py +210 -0
  27. rdf_construct/diff/formatters/text.py +195 -0
  28. rdf_construct/docs/__init__.py +60 -0
  29. rdf_construct/docs/config.py +238 -0
  30. rdf_construct/docs/extractors.py +603 -0
  31. rdf_construct/docs/generator.py +360 -0
  32. rdf_construct/docs/renderers/__init__.py +7 -0
  33. rdf_construct/docs/renderers/html.py +803 -0
  34. rdf_construct/docs/renderers/json.py +390 -0
  35. rdf_construct/docs/renderers/markdown.py +628 -0
  36. rdf_construct/docs/search.py +278 -0
  37. rdf_construct/docs/templates/html/base.html.jinja +44 -0
  38. rdf_construct/docs/templates/html/class.html.jinja +152 -0
  39. rdf_construct/docs/templates/html/hierarchy.html.jinja +28 -0
  40. rdf_construct/docs/templates/html/index.html.jinja +110 -0
  41. rdf_construct/docs/templates/html/instance.html.jinja +90 -0
  42. rdf_construct/docs/templates/html/namespaces.html.jinja +37 -0
  43. rdf_construct/docs/templates/html/property.html.jinja +124 -0
  44. rdf_construct/docs/templates/html/single_page.html.jinja +169 -0
  45. rdf_construct/lint/__init__.py +75 -0
  46. rdf_construct/lint/config.py +214 -0
  47. rdf_construct/lint/engine.py +396 -0
  48. rdf_construct/lint/formatters.py +327 -0
  49. rdf_construct/lint/rules.py +692 -0
  50. rdf_construct/main.py +6 -0
  51. rdf_construct/puml2rdf/__init__.py +103 -0
  52. rdf_construct/puml2rdf/config.py +230 -0
  53. rdf_construct/puml2rdf/converter.py +420 -0
  54. rdf_construct/puml2rdf/merger.py +200 -0
  55. rdf_construct/puml2rdf/model.py +202 -0
  56. rdf_construct/puml2rdf/parser.py +565 -0
  57. rdf_construct/puml2rdf/validators.py +451 -0
  58. rdf_construct/shacl/__init__.py +56 -0
  59. rdf_construct/shacl/config.py +166 -0
  60. rdf_construct/shacl/converters.py +520 -0
  61. rdf_construct/shacl/generator.py +364 -0
  62. rdf_construct/shacl/namespaces.py +93 -0
  63. rdf_construct/stats/__init__.py +29 -0
  64. rdf_construct/stats/collector.py +178 -0
  65. rdf_construct/stats/comparator.py +298 -0
  66. rdf_construct/stats/formatters/__init__.py +83 -0
  67. rdf_construct/stats/formatters/json.py +38 -0
  68. rdf_construct/stats/formatters/markdown.py +153 -0
  69. rdf_construct/stats/formatters/text.py +186 -0
  70. rdf_construct/stats/metrics/__init__.py +26 -0
  71. rdf_construct/stats/metrics/basic.py +147 -0
  72. rdf_construct/stats/metrics/complexity.py +137 -0
  73. rdf_construct/stats/metrics/connectivity.py +130 -0
  74. rdf_construct/stats/metrics/documentation.py +128 -0
  75. rdf_construct/stats/metrics/hierarchy.py +207 -0
  76. rdf_construct/stats/metrics/properties.py +88 -0
  77. rdf_construct/uml/__init__.py +22 -0
  78. rdf_construct/uml/context.py +194 -0
  79. rdf_construct/uml/mapper.py +371 -0
  80. rdf_construct/uml/odm_renderer.py +789 -0
  81. rdf_construct/uml/renderer.py +684 -0
  82. rdf_construct/uml/uml_layout.py +393 -0
  83. rdf_construct/uml/uml_style.py +613 -0
  84. rdf_construct-0.2.0.dist-info/METADATA +431 -0
  85. rdf_construct-0.2.0.dist-info/RECORD +88 -0
  86. rdf_construct-0.2.0.dist-info/WHEEL +4 -0
  87. rdf_construct-0.2.0.dist-info/entry_points.txt +3 -0
  88. rdf_construct-0.2.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,103 @@
1
+ """PlantUML to RDF import module.
2
+
3
+ This module provides tools for converting PlantUML class diagrams
4
+ to RDF/OWL ontologies, enabling diagram-first ontology design.
5
+
6
+ Example:
7
+ from rdf_construct.puml_import import PlantUMLParser, PumlToRdfConverter
8
+
9
+ # Parse a PlantUML file
10
+ parser = PlantUMLParser()
11
+ result = parser.parse_file(Path("design.puml"))
12
+
13
+ if result.success:
14
+ # Convert to RDF
15
+ converter = PumlToRdfConverter()
16
+ rdf_result = converter.convert(result.model)
17
+
18
+ # Save the ontology
19
+ rdf_result.graph.serialize("ontology.ttl", format="turtle")
20
+ """
21
+
22
+ from rdf_construct.puml2rdf.model import (
23
+ PropertyKind,
24
+ PumlAttribute,
25
+ PumlClass,
26
+ PumlModel,
27
+ PumlNote,
28
+ PumlPackage,
29
+ PumlRelationship,
30
+ RelationshipType,
31
+ )
32
+ from rdf_construct.puml2rdf.parser import (
33
+ ParseError,
34
+ ParseResult,
35
+ PlantUMLParser,
36
+ )
37
+ from rdf_construct.puml2rdf.converter import (
38
+ ConversionConfig,
39
+ ConversionResult,
40
+ PumlToRdfConverter,
41
+ XSD_TYPE_MAP,
42
+ )
43
+ from rdf_construct.puml2rdf.config import (
44
+ DatatypeMapping,
45
+ NamespaceMapping,
46
+ PumlImportConfig,
47
+ create_default_config,
48
+ load_import_config,
49
+ )
50
+ from rdf_construct.puml2rdf.merger import (
51
+ MergeResult,
52
+ OntologyMerger,
53
+ merge_with_existing,
54
+ )
55
+ from rdf_construct.puml2rdf.validators import (
56
+ PumlModelValidator,
57
+ RdfValidator,
58
+ Severity,
59
+ ValidationIssue,
60
+ ValidationResult,
61
+ validate_puml,
62
+ validate_rdf,
63
+ )
64
+
65
+
66
+ __all__ = [
67
+ # Model classes
68
+ "PropertyKind",
69
+ "PumlAttribute",
70
+ "PumlClass",
71
+ "PumlModel",
72
+ "PumlNote",
73
+ "PumlPackage",
74
+ "PumlRelationship",
75
+ "RelationshipType",
76
+ # Parser
77
+ "ParseError",
78
+ "ParseResult",
79
+ "PlantUMLParser",
80
+ # Converter
81
+ "ConversionConfig",
82
+ "ConversionResult",
83
+ "PumlToRdfConverter",
84
+ "XSD_TYPE_MAP",
85
+ # Config
86
+ "DatatypeMapping",
87
+ "NamespaceMapping",
88
+ "PumlImportConfig",
89
+ "create_default_config",
90
+ "load_import_config",
91
+ # Merger
92
+ "MergeResult",
93
+ "OntologyMerger",
94
+ "merge_with_existing",
95
+ # Validators
96
+ "PumlModelValidator",
97
+ "RdfValidator",
98
+ "Severity",
99
+ "ValidationIssue",
100
+ "ValidationResult",
101
+ "validate_puml",
102
+ "validate_rdf",
103
+ ]
@@ -0,0 +1,230 @@
1
+ """Configuration handling for PlantUML import.
2
+
3
+ This module provides YAML-based configuration for controlling
4
+ how PlantUML diagrams are converted to RDF ontologies.
5
+ """
6
+
7
+ from dataclasses import dataclass, field
8
+ from pathlib import Path
9
+ from typing import Any, Optional
10
+
11
+ import yaml
12
+
13
+ from rdf_construct.puml2rdf.converter import ConversionConfig
14
+
15
+
16
+ @dataclass
17
+ class NamespaceMapping:
18
+ """Maps a PlantUML package to an RDF namespace.
19
+
20
+ Attributes:
21
+ package: PlantUML package name or pattern
22
+ namespace_uri: Target namespace URI
23
+ prefix: Preferred prefix for this namespace
24
+ """
25
+
26
+ package: str
27
+ namespace_uri: str
28
+ prefix: Optional[str] = None
29
+
30
+
31
+ @dataclass
32
+ class DatatypeMapping:
33
+ """Custom datatype mapping.
34
+
35
+ Attributes:
36
+ puml_type: PlantUML/UML type name
37
+ rdf_type: Full RDF type URI or CURIE
38
+ """
39
+
40
+ puml_type: str
41
+ rdf_type: str
42
+
43
+
44
+ @dataclass
45
+ class PumlImportConfig:
46
+ """Complete configuration for PlantUML to RDF import.
47
+
48
+ Attributes:
49
+ default_namespace: Default namespace for entities without explicit package
50
+ language: Language tag for labels/comments
51
+ generate_labels: Whether to auto-generate rdfs:label
52
+ camel_to_label: Convert camelCase to readable labels
53
+ generate_inverse_properties: Create inverse for each object property
54
+ namespace_mappings: Package to namespace mappings
55
+ datatype_mappings: Custom datatype conversions
56
+ prefix_order: Preferred prefix ordering for output
57
+ ontology_imports: URIs to add as owl:imports
58
+ annotation_properties: Additional properties to preserve
59
+ """
60
+
61
+ default_namespace: str = "http://example.org/ontology#"
62
+ language: str = "en"
63
+ generate_labels: bool = True
64
+ camel_to_label: bool = True
65
+ generate_inverse_properties: bool = False
66
+ namespace_mappings: list[NamespaceMapping] = field(default_factory=list)
67
+ datatype_mappings: list[DatatypeMapping] = field(default_factory=list)
68
+ prefix_order: list[str] = field(default_factory=list)
69
+ ontology_imports: list[str] = field(default_factory=list)
70
+ annotation_properties: list[str] = field(default_factory=list)
71
+
72
+ def to_conversion_config(self) -> ConversionConfig:
73
+ """Convert to the simpler ConversionConfig used by converter."""
74
+ return ConversionConfig(
75
+ default_namespace=self.default_namespace,
76
+ language=self.language,
77
+ generate_labels=self.generate_labels,
78
+ camel_to_label=self.camel_to_label,
79
+ generate_inverse_properties=self.generate_inverse_properties,
80
+ )
81
+
82
+
83
+ def load_import_config(path: Path) -> PumlImportConfig:
84
+ """Load PlantUML import configuration from a YAML file.
85
+
86
+ Args:
87
+ path: Path to the YAML configuration file
88
+
89
+ Returns:
90
+ Parsed configuration object
91
+
92
+ Raises:
93
+ FileNotFoundError: If the config file doesn't exist
94
+ ValueError: If the config format is invalid
95
+ """
96
+ if not path.exists():
97
+ raise FileNotFoundError(f"Configuration file not found: {path}")
98
+
99
+ with open(path, "r", encoding="utf-8") as f:
100
+ data = yaml.safe_load(f)
101
+
102
+ if not isinstance(data, dict):
103
+ raise ValueError("Configuration must be a YAML dictionary")
104
+
105
+ return _parse_config(data)
106
+
107
+
108
+ def _parse_config(data: dict[str, Any]) -> PumlImportConfig:
109
+ """Parse configuration dictionary into PumlImportConfig.
110
+
111
+ Args:
112
+ data: Raw YAML data dictionary
113
+
114
+ Returns:
115
+ Parsed configuration object
116
+ """
117
+ config = PumlImportConfig()
118
+
119
+ # Simple string/bool fields
120
+ if "default_namespace" in data:
121
+ config.default_namespace = str(data["default_namespace"])
122
+ if "language" in data:
123
+ config.language = str(data["language"])
124
+ if "generate_labels" in data:
125
+ config.generate_labels = bool(data["generate_labels"])
126
+ if "camel_to_label" in data:
127
+ config.camel_to_label = bool(data["camel_to_label"])
128
+ if "generate_inverse_properties" in data:
129
+ config.generate_inverse_properties = bool(data["generate_inverse_properties"])
130
+
131
+ # Parse namespace mappings
132
+ if "namespace_mappings" in data:
133
+ mappings = data["namespace_mappings"]
134
+ if isinstance(mappings, list):
135
+ for item in mappings:
136
+ if isinstance(item, dict):
137
+ config.namespace_mappings.append(
138
+ NamespaceMapping(
139
+ package=item.get("package", ""),
140
+ namespace_uri=item.get("namespace_uri", ""),
141
+ prefix=item.get("prefix"),
142
+ )
143
+ )
144
+
145
+ # Parse datatype mappings
146
+ if "datatype_mappings" in data:
147
+ mappings = data["datatype_mappings"]
148
+ if isinstance(mappings, dict):
149
+ for puml_type, rdf_type in mappings.items():
150
+ config.datatype_mappings.append(
151
+ DatatypeMapping(puml_type=puml_type, rdf_type=str(rdf_type))
152
+ )
153
+ elif isinstance(mappings, list):
154
+ for item in mappings:
155
+ if isinstance(item, dict):
156
+ config.datatype_mappings.append(
157
+ DatatypeMapping(
158
+ puml_type=item.get("puml_type", ""),
159
+ rdf_type=item.get("rdf_type", ""),
160
+ )
161
+ )
162
+
163
+ # Parse simple lists
164
+ if "prefix_order" in data:
165
+ config.prefix_order = list(data["prefix_order"])
166
+ if "ontology_imports" in data:
167
+ config.ontology_imports = list(data["ontology_imports"])
168
+ if "annotation_properties" in data:
169
+ config.annotation_properties = list(data["annotation_properties"])
170
+
171
+ return config
172
+
173
+
174
+ def create_default_config() -> str:
175
+ """Generate a default configuration YAML string.
176
+
177
+ Returns:
178
+ YAML string with default configuration and comments
179
+ """
180
+ return '''# PlantUML Import Configuration
181
+ # ================================
182
+
183
+ # Default namespace for entities without explicit package
184
+ default_namespace: "http://example.org/ontology#"
185
+
186
+ # Language tag for labels and comments
187
+ language: "en"
188
+
189
+ # Automatically generate rdfs:label from entity names
190
+ generate_labels: true
191
+
192
+ # Convert camelCase names to readable labels
193
+ # e.g., 'floorArea' -> 'floor area'
194
+ camel_to_label: true
195
+
196
+ # Generate inverse properties for object properties
197
+ generate_inverse_properties: false
198
+
199
+ # Map PlantUML packages to RDF namespaces
200
+ namespace_mappings:
201
+ - package: "building"
202
+ namespace_uri: "http://example.org/building#"
203
+ prefix: "bld"
204
+ # - package: "core"
205
+ # namespace_uri: "http://example.org/core#"
206
+ # prefix: "core"
207
+
208
+ # Custom datatype mappings (PlantUML type -> XSD type)
209
+ datatype_mappings:
210
+ Money: "xsd:decimal"
211
+ Percentage: "xsd:decimal"
212
+ Identifier: "xsd:string"
213
+ # Add custom types as needed
214
+
215
+ # Preferred prefix ordering in output
216
+ prefix_order:
217
+ - "" # Default namespace first
218
+ - "owl"
219
+ - "rdfs"
220
+ - "xsd"
221
+
222
+ # URIs to include as owl:imports
223
+ ontology_imports: []
224
+ # - "http://example.org/core"
225
+
226
+ # Annotation properties to preserve from notes
227
+ annotation_properties: []
228
+ # - "dcterms:description"
229
+ # - "skos:definition"
230
+ '''