cognite-neat 0.92.3__py3-none-any.whl → 0.93.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.
Potentially problematic release.
This version of cognite-neat might be problematic. Click here for more details.
- cognite/neat/__init__.py +3 -2
- cognite/neat/{app → _app}/api/configuration.py +9 -7
- cognite/neat/_app/api/context_manager/__init__.py +3 -0
- cognite/neat/{app → _app}/api/context_manager/manager.py +1 -1
- cognite/neat/{app → _app}/api/explorer.py +5 -5
- cognite/neat/{app → _app}/api/routers/configuration.py +2 -2
- cognite/neat/{app → _app}/api/routers/crud.py +4 -4
- cognite/neat/{app → _app}/api/routers/workflows.py +7 -7
- cognite/neat/{app → _app}/main.py +1 -1
- cognite/neat/_app/ui/neat-app/package-lock.json +18306 -0
- cognite/neat/_app/ui/neat-app/package.json +62 -0
- cognite/neat/_app/ui/neat-app/public/favicon.ico +0 -0
- cognite/neat/_app/ui/neat-app/public/img/architect-icon.svg +116 -0
- cognite/neat/_app/ui/neat-app/public/img/developer-icon.svg +112 -0
- cognite/neat/_app/ui/neat-app/public/img/sme-icon.svg +34 -0
- cognite/neat/_app/ui/neat-app/public/index.html +43 -0
- cognite/neat/_app/ui/neat-app/public/logo192.png +0 -0
- cognite/neat/_app/ui/neat-app/public/manifest.json +25 -0
- cognite/neat/_app/ui/neat-app/public/robots.txt +3 -0
- cognite/neat/_app/ui/neat-app/src/App.css +38 -0
- cognite/neat/_app/ui/neat-app/src/App.js +17 -0
- cognite/neat/_app/ui/neat-app/src/App.test.js +8 -0
- cognite/neat/_app/ui/neat-app/src/MainContainer.tsx +70 -0
- cognite/neat/_app/ui/neat-app/src/components/JsonViewer.tsx +43 -0
- cognite/neat/_app/ui/neat-app/src/components/LocalUploader.tsx +124 -0
- cognite/neat/_app/ui/neat-app/src/components/OverviewComponentEditorDialog.tsx +63 -0
- cognite/neat/_app/ui/neat-app/src/components/StepEditorDialog.tsx +511 -0
- cognite/neat/_app/ui/neat-app/src/components/TabPanel.tsx +36 -0
- cognite/neat/_app/ui/neat-app/src/components/Utils.tsx +56 -0
- cognite/neat/_app/ui/neat-app/src/components/WorkflowDeleteDialog.tsx +60 -0
- cognite/neat/_app/ui/neat-app/src/components/WorkflowExecutionReport.tsx +112 -0
- cognite/neat/_app/ui/neat-app/src/components/WorkflowImportExportDialog.tsx +67 -0
- cognite/neat/_app/ui/neat-app/src/components/WorkflowMetadataDialog.tsx +79 -0
- cognite/neat/_app/ui/neat-app/src/index.css +13 -0
- cognite/neat/_app/ui/neat-app/src/index.js +13 -0
- cognite/neat/_app/ui/neat-app/src/logo.svg +1 -0
- cognite/neat/_app/ui/neat-app/src/reportWebVitals.js +13 -0
- cognite/neat/_app/ui/neat-app/src/setupTests.js +5 -0
- cognite/neat/_app/ui/neat-app/src/types/WorkflowTypes.ts +388 -0
- cognite/neat/_app/ui/neat-app/src/views/AboutView.tsx +61 -0
- cognite/neat/_app/ui/neat-app/src/views/ConfigView.tsx +184 -0
- cognite/neat/_app/ui/neat-app/src/views/GlobalConfigView.tsx +180 -0
- cognite/neat/_app/ui/neat-app/src/views/WorkflowView.tsx +570 -0
- cognite/neat/_app/ui/neat-app/tsconfig.json +27 -0
- cognite/neat/{config.py → _config.py} +3 -3
- cognite/neat/{constants.py → _constants.py} +13 -5
- cognite/neat/_graph/_shared.py +34 -0
- cognite/neat/{graph → _graph}/_tracking/base.py +1 -1
- cognite/neat/{graph → _graph}/_tracking/log.py +1 -1
- cognite/neat/{graph → _graph}/extractors/__init__.py +5 -0
- cognite/neat/{graph → _graph}/extractors/_base.py +2 -2
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_assets.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_base.py +4 -4
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_classic.py +5 -5
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_data_sets.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_events.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_files.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_labels.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_relationships.py +2 -2
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_sequences.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_classic_cdf/_timeseries.py +1 -1
- cognite/neat/{graph → _graph}/extractors/_dexpi.py +5 -5
- cognite/neat/{graph → _graph}/extractors/_dms.py +3 -3
- cognite/neat/_graph/extractors/_iodd.py +402 -0
- cognite/neat/{graph → _graph}/extractors/_mock_graph_generator.py +9 -8
- cognite/neat/_graph/extractors/_rdf_file.py +49 -0
- cognite/neat/{graph → _graph}/loaders/_base.py +5 -5
- cognite/neat/{graph → _graph}/loaders/_rdf2asset.py +11 -10
- cognite/neat/{graph → _graph}/loaders/_rdf2dms.py +10 -10
- cognite/neat/{graph → _graph}/queries/_base.py +91 -19
- cognite/neat/{graph → _graph}/queries/_construct.py +5 -5
- cognite/neat/{graph → _graph}/queries/_shared.py +3 -3
- cognite/neat/{graph → _graph}/transformers/__init__.py +6 -0
- cognite/neat/{graph → _graph}/transformers/_classic_cdf.py +135 -3
- cognite/neat/_graph/transformers/_iodd.py +25 -0
- cognite/neat/_graph/transformers/_prune_graph.py +126 -0
- cognite/neat/{graph → _graph}/transformers/_rdfpath.py +3 -3
- cognite/neat/_graph/transformers/_value_type.py +66 -0
- cognite/neat/{issues → _issues}/_base.py +32 -17
- cognite/neat/{issues → _issues}/errors/__init__.py +1 -1
- cognite/neat/{issues → _issues}/errors/_external.py +8 -8
- cognite/neat/{issues → _issues}/errors/_general.py +5 -5
- cognite/neat/{issues → _issues}/errors/_properties.py +7 -7
- cognite/neat/{issues → _issues}/errors/_resources.py +11 -11
- cognite/neat/{issues → _issues}/errors/_workflow.py +5 -5
- cognite/neat/{issues → _issues}/warnings/__init__.py +1 -1
- cognite/neat/{issues → _issues}/warnings/_external.py +5 -5
- cognite/neat/{issues → _issues}/warnings/_general.py +4 -4
- cognite/neat/{issues → _issues}/warnings/_models.py +10 -10
- cognite/neat/{issues → _issues}/warnings/_properties.py +6 -6
- cognite/neat/{issues → _issues}/warnings/_resources.py +5 -5
- cognite/neat/{issues → _issues}/warnings/user_modeling.py +9 -9
- cognite/neat/_rules/_constants.py +190 -0
- cognite/neat/{rules → _rules}/_shared.py +5 -5
- cognite/neat/_rules/analysis/__init__.py +5 -0
- cognite/neat/{rules → _rules}/analysis/_asset.py +5 -5
- cognite/neat/{rules → _rules}/analysis/_base.py +5 -5
- cognite/neat/_rules/analysis/_dms.py +43 -0
- cognite/neat/{rules → _rules}/analysis/_information.py +12 -6
- cognite/neat/_rules/catalog/__init__.py +6 -0
- cognite/neat/_rules/catalog/info-rules-imf.xlsx +0 -0
- cognite/neat/{rules → _rules}/exporters/__init__.py +2 -0
- cognite/neat/{rules → _rules}/exporters/_base.py +3 -3
- cognite/neat/{rules → _rules}/exporters/_rules2dms.py +5 -5
- cognite/neat/{rules → _rules}/exporters/_rules2excel.py +12 -8
- cognite/neat/_rules/exporters/_rules2instance_template.py +152 -0
- cognite/neat/{rules → _rules}/exporters/_rules2ontology.py +10 -9
- cognite/neat/{rules → _rules}/exporters/_rules2yaml.py +1 -3
- cognite/neat/{rules → _rules}/exporters/_validation.py +2 -2
- cognite/neat/{rules → _rules}/importers/_base.py +3 -3
- cognite/neat/{rules → _rules}/importers/_dms2rules.py +9 -9
- cognite/neat/{rules → _rules}/importers/_dtdl2rules/dtdl_converter.py +7 -7
- cognite/neat/{rules → _rules}/importers/_dtdl2rules/dtdl_importer.py +9 -9
- cognite/neat/{rules → _rules}/importers/_dtdl2rules/spec.py +1 -1
- cognite/neat/_rules/importers/_rdf/_base.py +144 -0
- cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/_imf2classes.py +1 -1
- cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/_imf2metadata.py +4 -4
- cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/_imf2properties.py +2 -1
- cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/_imf2rules.py +8 -39
- cognite/neat/{rules → _rules}/importers/_rdf/_inference2rules.py +33 -106
- cognite/neat/{rules → _rules}/importers/_rdf/_owl2rules/_owl2classes.py +1 -1
- cognite/neat/{rules → _rules}/importers/_rdf/_owl2rules/_owl2metadata.py +5 -5
- cognite/neat/{rules → _rules}/importers/_rdf/_owl2rules/_owl2properties.py +1 -1
- cognite/neat/_rules/importers/_rdf/_owl2rules/_owl2rules.py +39 -0
- cognite/neat/{rules → _rules}/importers/_rdf/_shared.py +4 -4
- cognite/neat/{rules → _rules}/importers/_spreadsheet2rules.py +7 -7
- cognite/neat/{rules → _rules}/importers/_yaml2rules.py +5 -5
- cognite/neat/{rules → _rules}/models/__init__.py +5 -5
- cognite/neat/{rules → _rules}/models/_base_input.py +15 -6
- cognite/neat/{rules → _rules}/models/_base_rules.py +14 -2
- cognite/neat/{rules → _rules}/models/_rdfpath.py +1 -1
- cognite/neat/_rules/models/_types.py +151 -0
- cognite/neat/{rules → _rules}/models/asset/_rules.py +4 -4
- cognite/neat/{rules → _rules}/models/asset/_rules_input.py +4 -4
- cognite/neat/{rules → _rules}/models/asset/_validation.py +7 -7
- cognite/neat/{rules → _rules}/models/data_types.py +15 -12
- cognite/neat/{rules → _rules}/models/dms/_exporter.py +60 -12
- cognite/neat/{rules → _rules}/models/dms/_rules.py +26 -23
- cognite/neat/{rules → _rules}/models/dms/_rules_input.py +4 -4
- cognite/neat/{rules → _rules}/models/dms/_schema.py +15 -14
- cognite/neat/{rules → _rules}/models/dms/_validation.py +8 -8
- cognite/neat/{rules → _rules}/models/domain.py +6 -6
- cognite/neat/{rules → _rules}/models/entities/__init__.py +1 -2
- cognite/neat/_rules/models/entities/_constants.py +15 -0
- cognite/neat/{rules → _rules}/models/entities/_loaders.py +2 -2
- cognite/neat/{rules → _rules}/models/entities/_multi_value.py +15 -2
- cognite/neat/{rules → _rules}/models/entities/_single_value.py +7 -4
- cognite/neat/{rules → _rules}/models/information/_rules.py +34 -22
- cognite/neat/{rules → _rules}/models/information/_rules_input.py +3 -3
- cognite/neat/{rules → _rules}/models/information/_validation.py +6 -5
- cognite/neat/_rules/models/mapping/__init__.py +4 -0
- cognite/neat/_rules/models/mapping/_base.py +131 -0
- cognite/neat/_rules/models/mapping/_classic2core.py +150 -0
- cognite/neat/{rules → _rules}/transformers/__init__.py +15 -2
- cognite/neat/{rules → _rules}/transformers/_base.py +3 -3
- cognite/neat/{rules → _rules}/transformers/_converters.py +289 -20
- cognite/neat/{rules/transformers/_map_onto.py → _rules/transformers/_mapping.py} +46 -4
- cognite/neat/{rules → _rules}/transformers/_pipelines.py +4 -4
- cognite/neat/{rules → _rules}/transformers/_verification.py +10 -4
- cognite/neat/_session/__init__.py +3 -0
- cognite/neat/_session/_base.py +86 -0
- cognite/neat/_session/_prepare.py +61 -0
- cognite/neat/_session/_read.py +118 -0
- cognite/neat/_session/_show.py +96 -0
- cognite/neat/_session/_state.py +69 -0
- cognite/neat/_session/_to.py +70 -0
- cognite/neat/_session/_wizard.py +39 -0
- cognite/neat/_session/exceptions.py +42 -0
- cognite/neat/{store → _store}/_base.py +63 -32
- cognite/neat/{store → _store}/_provenance.py +11 -1
- cognite/neat/{utils → _utils}/auth.py +14 -3
- cognite/neat/{utils → _utils}/auxiliary.py +1 -1
- cognite/neat/{utils → _utils}/cdf/loaders/_data_modeling.py +8 -2
- cognite/neat/{utils → _utils}/cdf/loaders/_ingestion.py +1 -1
- cognite/neat/{utils → _utils}/upload.py +1 -1
- cognite/neat/_version.py +1 -1
- cognite/neat/_workflows/__init__.py +17 -0
- cognite/neat/{workflows → _workflows}/base.py +10 -10
- cognite/neat/{workflows → _workflows}/cdf_store.py +3 -3
- cognite/neat/{workflows → _workflows}/examples/Export_DMS/workflow.yaml +89 -89
- cognite/neat/{workflows → _workflows}/manager.py +6 -6
- cognite/neat/{workflows → _workflows}/steps/data_contracts.py +3 -3
- cognite/neat/{workflows → _workflows}/steps/lib/current/graph_extractor.py +8 -31
- cognite/neat/{workflows → _workflows}/steps/lib/current/graph_loader.py +4 -4
- cognite/neat/{workflows → _workflows}/steps/lib/current/graph_store.py +4 -4
- cognite/neat/{workflows → _workflows}/steps/lib/current/rules_exporter.py +8 -8
- cognite/neat/{workflows → _workflows}/steps/lib/current/rules_importer.py +13 -13
- cognite/neat/{workflows → _workflows}/steps/lib/current/rules_validator.py +8 -8
- cognite/neat/{workflows → _workflows}/steps/lib/io/io_steps.py +3 -3
- cognite/neat/{workflows → _workflows}/steps/step_model.py +3 -3
- cognite/neat/{workflows → _workflows}/steps_registry.py +9 -9
- cognite/neat/{workflows → _workflows}/tasks.py +1 -1
- cognite/neat/{workflows → _workflows}/triggers.py +2 -2
- {cognite_neat-0.92.3.dist-info → cognite_neat-0.93.0.dist-info}/METADATA +6 -2
- cognite_neat-0.93.0.dist-info/RECORD +276 -0
- {cognite_neat-0.92.3.dist-info → cognite_neat-0.93.0.dist-info}/WHEEL +1 -1
- cognite_neat-0.93.0.dist-info/entry_points.txt +3 -0
- cognite/neat/app/api/context_manager/__init__.py +0 -3
- cognite/neat/graph/_shared.py +0 -5
- cognite/neat/graph/extractors/_iodd.py +0 -160
- cognite/neat/graph/extractors/_rdf_file.py +0 -26
- cognite/neat/rules/analysis/__init__.py +0 -6
- cognite/neat/rules/examples/__init__.py +0 -10
- cognite/neat/rules/examples/info-rules-imf.xlsx +0 -0
- cognite/neat/rules/examples/wind-energy.owl +0 -1511
- cognite/neat/rules/importers/_rdf/_owl2rules/_owl2rules.py +0 -65
- cognite/neat/rules/models/_types.py +0 -96
- cognite/neat/rules/models/entities/_constants.py +0 -73
- cognite/neat/utils/regex_patterns.py +0 -58
- cognite/neat/workflows/__init__.py +0 -12
- cognite_neat-0.92.3.dist-info/RECORD +0 -224
- cognite_neat-0.92.3.dist-info/entry_points.txt +0 -3
- /cognite/neat/{app → _app}/api/__init__.py +0 -0
- /cognite/neat/{app → _app}/api/asgi/metrics.py +0 -0
- /cognite/neat/{app → _app}/api/data_classes/__init__.py +0 -0
- /cognite/neat/{app → _app}/api/data_classes/rest.py +0 -0
- /cognite/neat/{app → _app}/api/routers/metrics.py +0 -0
- /cognite/neat/{app → _app}/api/utils/__init__.py +0 -0
- /cognite/neat/{app → _app}/api/utils/data_mapping.py +0 -0
- /cognite/neat/{app → _app}/api/utils/logging.py +0 -0
- /cognite/neat/{app → _app}/api/utils/query_templates.py +0 -0
- /cognite/neat/{app → _app}/monitoring/__init__.py +0 -0
- /cognite/neat/{app → _app}/monitoring/metrics.py +0 -0
- /cognite/neat/{app → _app}/ui/index.html +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/.gitignore +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/README.md +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/asset-manifest.json +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/favicon.ico +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/img/architect-icon.svg +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/img/developer-icon.svg +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/img/sme-icon.svg +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/index.html +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/logo192.png +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/manifest.json +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/robots.txt +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/static/css/main.72e3d92e.css +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/static/css/main.72e3d92e.css.map +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/static/js/main.5a52cf09.js +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/static/js/main.5a52cf09.js.LICENSE.txt +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/static/js/main.5a52cf09.js.map +0 -0
- /cognite/neat/{app → _app}/ui/neat-app/build/static/media/logo.8093b84df9ed36a174c629d6fe0b730d.svg +0 -0
- /cognite/neat/{graph → _graph}/__init__.py +0 -0
- /cognite/neat/{graph → _graph}/_tracking/__init__.py +0 -0
- /cognite/neat/{graph → _graph}/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
- /cognite/neat/{graph → _graph}/examples/Knowledge-Graph-Nordic44.xml +0 -0
- /cognite/neat/{graph → _graph}/examples/__init__.py +0 -0
- /cognite/neat/{graph → _graph}/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
- /cognite/neat/{graph → _graph}/extractors/_classic_cdf/__init__.py +0 -0
- /cognite/neat/{graph → _graph}/loaders/__init__.py +0 -0
- /cognite/neat/{graph → _graph}/models.py +0 -0
- /cognite/neat/{graph → _graph}/queries/__init__.py +0 -0
- /cognite/neat/{graph → _graph}/transformers/_base.py +0 -0
- /cognite/neat/{issues → _issues}/__init__.py +0 -0
- /cognite/neat/{issues → _issues}/formatters.py +0 -0
- /cognite/neat/{rules → _rules}/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/importers/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/importers/_dtdl2rules/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/importers/_dtdl2rules/_unit_lookup.py +0 -0
- /cognite/neat/{rules → _rules}/importers/_rdf/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/importers/_rdf/_imf2rules/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/importers/_rdf/_owl2rules/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/models/asset/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/models/dms/__init__.py +0 -0
- /cognite/neat/{rules → _rules}/models/entities/_types.py +0 -0
- /cognite/neat/{rules → _rules}/models/entities/_wrapped.py +0 -0
- /cognite/neat/{rules → _rules}/models/information/__init__.py +0 -0
- /cognite/neat/{store → _store}/__init__.py +0 -0
- /cognite/neat/{utils → _utils}/__init__.py +0 -0
- /cognite/neat/{utils → _utils}/cdf/__init__.py +0 -0
- /cognite/neat/{utils → _utils}/cdf/data_classes.py +0 -0
- /cognite/neat/{utils → _utils}/cdf/loaders/__init__.py +0 -0
- /cognite/neat/{utils → _utils}/cdf/loaders/_base.py +0 -0
- /cognite/neat/{utils → _utils}/collection_.py +0 -0
- /cognite/neat/{utils → _utils}/rdf_.py +0 -0
- /cognite/neat/{utils → _utils}/spreadsheet.py +0 -0
- /cognite/neat/{utils → _utils}/text.py +0 -0
- /cognite/neat/{utils → _utils}/time_.py +0 -0
- /cognite/neat/{utils → _utils}/xml_.py +0 -0
- /cognite/neat/{workflows → _workflows}/examples/Export_Semantic_Data_Model/workflow.yaml +0 -0
- /cognite/neat/{workflows → _workflows}/examples/Import_DMS/workflow.yaml +0 -0
- /cognite/neat/{workflows → _workflows}/examples/Validate_Rules/workflow.yaml +0 -0
- /cognite/neat/{workflows → _workflows}/examples/Validate_Solution_Model/workflow.yaml +0 -0
- /cognite/neat/{workflows → _workflows}/model.py +0 -0
- /cognite/neat/{workflows → _workflows}/steps/__init__.py +0 -0
- /cognite/neat/{workflows → _workflows}/steps/lib/__init__.py +0 -0
- /cognite/neat/{workflows → _workflows}/steps/lib/current/__init__.py +0 -0
- /cognite/neat/{workflows → _workflows}/steps/lib/io/__init__.py +0 -0
- /cognite/neat/{workflows → _workflows}/utils.py +0 -0
- {cognite_neat-0.92.3.dist-info → cognite_neat-0.93.0.dist-info}/LICENSE +0 -0
|
@@ -3,23 +3,21 @@ from datetime import datetime
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import cast
|
|
5
5
|
|
|
6
|
-
from rdflib import RDF
|
|
6
|
+
from rdflib import RDF
|
|
7
7
|
from rdflib import Literal as RdfLiteral
|
|
8
8
|
|
|
9
|
-
from cognite.neat.
|
|
10
|
-
from cognite.neat.
|
|
11
|
-
from cognite.neat.
|
|
12
|
-
from cognite.neat.
|
|
13
|
-
from cognite.neat.
|
|
14
|
-
from cognite.neat.
|
|
15
|
-
from cognite.neat.rules.models._base_rules import MatchType
|
|
16
|
-
from cognite.neat.rules.models.entities._single_value import UnknownEntity
|
|
17
|
-
from cognite.neat.rules.models.information import (
|
|
18
|
-
InformationInputRules,
|
|
9
|
+
from cognite.neat._constants import DEFAULT_NAMESPACE
|
|
10
|
+
from cognite.neat._issues.warnings import PropertyValueTypeUndefinedWarning
|
|
11
|
+
from cognite.neat._rules.models._base_rules import MatchType
|
|
12
|
+
from cognite.neat._rules.models.data_types import AnyURI
|
|
13
|
+
from cognite.neat._rules.models.entities._single_value import UnknownEntity
|
|
14
|
+
from cognite.neat._rules.models.information import (
|
|
19
15
|
InformationMetadata,
|
|
20
16
|
)
|
|
21
|
-
from cognite.neat.
|
|
22
|
-
from cognite.neat.
|
|
17
|
+
from cognite.neat._store import NeatGraphStore
|
|
18
|
+
from cognite.neat._utils.rdf_ import remove_namespace_from_uri
|
|
19
|
+
|
|
20
|
+
from ._base import DEFAULT_NON_EXISTING_NODE_TYPE, BaseRDFImporter
|
|
23
21
|
|
|
24
22
|
ORDERED_CLASSES_QUERY = """SELECT ?class (count(?s) as ?instances )
|
|
25
23
|
WHERE { ?s a ?class . }
|
|
@@ -36,7 +34,7 @@ INSTANCE_PROPERTIES_DEFINITION = """SELECT ?property (count(?property) as ?occur
|
|
|
36
34
|
GROUP BY ?property ?dataType ?objectType"""
|
|
37
35
|
|
|
38
36
|
|
|
39
|
-
class InferenceImporter(
|
|
37
|
+
class InferenceImporter(BaseRDFImporter):
|
|
40
38
|
"""Infers rules from a triple store.
|
|
41
39
|
|
|
42
40
|
Rules inference through analysis of knowledge graph provided in various formats.
|
|
@@ -50,62 +48,32 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
|
|
|
50
48
|
prefix: Prefix to be used for the inferred model
|
|
51
49
|
"""
|
|
52
50
|
|
|
53
|
-
def __init__(
|
|
54
|
-
self,
|
|
55
|
-
issue_list: IssueList,
|
|
56
|
-
graph: Graph,
|
|
57
|
-
max_number_of_instance: int = -1,
|
|
58
|
-
prefix: str = "inferred",
|
|
59
|
-
) -> None:
|
|
60
|
-
self.issue_list = issue_list
|
|
61
|
-
self.graph = graph
|
|
62
|
-
self.max_number_of_instance = max_number_of_instance
|
|
63
|
-
self.prefix = prefix
|
|
64
|
-
|
|
65
51
|
@classmethod
|
|
66
52
|
def from_graph_store(
|
|
67
53
|
cls,
|
|
68
54
|
store: NeatGraphStore,
|
|
69
|
-
max_number_of_instance: int = -1,
|
|
70
55
|
prefix: str = "inferred",
|
|
56
|
+
max_number_of_instance: int = -1,
|
|
57
|
+
non_existing_node_type: UnknownEntity | AnyURI = DEFAULT_NON_EXISTING_NODE_TYPE,
|
|
71
58
|
) -> "InferenceImporter":
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
return cls(
|
|
75
|
-
issue_list,
|
|
76
|
-
store.graph,
|
|
77
|
-
max_number_of_instance=max_number_of_instance,
|
|
78
|
-
prefix=prefix,
|
|
79
|
-
)
|
|
59
|
+
return super().from_graph_store(store, prefix, max_number_of_instance, non_existing_node_type)
|
|
80
60
|
|
|
81
61
|
@classmethod
|
|
82
|
-
def
|
|
62
|
+
def from_file(
|
|
83
63
|
cls,
|
|
84
64
|
filepath: Path,
|
|
85
|
-
max_number_of_instance: int = -1,
|
|
86
65
|
prefix: str = "inferred",
|
|
66
|
+
max_number_of_instance: int = -1,
|
|
67
|
+
non_existing_node_type: UnknownEntity | AnyURI = DEFAULT_NON_EXISTING_NODE_TYPE,
|
|
87
68
|
) -> "InferenceImporter":
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
graph = Graph()
|
|
91
|
-
try:
|
|
92
|
-
graph.parse(filepath)
|
|
93
|
-
except Exception as e:
|
|
94
|
-
issue_list.append(FileReadError(filepath, str(e)))
|
|
95
|
-
|
|
96
|
-
return cls(
|
|
97
|
-
issue_list,
|
|
98
|
-
graph,
|
|
99
|
-
max_number_of_instance=max_number_of_instance,
|
|
100
|
-
prefix=prefix,
|
|
101
|
-
)
|
|
69
|
+
return super().from_file(filepath, prefix, max_number_of_instance, non_existing_node_type)
|
|
102
70
|
|
|
103
71
|
@classmethod
|
|
104
72
|
def from_json_file(
|
|
105
73
|
cls,
|
|
106
74
|
filepath: Path,
|
|
107
|
-
max_number_of_instance: int = -1,
|
|
108
75
|
prefix: str = "inferred",
|
|
76
|
+
max_number_of_instance: int = -1,
|
|
109
77
|
) -> "InferenceImporter":
|
|
110
78
|
raise NotImplementedError("JSON file format is not supported yet.")
|
|
111
79
|
|
|
@@ -113,8 +81,8 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
|
|
|
113
81
|
def from_yaml_file(
|
|
114
82
|
cls,
|
|
115
83
|
filepath: Path,
|
|
116
|
-
max_number_of_instance: int = -1,
|
|
117
84
|
prefix: str = "inferred",
|
|
85
|
+
max_number_of_instance: int = -1,
|
|
118
86
|
) -> "InferenceImporter":
|
|
119
87
|
raise NotImplementedError("YAML file format is not supported yet.")
|
|
120
88
|
|
|
@@ -122,27 +90,11 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
|
|
|
122
90
|
def from_xml_file(
|
|
123
91
|
cls,
|
|
124
92
|
filepath: Path,
|
|
125
|
-
max_number_of_instance: int = -1,
|
|
126
93
|
prefix: str = "inferred",
|
|
94
|
+
max_number_of_instance: int = -1,
|
|
127
95
|
) -> "InferenceImporter":
|
|
128
96
|
raise NotImplementedError("JSON file format is not supported yet.")
|
|
129
97
|
|
|
130
|
-
def to_rules(
|
|
131
|
-
self,
|
|
132
|
-
) -> ReadRules[InformationInputRules]:
|
|
133
|
-
"""
|
|
134
|
-
Creates `Rules` object from the data for target role.
|
|
135
|
-
"""
|
|
136
|
-
|
|
137
|
-
if self.issue_list.has_errors:
|
|
138
|
-
# In case there were errors during the import, the to_rules method will return None
|
|
139
|
-
return ReadRules(None, self.issue_list, {})
|
|
140
|
-
|
|
141
|
-
rules_dict = self._to_rules_components()
|
|
142
|
-
|
|
143
|
-
rules = InformationInputRules.load(rules_dict)
|
|
144
|
-
return ReadRules(rules, self.issue_list, {})
|
|
145
|
-
|
|
146
98
|
def _to_rules_components(
|
|
147
99
|
self,
|
|
148
100
|
) -> dict:
|
|
@@ -157,16 +109,10 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
|
|
|
157
109
|
"""
|
|
158
110
|
classes: dict[str, dict] = {}
|
|
159
111
|
properties: dict[str, dict] = {}
|
|
160
|
-
prefixes: dict[str, Namespace] = get_default_prefixes()
|
|
161
112
|
count_by_value_type_by_property: dict[str, dict[str, int]] = defaultdict(Counter)
|
|
162
113
|
|
|
163
|
-
# Adds default namespace to prefixes
|
|
164
|
-
prefixes[self._default_metadata().prefix] = self._default_metadata().namespace
|
|
165
|
-
|
|
166
114
|
# Infers all the classes in the graph
|
|
167
115
|
for class_uri, no_instances in self.graph.query(ORDERED_CLASSES_QUERY): # type: ignore[misc]
|
|
168
|
-
self._add_uri_namespace_to_prefixes(cast(URIRef, class_uri), prefixes)
|
|
169
|
-
|
|
170
116
|
if (class_id := remove_namespace_from_uri(class_uri)) in classes:
|
|
171
117
|
# handles cases when class id is already present in classes
|
|
172
118
|
class_id = f"{class_id}_{len(classes)+1}"
|
|
@@ -195,27 +141,24 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
|
|
|
195
141
|
|
|
196
142
|
property_id = remove_namespace_from_uri(property_uri)
|
|
197
143
|
|
|
198
|
-
self._add_uri_namespace_to_prefixes(cast(URIRef, property_uri), prefixes)
|
|
199
|
-
|
|
200
144
|
if value_type_uri := (data_type_uri or object_type_uri):
|
|
201
|
-
self._add_uri_namespace_to_prefixes(cast(URIRef, value_type_uri), prefixes)
|
|
202
|
-
|
|
203
145
|
value_type_id = remove_namespace_from_uri(value_type_uri)
|
|
204
146
|
|
|
205
147
|
# this handles situations when property points to node that is not present in graph
|
|
206
148
|
else:
|
|
207
|
-
value_type_id = str(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
recommended_action="Make sure that graph is complete",
|
|
216
|
-
)
|
|
149
|
+
value_type_id = str(self.non_existing_node_type)
|
|
150
|
+
|
|
151
|
+
issue = PropertyValueTypeUndefinedWarning(
|
|
152
|
+
resource_type="Property",
|
|
153
|
+
identifier=f"{class_id}:{property_id}",
|
|
154
|
+
property_name=property_id,
|
|
155
|
+
default_action="Remove the property from the rules",
|
|
156
|
+
recommended_action="Make sure that graph is complete",
|
|
217
157
|
)
|
|
218
158
|
|
|
159
|
+
if issue not in self.issue_list:
|
|
160
|
+
self.issue_list.append(issue)
|
|
161
|
+
|
|
219
162
|
id_ = f"{class_id}:{property_id}"
|
|
220
163
|
|
|
221
164
|
definition = {
|
|
@@ -224,10 +167,6 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
|
|
|
224
167
|
"max_count": cast(RdfLiteral, occurrence).value,
|
|
225
168
|
"value_type": value_type_id,
|
|
226
169
|
"reference": property_uri,
|
|
227
|
-
"transformation": (
|
|
228
|
-
f"{uri_to_short_form(class_definition['reference'], prefixes)}"
|
|
229
|
-
f"({uri_to_short_form(cast(URIRef, property_uri), prefixes)})"
|
|
230
|
-
),
|
|
231
170
|
}
|
|
232
171
|
|
|
233
172
|
count_by_value_type_by_property[id_][value_type_id] += 1
|
|
@@ -279,20 +218,8 @@ class InferenceImporter(BaseImporter[InformationInputRules]):
|
|
|
279
218
|
"metadata": self._default_metadata().model_dump(),
|
|
280
219
|
"classes": list(classes.values()),
|
|
281
220
|
"properties": list(properties.values()),
|
|
282
|
-
"prefixes": prefixes,
|
|
283
221
|
}
|
|
284
222
|
|
|
285
|
-
@classmethod
|
|
286
|
-
def _add_uri_namespace_to_prefixes(cls, URI: URIRef, prefixes: dict[str, Namespace]):
|
|
287
|
-
"""Add URI to prefixes dict if not already present
|
|
288
|
-
|
|
289
|
-
Args:
|
|
290
|
-
URI: URI from which namespace is being extracted
|
|
291
|
-
prefixes: Dict of prefixes and namespaces
|
|
292
|
-
"""
|
|
293
|
-
if Namespace(get_namespace(URI)) not in prefixes.values():
|
|
294
|
-
prefixes[f"prefix-{len(prefixes)+1}"] = Namespace(get_namespace(URI))
|
|
295
|
-
|
|
296
223
|
def _default_metadata(self):
|
|
297
224
|
return InformationMetadata(
|
|
298
225
|
name="Inferred Model",
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from rdflib import Graph, Namespace
|
|
2
2
|
|
|
3
|
-
from cognite.neat.
|
|
4
|
-
from cognite.neat.
|
|
5
|
-
from cognite.neat.
|
|
6
|
-
from cognite.neat.
|
|
7
|
-
from cognite.neat.
|
|
3
|
+
from cognite.neat._constants import DEFAULT_NAMESPACE
|
|
4
|
+
from cognite.neat._rules.importers._rdf._shared import make_metadata_compliant
|
|
5
|
+
from cognite.neat._rules.models import RoleTypes, SchemaCompleteness
|
|
6
|
+
from cognite.neat._utils.collection_ import remove_none_elements_from_set
|
|
7
|
+
from cognite.neat._utils.rdf_ import convert_rdflib_content
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def parse_owl_metadata(graph: Graph) -> dict:
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""This module performs importing of various formats to one of serializations for which
|
|
2
|
+
there are loaders to TransformationRules pydantic class."""
|
|
3
|
+
|
|
4
|
+
from cognite.neat._rules.importers._rdf._base import BaseRDFImporter
|
|
5
|
+
from cognite.neat._rules.importers._rdf._shared import make_components_compliant
|
|
6
|
+
|
|
7
|
+
from ._owl2classes import parse_owl_classes
|
|
8
|
+
from ._owl2metadata import parse_owl_metadata
|
|
9
|
+
from ._owl2properties import parse_owl_properties
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class OWLImporter(BaseRDFImporter):
|
|
13
|
+
"""Convert OWL ontology to tables/ transformation rules / Excel file.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
filepath: Path to OWL ontology
|
|
17
|
+
|
|
18
|
+
!!! Note
|
|
19
|
+
OWL Ontologies are information models which completeness varies. As such, constructing functional
|
|
20
|
+
data model directly will often be impossible, therefore the produced Rules object will be ill formed.
|
|
21
|
+
To avoid this, neat will automatically attempt to make the imported rules compliant by adding default
|
|
22
|
+
values for missing information, attaching dangling properties to default containers based on the
|
|
23
|
+
property type, etc.
|
|
24
|
+
|
|
25
|
+
One has to be aware that NEAT will be opinionated about how to make the ontology
|
|
26
|
+
compliant, and that the resulting rules may not be what you expect.
|
|
27
|
+
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def _to_rules_components(
|
|
31
|
+
self,
|
|
32
|
+
) -> dict:
|
|
33
|
+
components = {
|
|
34
|
+
"Metadata": parse_owl_metadata(self.graph),
|
|
35
|
+
"Classes": parse_owl_classes(self.graph),
|
|
36
|
+
"Properties": parse_owl_properties(self.graph),
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return make_components_compliant(components)
|
|
@@ -4,10 +4,10 @@ import numpy as np
|
|
|
4
4
|
import pandas as pd
|
|
5
5
|
from rdflib import OWL, Literal, Namespace
|
|
6
6
|
|
|
7
|
-
from cognite.neat.
|
|
8
|
-
from cognite.neat.
|
|
9
|
-
from cognite.neat.
|
|
10
|
-
from cognite.neat.
|
|
7
|
+
from cognite.neat._rules._constants import PATTERNS
|
|
8
|
+
from cognite.neat._rules.models._base_rules import MatchType
|
|
9
|
+
from cognite.neat._rules.models.data_types import _XSD_TYPES
|
|
10
|
+
from cognite.neat._utils.rdf_ import remove_namespace_from_uri
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def parse_raw_classes_dataframe(query_results: list[tuple]) -> pd.DataFrame:
|
|
@@ -13,23 +13,23 @@ from cognite.client.utils._importing import local_import
|
|
|
13
13
|
from pandas import ExcelFile
|
|
14
14
|
from rdflib import Namespace
|
|
15
15
|
|
|
16
|
-
from cognite.neat.
|
|
17
|
-
from cognite.neat.
|
|
16
|
+
from cognite.neat._issues import IssueList
|
|
17
|
+
from cognite.neat._issues.errors import (
|
|
18
18
|
FileMissingRequiredFieldError,
|
|
19
19
|
FileNotFoundNeatError,
|
|
20
20
|
FileReadError,
|
|
21
21
|
PropertyDefinitionDuplicatedError,
|
|
22
22
|
)
|
|
23
|
-
from cognite.neat.
|
|
24
|
-
from cognite.neat.
|
|
25
|
-
from cognite.neat.
|
|
23
|
+
from cognite.neat._issues.warnings import FileMissingRequiredFieldWarning
|
|
24
|
+
from cognite.neat._rules._shared import ReadRules, T_InputRules
|
|
25
|
+
from cognite.neat._rules.models import (
|
|
26
26
|
INPUT_RULES_BY_ROLE,
|
|
27
27
|
VERIFIED_RULES_BY_ROLE,
|
|
28
28
|
RoleTypes,
|
|
29
29
|
SchemaCompleteness,
|
|
30
30
|
)
|
|
31
|
-
from cognite.neat.
|
|
32
|
-
from cognite.neat.
|
|
31
|
+
from cognite.neat._utils.spreadsheet import SpreadsheetRead, read_individual_sheet
|
|
32
|
+
from cognite.neat._utils.text import humanize_collection
|
|
33
33
|
|
|
34
34
|
from ._base import BaseImporter
|
|
35
35
|
|
|
@@ -3,16 +3,16 @@ from typing import Any, cast
|
|
|
3
3
|
|
|
4
4
|
import yaml
|
|
5
5
|
|
|
6
|
-
from cognite.neat.
|
|
7
|
-
from cognite.neat.
|
|
6
|
+
from cognite.neat._issues import IssueList, NeatIssue
|
|
7
|
+
from cognite.neat._issues.errors import (
|
|
8
8
|
FileMissingRequiredFieldError,
|
|
9
9
|
FileNotAFileError,
|
|
10
10
|
FileNotFoundNeatError,
|
|
11
11
|
FileTypeUnexpectedError,
|
|
12
12
|
)
|
|
13
|
-
from cognite.neat.
|
|
14
|
-
from cognite.neat.
|
|
15
|
-
from cognite.neat.
|
|
13
|
+
from cognite.neat._issues.warnings import NeatValueWarning
|
|
14
|
+
from cognite.neat._rules._shared import ReadRules, T_InputRules
|
|
15
|
+
from cognite.neat._rules.models import INPUT_RULES_BY_ROLE, RoleTypes
|
|
16
16
|
|
|
17
17
|
from ._base import BaseImporter
|
|
18
18
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
from cognite.neat.
|
|
2
|
-
from cognite.neat.
|
|
3
|
-
from cognite.neat.
|
|
4
|
-
from cognite.neat.
|
|
5
|
-
from cognite.neat.
|
|
1
|
+
from cognite.neat._rules.models.asset._rules import AssetRules
|
|
2
|
+
from cognite.neat._rules.models.asset._rules_input import AssetInputRules
|
|
3
|
+
from cognite.neat._rules.models.domain import DomainInputRules, DomainRules
|
|
4
|
+
from cognite.neat._rules.models.information._rules import InformationRules
|
|
5
|
+
from cognite.neat._rules.models.information._rules_input import InformationInputRules
|
|
6
6
|
|
|
7
7
|
from ._base_rules import DataModelType, ExtensionCategory, RoleTypes, SchemaCompleteness, SheetList, SheetRow
|
|
8
8
|
from .dms._rules import DMSRules
|
|
@@ -18,6 +18,8 @@ from dataclasses import Field, dataclass, fields, is_dataclass
|
|
|
18
18
|
from types import GenericAlias, UnionType
|
|
19
19
|
from typing import Any, Generic, TypeVar, Union, cast, get_args, get_origin, overload
|
|
20
20
|
|
|
21
|
+
import pandas as pd
|
|
22
|
+
|
|
21
23
|
from ._base_rules import BaseRules, SchemaModel
|
|
22
24
|
|
|
23
25
|
if sys.version_info >= (3, 11):
|
|
@@ -40,14 +42,14 @@ class InputRules(Generic[T_BaseRules], ABC):
|
|
|
40
42
|
|
|
41
43
|
@classmethod
|
|
42
44
|
@overload
|
|
43
|
-
def load(cls, data: dict[str, Any]) ->
|
|
45
|
+
def load(cls: "type[T_InputRules]", data: dict[str, Any]) -> "T_InputRules": ...
|
|
44
46
|
|
|
45
47
|
@classmethod
|
|
46
48
|
@overload
|
|
47
|
-
def load(cls, data: None) -> None: ...
|
|
49
|
+
def load(cls: "type[T_InputRules]", data: None) -> None: ...
|
|
48
50
|
|
|
49
51
|
@classmethod
|
|
50
|
-
def load(cls, data: dict | None) ->
|
|
52
|
+
def load(cls: "type[T_InputRules]", data: dict | None) -> "T_InputRules | None":
|
|
51
53
|
if data is None:
|
|
52
54
|
return None
|
|
53
55
|
return cls._load(data)
|
|
@@ -62,14 +64,15 @@ class InputRules(Generic[T_BaseRules], ABC):
|
|
|
62
64
|
if isinstance(type_, str) and type_.startswith(cls.__name__):
|
|
63
65
|
type_ = cls
|
|
64
66
|
|
|
67
|
+
candidate: type
|
|
65
68
|
if is_dataclass(type_):
|
|
66
|
-
candidate = type_
|
|
69
|
+
candidate = type_ # type: ignore[assignment]
|
|
67
70
|
elif isinstance(type_, GenericAlias) and type_.__origin__ is list and is_dataclass(type_.__args__[0]):
|
|
68
|
-
candidate = type_.__args__[0]
|
|
71
|
+
candidate = type_.__args__[0] # type: ignore[assignment]
|
|
69
72
|
|
|
70
73
|
# this handles prefixes
|
|
71
74
|
elif isinstance(type_, GenericAlias) and type_.__origin__ is dict:
|
|
72
|
-
candidate = type_
|
|
75
|
+
candidate = type_ # type: ignore[assignment]
|
|
73
76
|
else:
|
|
74
77
|
continue
|
|
75
78
|
|
|
@@ -124,6 +127,9 @@ class InputRules(Generic[T_BaseRules], ABC):
|
|
|
124
127
|
return output
|
|
125
128
|
|
|
126
129
|
|
|
130
|
+
T_InputRules = TypeVar("T_InputRules", bound=InputRules)
|
|
131
|
+
|
|
132
|
+
|
|
127
133
|
@dataclass
|
|
128
134
|
class InputComponent(ABC, Generic[T_RuleModel]):
|
|
129
135
|
@classmethod
|
|
@@ -170,3 +176,6 @@ class InputComponent(ABC, Generic[T_RuleModel]):
|
|
|
170
176
|
for name, field_ in self._get_verified_cls().model_fields.items()
|
|
171
177
|
if not field_.exclude
|
|
172
178
|
}
|
|
179
|
+
|
|
180
|
+
def _repr_html_(self) -> str:
|
|
181
|
+
return pd.DataFrame([self.dump()])._repr_html_() # type: ignore[operator]
|
|
@@ -24,6 +24,8 @@ from pydantic import (
|
|
|
24
24
|
from pydantic.main import IncEx
|
|
25
25
|
from pydantic_core import core_schema
|
|
26
26
|
|
|
27
|
+
from cognite.neat._rules.models._types import ClassEntityType, InformationPropertyType
|
|
28
|
+
|
|
27
29
|
if sys.version_info >= (3, 11):
|
|
28
30
|
from enum import StrEnum
|
|
29
31
|
from typing import Self
|
|
@@ -208,7 +210,7 @@ class BaseRules(SchemaModel, ABC):
|
|
|
208
210
|
as_reference: bool = False,
|
|
209
211
|
mode: Literal["python", "json"] = "python",
|
|
210
212
|
by_alias: bool = False,
|
|
211
|
-
exclude: IncEx = None,
|
|
213
|
+
exclude: IncEx | None = None,
|
|
212
214
|
exclude_none: bool = False,
|
|
213
215
|
exclude_unset: bool = False,
|
|
214
216
|
exclude_defaults: bool = False,
|
|
@@ -244,7 +246,7 @@ class BaseRules(SchemaModel, ABC):
|
|
|
244
246
|
if entities_exclude_defaults:
|
|
245
247
|
context["metadata"] = self.metadata
|
|
246
248
|
|
|
247
|
-
exclude_input: IncEx
|
|
249
|
+
exclude_input: IncEx | None
|
|
248
250
|
if self.reference is None:
|
|
249
251
|
exclude_input = exclude
|
|
250
252
|
else:
|
|
@@ -348,3 +350,13 @@ ExtensionCategoryType = Annotated[
|
|
|
348
350
|
),
|
|
349
351
|
BeforeValidator(lambda v: ExtensionCategory(v) if isinstance(v, str) else v),
|
|
350
352
|
]
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
# Immutable such that this can be used as a key in a dictionary
|
|
356
|
+
class PropertyRef(BaseModel, frozen=True):
|
|
357
|
+
class_: ClassEntityType = Field(alias="Class")
|
|
358
|
+
property_: InformationPropertyType = Field(alias="Property")
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
class ClassRef(BaseModel, frozen=True):
|
|
362
|
+
class_: ClassEntityType = Field(alias="Class")
|
|
@@ -8,7 +8,7 @@ from typing import ClassVar, Literal
|
|
|
8
8
|
|
|
9
9
|
from pydantic import BaseModel, field_validator, model_serializer
|
|
10
10
|
|
|
11
|
-
from cognite.neat.
|
|
11
|
+
from cognite.neat._issues.errors import NeatValueError
|
|
12
12
|
|
|
13
13
|
if sys.version_info >= (3, 11):
|
|
14
14
|
from enum import StrEnum
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
from collections.abc import Callable
|
|
3
|
+
from typing import Annotated, Any, TypeAlias, TypeVar
|
|
4
|
+
|
|
5
|
+
import rdflib
|
|
6
|
+
from pydantic import (
|
|
7
|
+
AfterValidator,
|
|
8
|
+
BeforeValidator,
|
|
9
|
+
HttpUrl,
|
|
10
|
+
StringConstraints,
|
|
11
|
+
TypeAdapter,
|
|
12
|
+
ValidationInfo,
|
|
13
|
+
WrapValidator,
|
|
14
|
+
)
|
|
15
|
+
from pydantic.functional_serializers import PlainSerializer
|
|
16
|
+
|
|
17
|
+
from cognite.neat._issues.errors import RegexViolationError
|
|
18
|
+
from cognite.neat._issues.warnings import RegexViolationWarning
|
|
19
|
+
from cognite.neat._rules._constants import (
|
|
20
|
+
DATA_MODEL_COMPLIANCE_REGEX,
|
|
21
|
+
PATTERNS,
|
|
22
|
+
PREFIX_COMPLIANCE_REGEX,
|
|
23
|
+
VERSION_COMPLIANCE_REGEX,
|
|
24
|
+
EntityTypes,
|
|
25
|
+
)
|
|
26
|
+
from cognite.neat._rules.models.entities._multi_value import MultiValueTypeInfo
|
|
27
|
+
from cognite.neat._rules.models.entities._single_value import (
|
|
28
|
+
ClassEntity,
|
|
29
|
+
ContainerEntity,
|
|
30
|
+
ViewEntity,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
Entities: TypeAlias = ClassEntity | ViewEntity | ContainerEntity
|
|
34
|
+
T_Entities = TypeVar("T_Entities", bound=Entities)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _custom_error(exc_factory: Callable[[str | None, Exception], Any]) -> Any:
|
|
38
|
+
def _validator(value: Any, next_: Any, ctx: ValidationInfo) -> Any:
|
|
39
|
+
try:
|
|
40
|
+
return next_(value, ctx)
|
|
41
|
+
except Exception:
|
|
42
|
+
raise exc_factory(ctx.field_name, value) from None
|
|
43
|
+
|
|
44
|
+
return WrapValidator(_validator)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
StrOrListType = Annotated[
|
|
48
|
+
str | list[str],
|
|
49
|
+
BeforeValidator(lambda value: value.replace(", ", ",").split(",") if isinstance(value, str) and value else value),
|
|
50
|
+
PlainSerializer(
|
|
51
|
+
lambda value: ",".join([entry for entry in value if entry]) if isinstance(value, list) else value,
|
|
52
|
+
return_type=str,
|
|
53
|
+
when_used="unless-none",
|
|
54
|
+
),
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
StrListType = Annotated[
|
|
58
|
+
list[str],
|
|
59
|
+
BeforeValidator(lambda value: [entry.strip() for entry in value.split(",")] if isinstance(value, str) else value),
|
|
60
|
+
PlainSerializer(
|
|
61
|
+
lambda value: ",".join([entry for entry in value if entry]), return_type=str, when_used="unless-none"
|
|
62
|
+
),
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
NamespaceType = Annotated[
|
|
66
|
+
rdflib.Namespace,
|
|
67
|
+
BeforeValidator(
|
|
68
|
+
lambda value: (
|
|
69
|
+
rdflib.Namespace(TypeAdapter(HttpUrl).validate_python(value))
|
|
70
|
+
if value.endswith("#") or value.endswith("/")
|
|
71
|
+
else rdflib.Namespace(TypeAdapter(HttpUrl).validate_python(f"{value}/"))
|
|
72
|
+
)
|
|
73
|
+
),
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
PrefixType = Annotated[
|
|
77
|
+
str,
|
|
78
|
+
StringConstraints(pattern=PREFIX_COMPLIANCE_REGEX),
|
|
79
|
+
_custom_error(lambda _, value: RegexViolationError(value, PREFIX_COMPLIANCE_REGEX)),
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
DataModelExternalIdType = Annotated[
|
|
83
|
+
str,
|
|
84
|
+
StringConstraints(pattern=DATA_MODEL_COMPLIANCE_REGEX),
|
|
85
|
+
_custom_error(lambda _, value: RegexViolationError(value, DATA_MODEL_COMPLIANCE_REGEX)),
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
VersionType = Annotated[
|
|
90
|
+
str,
|
|
91
|
+
BeforeValidator(str),
|
|
92
|
+
StringConstraints(pattern=VERSION_COMPLIANCE_REGEX),
|
|
93
|
+
_custom_error(lambda _, value: RegexViolationError(value, VERSION_COMPLIANCE_REGEX)),
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _external_id_validation_factory(entity_type: EntityTypes):
|
|
98
|
+
def _external_id_validation(value: str) -> str:
|
|
99
|
+
compiled_regex = PATTERNS.entity_pattern(entity_type)
|
|
100
|
+
if not compiled_regex.match(value):
|
|
101
|
+
raise RegexViolationError(value, compiled_regex.pattern)
|
|
102
|
+
if PATTERNS.more_than_one_alphanumeric.search(value):
|
|
103
|
+
warnings.warn(
|
|
104
|
+
RegexViolationWarning(
|
|
105
|
+
value,
|
|
106
|
+
compiled_regex.pattern,
|
|
107
|
+
"property",
|
|
108
|
+
"MoreThanOneNonAlphanumeric",
|
|
109
|
+
),
|
|
110
|
+
stacklevel=2,
|
|
111
|
+
)
|
|
112
|
+
return value
|
|
113
|
+
|
|
114
|
+
return _external_id_validation
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
SpaceType = Annotated[
|
|
118
|
+
str,
|
|
119
|
+
AfterValidator(_external_id_validation_factory(EntityTypes.space)),
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
InformationPropertyType = Annotated[
|
|
123
|
+
str,
|
|
124
|
+
AfterValidator(_external_id_validation_factory(EntityTypes.information_property)),
|
|
125
|
+
]
|
|
126
|
+
DmsPropertyType = Annotated[
|
|
127
|
+
str,
|
|
128
|
+
AfterValidator(_external_id_validation_factory(EntityTypes.dms_property)),
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _entity_validation(value: Entities) -> Entities:
|
|
133
|
+
suffix_regex = PATTERNS.entity_pattern(value.type_)
|
|
134
|
+
if not suffix_regex.match(value.suffix):
|
|
135
|
+
raise RegexViolationError(str(value), suffix_regex.pattern)
|
|
136
|
+
return value
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
ClassEntityType = Annotated[ClassEntity, AfterValidator(_entity_validation)]
|
|
140
|
+
ViewEntityType = Annotated[ViewEntity, AfterValidator(_entity_validation)]
|
|
141
|
+
ContainerEntityType = Annotated[ContainerEntity, AfterValidator(_entity_validation)]
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _multi_value_type_validation(value: MultiValueTypeInfo) -> MultiValueTypeInfo:
|
|
145
|
+
for type_ in value.types:
|
|
146
|
+
if isinstance(type_, ClassEntity):
|
|
147
|
+
_entity_validation(type_)
|
|
148
|
+
return value
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
MultiValueTypeType = Annotated[MultiValueTypeInfo, AfterValidator(_multi_value_type_validation)]
|