cognite-neat 0.123.24__py3-none-any.whl → 1.0.22__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.
- cognite/neat/__init__.py +4 -3
- cognite/neat/_client/__init__.py +5 -0
- cognite/neat/_client/api.py +8 -0
- cognite/neat/_client/client.py +21 -0
- cognite/neat/_client/config.py +40 -0
- cognite/neat/_client/containers_api.py +138 -0
- cognite/neat/_client/data_classes.py +44 -0
- cognite/neat/_client/data_model_api.py +115 -0
- cognite/neat/_client/init/credentials.py +70 -0
- cognite/neat/_client/init/env_vars.py +131 -0
- cognite/neat/_client/init/main.py +51 -0
- cognite/neat/_client/spaces_api.py +115 -0
- cognite/neat/_client/statistics_api.py +24 -0
- cognite/neat/_client/views_api.py +144 -0
- cognite/neat/_config.py +266 -0
- cognite/neat/_data_model/_analysis.py +571 -0
- cognite/neat/_data_model/_constants.py +74 -0
- cognite/neat/_data_model/_identifiers.py +61 -0
- cognite/neat/_data_model/_shared.py +41 -0
- cognite/neat/_data_model/_snapshot.py +134 -0
- cognite/neat/_data_model/deployer/_differ.py +140 -0
- cognite/neat/_data_model/deployer/_differ_container.py +360 -0
- cognite/neat/_data_model/deployer/_differ_data_model.py +54 -0
- cognite/neat/_data_model/deployer/_differ_space.py +9 -0
- cognite/neat/_data_model/deployer/_differ_view.py +299 -0
- cognite/neat/_data_model/deployer/data_classes.py +644 -0
- cognite/neat/_data_model/deployer/deployer.py +431 -0
- cognite/neat/_data_model/exporters/__init__.py +15 -0
- cognite/neat/_data_model/exporters/_api_exporter.py +37 -0
- cognite/neat/_data_model/exporters/_base.py +24 -0
- cognite/neat/_data_model/exporters/_table_exporter/exporter.py +128 -0
- cognite/neat/_data_model/exporters/_table_exporter/workbook.py +409 -0
- cognite/neat/_data_model/exporters/_table_exporter/writer.py +480 -0
- cognite/neat/_data_model/importers/__init__.py +5 -0
- cognite/neat/_data_model/importers/_api_importer.py +166 -0
- cognite/neat/_data_model/importers/_base.py +16 -0
- cognite/neat/_data_model/importers/_table_importer/data_classes.py +344 -0
- cognite/neat/_data_model/importers/_table_importer/importer.py +192 -0
- cognite/neat/_data_model/importers/_table_importer/reader.py +1102 -0
- cognite/neat/_data_model/importers/_table_importer/source.py +94 -0
- cognite/neat/_data_model/models/conceptual/_base.py +18 -0
- cognite/neat/_data_model/models/conceptual/_concept.py +67 -0
- cognite/neat/_data_model/models/conceptual/_data_model.py +51 -0
- cognite/neat/_data_model/models/conceptual/_properties.py +104 -0
- cognite/neat/_data_model/models/conceptual/_property.py +105 -0
- cognite/neat/_data_model/models/dms/__init__.py +206 -0
- cognite/neat/_data_model/models/dms/_base.py +31 -0
- cognite/neat/_data_model/models/dms/_constants.py +48 -0
- cognite/neat/_data_model/models/dms/_constraints.py +42 -0
- cognite/neat/_data_model/models/dms/_container.py +159 -0
- cognite/neat/_data_model/models/dms/_data_model.py +95 -0
- cognite/neat/_data_model/models/dms/_data_types.py +195 -0
- cognite/neat/_data_model/models/dms/_http.py +28 -0
- cognite/neat/_data_model/models/dms/_indexes.py +30 -0
- cognite/neat/_data_model/models/dms/_limits.py +96 -0
- cognite/neat/_data_model/models/dms/_references.py +141 -0
- cognite/neat/_data_model/models/dms/_schema.py +18 -0
- cognite/neat/_data_model/models/dms/_space.py +48 -0
- cognite/neat/_data_model/models/dms/_types.py +17 -0
- cognite/neat/_data_model/models/dms/_view_filter.py +310 -0
- cognite/neat/_data_model/models/dms/_view_property.py +235 -0
- cognite/neat/_data_model/models/dms/_views.py +216 -0
- cognite/neat/_data_model/models/entities/__init__.py +50 -0
- cognite/neat/_data_model/models/entities/_base.py +101 -0
- cognite/neat/_data_model/models/entities/_constants.py +22 -0
- cognite/neat/_data_model/models/entities/_data_types.py +144 -0
- cognite/neat/_data_model/models/entities/_identifiers.py +61 -0
- cognite/neat/_data_model/models/entities/_parser.py +226 -0
- cognite/neat/_data_model/validation/dms/__init__.py +75 -0
- cognite/neat/_data_model/validation/dms/_ai_readiness.py +381 -0
- cognite/neat/_data_model/validation/dms/_base.py +25 -0
- cognite/neat/_data_model/validation/dms/_connections.py +681 -0
- cognite/neat/_data_model/validation/dms/_consistency.py +58 -0
- cognite/neat/_data_model/validation/dms/_containers.py +199 -0
- cognite/neat/_data_model/validation/dms/_limits.py +368 -0
- cognite/neat/_data_model/validation/dms/_orchestrator.py +70 -0
- cognite/neat/_data_model/validation/dms/_views.py +164 -0
- cognite/neat/_exceptions.py +68 -0
- cognite/neat/_issues.py +68 -0
- cognite/neat/_session/__init__.py +3 -0
- cognite/neat/_session/_html/_render.py +30 -0
- cognite/neat/_session/_html/static/__init__.py +8 -0
- cognite/neat/_session/_html/static/deployment.css +476 -0
- cognite/neat/_session/_html/static/deployment.js +181 -0
- cognite/neat/_session/_html/static/issues.css +211 -0
- cognite/neat/_session/_html/static/issues.js +168 -0
- cognite/neat/_session/_html/static/shared.css +186 -0
- cognite/neat/_session/_html/templates/__init__.py +4 -0
- cognite/neat/_session/_html/templates/deployment.html +80 -0
- cognite/neat/_session/_html/templates/issues.html +45 -0
- cognite/neat/_session/_issues.py +81 -0
- cognite/neat/_session/_physical.py +294 -0
- cognite/neat/_session/_result/__init__.py +3 -0
- cognite/neat/_session/_result/_deployment/__init__.py +0 -0
- cognite/neat/_session/_result/_deployment/_physical/__init__.py +0 -0
- cognite/neat/_session/_result/_deployment/_physical/_changes.py +196 -0
- cognite/neat/_session/_result/_deployment/_physical/_statistics.py +180 -0
- cognite/neat/_session/_result/_deployment/_physical/serializer.py +35 -0
- cognite/neat/_session/_result/_result.py +31 -0
- cognite/neat/_session/_session.py +81 -0
- cognite/neat/_session/_usage_analytics/__init__.py +0 -0
- cognite/neat/_session/_usage_analytics/_collector.py +131 -0
- cognite/neat/_session/_usage_analytics/_constants.py +23 -0
- cognite/neat/_session/_usage_analytics/_storage.py +240 -0
- cognite/neat/_session/_wrappers.py +101 -0
- cognite/neat/_state_machine/__init__.py +10 -0
- cognite/neat/_state_machine/_base.py +37 -0
- cognite/neat/_state_machine/_states.py +52 -0
- cognite/neat/_store/__init__.py +3 -0
- cognite/neat/_store/_provenance.py +88 -0
- cognite/neat/_store/_store.py +220 -0
- cognite/neat/_utils/__init__.py +0 -0
- cognite/neat/_utils/_reader.py +194 -0
- cognite/neat/_utils/auxiliary.py +49 -0
- cognite/neat/_utils/collection.py +11 -0
- cognite/neat/_utils/http_client/__init__.py +39 -0
- cognite/neat/_utils/http_client/_client.py +245 -0
- cognite/neat/_utils/http_client/_config.py +19 -0
- cognite/neat/_utils/http_client/_data_classes.py +294 -0
- cognite/neat/_utils/http_client/_tracker.py +31 -0
- cognite/neat/_utils/repo.py +19 -0
- cognite/neat/_utils/text.py +71 -0
- cognite/neat/_utils/useful_types.py +37 -0
- cognite/neat/_utils/validation.py +154 -0
- cognite/neat/_v0/__init__.py +0 -0
- cognite/neat/_v0/core/__init__.py +0 -0
- cognite/neat/_v0/core/_client/_api/__init__.py +0 -0
- cognite/neat/{core → _v0/core}/_client/_api/data_modeling_loaders.py +8 -7
- cognite/neat/{core → _v0/core}/_client/_api/neat_instances.py +5 -5
- cognite/neat/{core → _v0/core}/_client/_api/schema.py +5 -5
- cognite/neat/{core → _v0/core}/_client/_api/statistics.py +3 -3
- cognite/neat/{core → _v0/core}/_client/_api_client.py +1 -1
- cognite/neat/_v0/core/_client/data_classes/__init__.py +0 -0
- cognite/neat/{core → _v0/core}/_client/data_classes/schema.py +4 -4
- cognite/neat/{core → _v0/core}/_client/testing.py +1 -1
- cognite/neat/{core → _v0/core}/_constants.py +5 -3
- cognite/neat/_v0/core/_data_model/__init__.py +0 -0
- cognite/neat/{core → _v0/core}/_data_model/_constants.py +7 -0
- cognite/neat/{core → _v0/core}/_data_model/_shared.py +4 -4
- cognite/neat/{core → _v0/core}/_data_model/analysis/_base.py +8 -8
- cognite/neat/{core → _v0/core}/_data_model/exporters/__init__.py +1 -2
- cognite/neat/{core → _v0/core}/_data_model/exporters/_base.py +7 -7
- cognite/neat/{core → _v0/core}/_data_model/exporters/_data_model2dms.py +9 -9
- cognite/neat/{core → _v0/core}/_data_model/exporters/_data_model2excel.py +12 -12
- cognite/neat/{core → _v0/core}/_data_model/exporters/_data_model2instance_template.py +4 -4
- cognite/neat/{core/_data_model/exporters/_data_model2ontology.py → _v0/core/_data_model/exporters/_data_model2semantic_model.py} +126 -116
- cognite/neat/{core → _v0/core}/_data_model/exporters/_data_model2yaml.py +1 -1
- cognite/neat/{core → _v0/core}/_data_model/importers/_base.py +5 -5
- cognite/neat/{core → _v0/core}/_data_model/importers/_base_file_reader.py +2 -2
- cognite/neat/{core → _v0/core}/_data_model/importers/_dict2data_model.py +5 -5
- cognite/neat/{core → _v0/core}/_data_model/importers/_dms2data_model.py +18 -15
- cognite/neat/{core → _v0/core}/_data_model/importers/_graph2data_model.py +12 -12
- cognite/neat/{core → _v0/core}/_data_model/importers/_rdf/_base.py +12 -12
- cognite/neat/{core → _v0/core}/_data_model/importers/_rdf/_inference2rdata_model.py +14 -14
- cognite/neat/_v0/core/_data_model/importers/_rdf/_owl2data_model.py +144 -0
- cognite/neat/{core → _v0/core}/_data_model/importers/_rdf/_shared.py +17 -13
- cognite/neat/{core → _v0/core}/_data_model/importers/_spreadsheet2data_model.py +92 -12
- cognite/neat/{core → _v0/core}/_data_model/models/__init__.py +3 -3
- cognite/neat/{core → _v0/core}/_data_model/models/_base_verified.py +5 -5
- cognite/neat/{core → _v0/core}/_data_model/models/_import_contexts.py +1 -1
- cognite/neat/{core → _v0/core}/_data_model/models/_types.py +5 -5
- cognite/neat/{core → _v0/core}/_data_model/models/conceptual/_unverified.py +16 -10
- cognite/neat/{core → _v0/core}/_data_model/models/conceptual/_validation.py +12 -12
- cognite/neat/{core → _v0/core}/_data_model/models/conceptual/_verified.py +9 -9
- cognite/neat/{core → _v0/core}/_data_model/models/data_types.py +14 -4
- cognite/neat/{core → _v0/core}/_data_model/models/entities/__init__.py +6 -0
- cognite/neat/_v0/core/_data_model/models/entities/_loaders.py +155 -0
- cognite/neat/{core → _v0/core}/_data_model/models/entities/_multi_value.py +2 -2
- cognite/neat/_v0/core/_data_model/models/entities/_restrictions.py +230 -0
- cognite/neat/{core → _v0/core}/_data_model/models/entities/_single_value.py +121 -16
- cognite/neat/{core → _v0/core}/_data_model/models/entities/_types.py +10 -0
- cognite/neat/{core → _v0/core}/_data_model/models/mapping/_classic2core.py +5 -5
- cognite/neat/{core → _v0/core}/_data_model/models/physical/__init__.py +1 -1
- cognite/neat/{core → _v0/core}/_data_model/models/physical/_exporter.py +26 -19
- cognite/neat/{core → _v0/core}/_data_model/models/physical/_unverified.py +133 -37
- cognite/neat/{core → _v0/core}/_data_model/models/physical/_validation.py +24 -20
- cognite/neat/{core → _v0/core}/_data_model/models/physical/_verified.py +95 -24
- cognite/neat/{core → _v0/core}/_data_model/transformers/_base.py +4 -4
- cognite/neat/{core → _v0/core}/_data_model/transformers/_converters.py +35 -28
- cognite/neat/{core → _v0/core}/_data_model/transformers/_mapping.py +7 -7
- cognite/neat/{core → _v0/core}/_data_model/transformers/_union_conceptual.py +5 -5
- cognite/neat/{core → _v0/core}/_data_model/transformers/_verification.py +7 -7
- cognite/neat/_v0/core/_instances/__init__.py +0 -0
- cognite/neat/{core → _v0/core}/_instances/_tracking/base.py +1 -1
- cognite/neat/{core → _v0/core}/_instances/_tracking/log.py +1 -1
- cognite/neat/{core → _v0/core}/_instances/extractors/__init__.py +3 -2
- cognite/neat/{core → _v0/core}/_instances/extractors/_base.py +6 -6
- cognite/neat/_v0/core/_instances/extractors/_classic_cdf/__init__.py +0 -0
- cognite/neat/{core → _v0/core}/_instances/extractors/_classic_cdf/_base.py +7 -7
- cognite/neat/{core → _v0/core}/_instances/extractors/_classic_cdf/_classic.py +12 -12
- cognite/neat/{core → _v0/core}/_instances/extractors/_classic_cdf/_relationships.py +3 -3
- cognite/neat/{core → _v0/core}/_instances/extractors/_classic_cdf/_sequences.py +2 -2
- cognite/neat/{core → _v0/core}/_instances/extractors/_dict.py +6 -3
- cognite/neat/{core → _v0/core}/_instances/extractors/_dms.py +6 -6
- cognite/neat/{core → _v0/core}/_instances/extractors/_dms_graph.py +11 -11
- cognite/neat/{core → _v0/core}/_instances/extractors/_mock_graph_generator.py +10 -10
- cognite/neat/{core → _v0/core}/_instances/extractors/_raw.py +3 -3
- cognite/neat/{core → _v0/core}/_instances/extractors/_rdf_file.py +7 -7
- cognite/neat/{core → _v0/core}/_instances/loaders/_base.py +5 -5
- cognite/neat/{core → _v0/core}/_instances/loaders/_rdf2dms.py +17 -17
- cognite/neat/{core → _v0/core}/_instances/loaders/_rdf_to_instance_space.py +11 -11
- cognite/neat/{core → _v0/core}/_instances/queries/_select.py +29 -3
- cognite/neat/{core → _v0/core}/_instances/queries/_update.py +1 -1
- cognite/neat/{core → _v0/core}/_instances/transformers/_base.py +4 -4
- cognite/neat/{core → _v0/core}/_instances/transformers/_classic_cdf.py +6 -6
- cognite/neat/{core → _v0/core}/_instances/transformers/_prune_graph.py +4 -4
- cognite/neat/{core → _v0/core}/_instances/transformers/_rdfpath.py +1 -1
- cognite/neat/{core → _v0/core}/_instances/transformers/_value_type.py +4 -4
- cognite/neat/{core → _v0/core}/_issues/_base.py +5 -5
- cognite/neat/{core → _v0/core}/_issues/_contextmanagers.py +1 -1
- cognite/neat/{core → _v0/core}/_issues/_factory.py +3 -3
- cognite/neat/{core → _v0/core}/_issues/errors/__init__.py +1 -1
- cognite/neat/{core → _v0/core}/_issues/errors/_external.py +1 -1
- cognite/neat/{core → _v0/core}/_issues/errors/_general.py +1 -1
- cognite/neat/{core → _v0/core}/_issues/errors/_properties.py +1 -1
- cognite/neat/{core → _v0/core}/_issues/errors/_resources.py +2 -2
- cognite/neat/{core → _v0/core}/_issues/errors/_wrapper.py +7 -3
- cognite/neat/{core → _v0/core}/_issues/warnings/__init__.py +1 -1
- cognite/neat/{core → _v0/core}/_issues/warnings/_external.py +1 -1
- cognite/neat/{core → _v0/core}/_issues/warnings/_general.py +1 -1
- cognite/neat/{core → _v0/core}/_issues/warnings/_models.py +2 -2
- cognite/neat/{core → _v0/core}/_issues/warnings/_properties.py +2 -2
- cognite/neat/{core → _v0/core}/_issues/warnings/_resources.py +1 -1
- cognite/neat/{core → _v0/core}/_issues/warnings/user_modeling.py +1 -1
- cognite/neat/{core → _v0/core}/_store/_data_model.py +12 -12
- cognite/neat/{core → _v0/core}/_store/_instance.py +43 -10
- cognite/neat/{core → _v0/core}/_store/_provenance.py +3 -3
- cognite/neat/{core → _v0/core}/_store/exceptions.py +4 -4
- cognite/neat/_v0/core/_utils/__init__.py +0 -0
- cognite/neat/{core → _v0/core}/_utils/auth.py +22 -12
- cognite/neat/{core → _v0/core}/_utils/auxiliary.py +1 -1
- cognite/neat/{core → _v0/core}/_utils/collection_.py +2 -2
- cognite/neat/{core → _v0/core}/_utils/graph_transformations_report.py +1 -1
- cognite/neat/{core → _v0/core}/_utils/rdf_.py +1 -1
- cognite/neat/{core → _v0/core}/_utils/reader/_base.py +1 -1
- cognite/neat/{core → _v0/core}/_utils/spreadsheet.py +18 -4
- cognite/neat/{core → _v0/core}/_utils/text.py +1 -1
- cognite/neat/{core → _v0/core}/_utils/upload.py +3 -3
- cognite/neat/{session → _v0}/engine/_load.py +1 -1
- cognite/neat/_v0/plugins/__init__.py +4 -0
- cognite/neat/_v0/plugins/_base.py +9 -0
- cognite/neat/_v0/plugins/_data_model.py +48 -0
- cognite/neat/{plugins → _v0/plugins}/_issues.py +1 -1
- cognite/neat/{plugins → _v0/plugins}/_manager.py +7 -16
- cognite/neat/{session → _v0/session}/_base.py +13 -15
- cognite/neat/{session → _v0/session}/_collector.py +1 -1
- cognite/neat/_v0/session/_diff.py +51 -0
- cognite/neat/{session → _v0/session}/_drop.py +3 -3
- cognite/neat/{session → _v0/session}/_explore.py +2 -2
- cognite/neat/{session → _v0/session}/_fix.py +2 -2
- cognite/neat/{session → _v0/session}/_inspect.py +3 -3
- cognite/neat/{session → _v0/session}/_mapping.py +3 -3
- cognite/neat/{session → _v0/session}/_plugin.py +4 -5
- cognite/neat/{session → _v0/session}/_prepare.py +8 -8
- cognite/neat/{session → _v0/session}/_read.py +34 -21
- cognite/neat/{session → _v0/session}/_set.py +8 -8
- cognite/neat/{session → _v0/session}/_show.py +5 -5
- cognite/neat/{session → _v0/session}/_state.py +10 -10
- cognite/neat/{session → _v0/session}/_subset.py +4 -4
- cognite/neat/{session → _v0/session}/_template.py +11 -11
- cognite/neat/{session → _v0/session}/_to.py +12 -12
- cognite/neat/{session → _v0/session}/_wizard.py +1 -1
- cognite/neat/{session → _v0/session}/exceptions.py +5 -5
- cognite/neat/_version.py +1 -1
- cognite/neat/legacy.py +6 -0
- cognite_neat-1.0.22.dist-info/METADATA +123 -0
- cognite_neat-1.0.22.dist-info/RECORD +329 -0
- cognite_neat-1.0.22.dist-info/WHEEL +4 -0
- cognite/neat/core/_data_model/importers/_rdf/_owl2data_model.py +0 -91
- cognite/neat/core/_data_model/models/entities/_loaders.py +0 -75
- cognite/neat/plugins/__init__.py +0 -3
- cognite/neat/plugins/data_model/importers/__init__.py +0 -5
- cognite/neat/plugins/data_model/importers/_base.py +0 -28
- cognite/neat/session/_session/_data_model/__init__.py +0 -3
- cognite/neat/session/_session/_data_model/_read.py +0 -193
- cognite/neat/session/_session/_data_model/_routes.py +0 -45
- cognite/neat/session/_session/_data_model/_show.py +0 -147
- cognite/neat/session/_session/_data_model/_write.py +0 -335
- cognite_neat-0.123.24.dist-info/METADATA +0 -144
- cognite_neat-0.123.24.dist-info/RECORD +0 -201
- cognite_neat-0.123.24.dist-info/WHEEL +0 -4
- cognite_neat-0.123.24.dist-info/licenses/LICENSE +0 -201
- /cognite/neat/{core → _client/init}/__init__.py +0 -0
- /cognite/neat/{core/_client/_api → _data_model}/__init__.py +0 -0
- /cognite/neat/{core/_client/data_classes → _data_model/deployer}/__init__.py +0 -0
- /cognite/neat/{core/_data_model → _data_model/exporters/_table_exporter}/__init__.py +0 -0
- /cognite/neat/{core/_instances → _data_model/importers/_table_importer}/__init__.py +0 -0
- /cognite/neat/{core/_instances/extractors/_classic_cdf → _data_model/models}/__init__.py +0 -0
- /cognite/neat/{core/_utils → _data_model/models/conceptual}/__init__.py +0 -0
- /cognite/neat/{plugins/data_model → _data_model/validation}/__init__.py +0 -0
- /cognite/neat/{session/_session → _session/_html}/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_client/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_client/data_classes/data_modeling.py +0 -0
- /cognite/neat/{core → _v0/core}/_client/data_classes/neat_sequence.py +0 -0
- /cognite/neat/{core → _v0/core}/_client/data_classes/statistics.py +0 -0
- /cognite/neat/{core → _v0/core}/_config.py +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/analysis/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/catalog/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/catalog/classic_model.xlsx +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/catalog/conceptual-imf-data-model.xlsx +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/catalog/hello_world_pump.xlsx +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/importers/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/importers/_rdf/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/models/_base_unverified.py +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/models/conceptual/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/models/entities/_constants.py +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/models/entities/_wrapped.py +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/models/mapping/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/models/mapping/_classic2core.yaml +0 -0
- /cognite/neat/{core → _v0/core}/_data_model/transformers/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/_shared.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/_tracking/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
- /cognite/neat/{core → _v0/core}/_instances/examples/Knowledge-Graph-Nordic44.xml +0 -0
- /cognite/neat/{core → _v0/core}/_instances/examples/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
- /cognite/neat/{core → _v0/core}/_instances/extractors/_classic_cdf/_assets.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/extractors/_classic_cdf/_data_sets.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/extractors/_classic_cdf/_events.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/extractors/_classic_cdf/_files.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/extractors/_classic_cdf/_labels.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/extractors/_classic_cdf/_timeseries.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/loaders/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/queries/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/queries/_base.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/queries/_queries.py +0 -0
- /cognite/neat/{core → _v0/core}/_instances/transformers/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_issues/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_issues/formatters.py +0 -0
- /cognite/neat/{core → _v0/core}/_shared.py +0 -0
- /cognite/neat/{core → _v0/core}/_store/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_utils/io_.py +0 -0
- /cognite/neat/{core → _v0/core}/_utils/reader/__init__.py +0 -0
- /cognite/neat/{core → _v0/core}/_utils/tarjan.py +0 -0
- /cognite/neat/{core → _v0/core}/_utils/time_.py +0 -0
- /cognite/neat/{core → _v0/core}/_utils/xml_.py +0 -0
- /cognite/neat/{session → _v0}/engine/__init__.py +0 -0
- /cognite/neat/{session → _v0}/engine/_import.py +0 -0
- /cognite/neat/{session → _v0}/engine/_interface.py +0 -0
- /cognite/neat/{session → _v0/session}/__init__.py +0 -0
- /cognite/neat/{session → _v0/session}/_experimental.py +0 -0
- /cognite/neat/{session → _v0/session}/_state/README.md +0 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
from typing import Literal, overload
|
|
2
|
+
|
|
3
|
+
from cognite.neat._v0.core._data_model.models.data_types import DataType
|
|
4
|
+
from cognite.neat._v0.core._issues.errors import NeatTypeError
|
|
5
|
+
|
|
6
|
+
from ._multi_value import MultiValueTypeInfo
|
|
7
|
+
from ._single_value import (
|
|
8
|
+
ConceptEntity,
|
|
9
|
+
EdgeEntity,
|
|
10
|
+
PhysicalUnknownEntity,
|
|
11
|
+
ReverseConnectionEntity,
|
|
12
|
+
Unknown,
|
|
13
|
+
UnknownEntity,
|
|
14
|
+
ViewEntity,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@overload
|
|
19
|
+
def load_value_type(
|
|
20
|
+
raw: str | MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity,
|
|
21
|
+
default_prefix: str,
|
|
22
|
+
return_on_failure: Literal[False] = False,
|
|
23
|
+
) -> MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity: ...
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@overload
|
|
27
|
+
def load_value_type(
|
|
28
|
+
raw: str | MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity,
|
|
29
|
+
default_prefix: str,
|
|
30
|
+
return_on_failure: Literal[True],
|
|
31
|
+
) -> MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity | None | str: ...
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def load_value_type(
|
|
35
|
+
raw: str | MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity,
|
|
36
|
+
default_prefix: str,
|
|
37
|
+
return_on_failure: Literal[True, False] = False,
|
|
38
|
+
) -> MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity | None | str:
|
|
39
|
+
"""
|
|
40
|
+
Loads a value type from a raw string or entity.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
raw: The raw value to load.
|
|
44
|
+
default_prefix: The default prefix to use if not specified in the raw value.
|
|
45
|
+
return_on_failure: If True, returns the raw value on parsing failure instead of raising an error.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
The loaded value type entity, or the raw value if loading fails and `return_on_failure` is True.
|
|
49
|
+
"""
|
|
50
|
+
if isinstance(raw, MultiValueTypeInfo | DataType | ConceptEntity | UnknownEntity):
|
|
51
|
+
return raw
|
|
52
|
+
elif isinstance(raw, str):
|
|
53
|
+
# property holding xsd data type
|
|
54
|
+
# check if it is multi value type
|
|
55
|
+
if "," in raw:
|
|
56
|
+
value_type = MultiValueTypeInfo.load(raw)
|
|
57
|
+
value_type.set_default_prefix(default_prefix)
|
|
58
|
+
return value_type
|
|
59
|
+
elif DataType.is_data_type(raw):
|
|
60
|
+
return DataType.load(raw)
|
|
61
|
+
|
|
62
|
+
# unknown value type
|
|
63
|
+
elif raw == str(Unknown):
|
|
64
|
+
return UnknownEntity()
|
|
65
|
+
|
|
66
|
+
# property holding link to class
|
|
67
|
+
else:
|
|
68
|
+
return ConceptEntity.load(raw, prefix=default_prefix, return_on_failure=return_on_failure)
|
|
69
|
+
else:
|
|
70
|
+
raise NeatTypeError(f"Invalid value type: {type(raw)}")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@overload
|
|
74
|
+
def load_dms_value_type(
|
|
75
|
+
raw: str | DataType | ViewEntity | PhysicalUnknownEntity,
|
|
76
|
+
default_space: str,
|
|
77
|
+
default_version: str,
|
|
78
|
+
return_on_failure: Literal[False],
|
|
79
|
+
) -> DataType | ViewEntity | PhysicalUnknownEntity: ...
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@overload
|
|
83
|
+
def load_dms_value_type(
|
|
84
|
+
raw: str | DataType | ViewEntity | PhysicalUnknownEntity,
|
|
85
|
+
default_space: str,
|
|
86
|
+
default_version: str,
|
|
87
|
+
return_on_failure: Literal[True],
|
|
88
|
+
) -> DataType | ViewEntity | PhysicalUnknownEntity | str: ...
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def load_dms_value_type(
|
|
92
|
+
raw: str | DataType | ViewEntity | PhysicalUnknownEntity,
|
|
93
|
+
default_space: str,
|
|
94
|
+
default_version: str,
|
|
95
|
+
return_on_failure: Literal[True, False] = False,
|
|
96
|
+
) -> DataType | ViewEntity | PhysicalUnknownEntity | str:
|
|
97
|
+
"""
|
|
98
|
+
Loads a value type from a raw string or entity in the context of a data modeling service
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
raw: The raw value to load.
|
|
102
|
+
default_space: The default space to use if not specified in the raw value.
|
|
103
|
+
default_version: The default version to use if not specified in the raw value.
|
|
104
|
+
return_on_failure: If True, returns the raw value on parsing failure instead of raising an error.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
The loaded value type entity, or the raw value if loading fails and `return_on_failure` is True.
|
|
108
|
+
"""
|
|
109
|
+
if isinstance(raw, DataType | ViewEntity | PhysicalUnknownEntity):
|
|
110
|
+
return raw
|
|
111
|
+
elif isinstance(raw, str):
|
|
112
|
+
if DataType.is_data_type(raw):
|
|
113
|
+
return DataType.load(raw)
|
|
114
|
+
elif raw == str(Unknown):
|
|
115
|
+
return PhysicalUnknownEntity()
|
|
116
|
+
else:
|
|
117
|
+
return ViewEntity.load(
|
|
118
|
+
raw, space=default_space, version=default_version, return_on_failure=return_on_failure
|
|
119
|
+
)
|
|
120
|
+
raise NeatTypeError(f"Invalid value type: {type(raw)}")
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@overload
|
|
124
|
+
def load_connection(
|
|
125
|
+
raw: Literal["direct"] | ReverseConnectionEntity | EdgeEntity | str | None,
|
|
126
|
+
default_space: str,
|
|
127
|
+
default_version: str,
|
|
128
|
+
return_on_failure: Literal[False] = False,
|
|
129
|
+
) -> Literal["direct"] | ReverseConnectionEntity | EdgeEntity | None: ...
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@overload
|
|
133
|
+
def load_connection(
|
|
134
|
+
raw: Literal["direct"] | ReverseConnectionEntity | EdgeEntity | str | None,
|
|
135
|
+
default_space: str,
|
|
136
|
+
default_version: str,
|
|
137
|
+
return_on_failure: Literal[True],
|
|
138
|
+
) -> Literal["direct"] | ReverseConnectionEntity | EdgeEntity | None | str: ...
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def load_connection(
|
|
142
|
+
raw: Literal["direct"] | ReverseConnectionEntity | EdgeEntity | str | None,
|
|
143
|
+
default_space: str,
|
|
144
|
+
default_version: str,
|
|
145
|
+
return_on_failure: Literal[True, False] = False,
|
|
146
|
+
) -> Literal["direct"] | ReverseConnectionEntity | EdgeEntity | None | str:
|
|
147
|
+
if isinstance(raw, str) and raw.lower() == "direct":
|
|
148
|
+
return "direct" # type: ignore[return-value]
|
|
149
|
+
elif isinstance(raw, EdgeEntity | ReverseConnectionEntity) or raw is None:
|
|
150
|
+
return raw # type: ignore[return-value]
|
|
151
|
+
elif isinstance(raw, str) and raw.startswith("edge"):
|
|
152
|
+
return EdgeEntity.load(raw, space=default_space, version=default_version, return_on_failure=return_on_failure) # type: ignore[return-value]
|
|
153
|
+
elif isinstance(raw, str) and raw.startswith("reverse"):
|
|
154
|
+
return ReverseConnectionEntity.load(raw, return_on_failure=return_on_failure) # type: ignore[return-value]
|
|
155
|
+
raise NeatTypeError(f"Invalid connection: {type(raw)}")
|
|
@@ -6,8 +6,8 @@ from pydantic import (
|
|
|
6
6
|
model_validator,
|
|
7
7
|
)
|
|
8
8
|
|
|
9
|
-
from cognite.neat.core._data_model._constants import EntityTypes
|
|
10
|
-
from cognite.neat.core._data_model.models.data_types import DataType
|
|
9
|
+
from cognite.neat._v0.core._data_model._constants import EntityTypes
|
|
10
|
+
from cognite.neat._v0.core._data_model.models.data_types import DataType
|
|
11
11
|
|
|
12
12
|
from ._constants import _PARSE, Undefined
|
|
13
13
|
from ._single_value import ConceptEntity, UnknownEntity
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import sys
|
|
3
|
+
from abc import ABC
|
|
4
|
+
from typing import Any, ClassVar, Final, Literal, TypeVar, cast, get_args
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
|
7
|
+
from rdflib import Literal as RDFLiteral
|
|
8
|
+
from rdflib import URIRef
|
|
9
|
+
|
|
10
|
+
from cognite.neat._v0.core._data_model._constants import EntityTypes
|
|
11
|
+
from cognite.neat._v0.core._data_model.models.data_types import _XSD_TYPES, DataType
|
|
12
|
+
from cognite.neat._v0.core._data_model.models.entities._constants import _PARSE
|
|
13
|
+
from cognite.neat._v0.core._data_model.models.entities._single_value import ConceptEntity, ConceptualEntity
|
|
14
|
+
from cognite.neat._v0.core._issues.errors._general import NeatValueError
|
|
15
|
+
from cognite.neat._v0.core._utils.rdf_ import remove_namespace_from_uri
|
|
16
|
+
|
|
17
|
+
if sys.version_info <= (3, 11):
|
|
18
|
+
from typing_extensions import Self
|
|
19
|
+
else:
|
|
20
|
+
from typing import Self
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
ValueConstraints = Literal["allValuesFrom", "someValuesFrom", "hasValue"]
|
|
24
|
+
CardinalityConstraints = Literal["minCardinality", "maxCardinality", "cardinality", "qualifiedCardinality"]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# Constants for regex patterns - more maintainable
|
|
28
|
+
PROPERTY_PATTERN: Final[str] = r"[a-zA-Z0-9._~?@!$&'*+,;=%-]+"
|
|
29
|
+
VALUE_PATTERN: Final[str] = r".+"
|
|
30
|
+
CARDINALITY_VALUE_PATTERN: Final[str] = r"\d+"
|
|
31
|
+
ON_PATTERN: Final[str] = r"[^(]*"
|
|
32
|
+
|
|
33
|
+
VALUE_CONSTRAINT_REGEX = re.compile(
|
|
34
|
+
rf"^{EntityTypes.value_constraint}:(?P<property>{PROPERTY_PATTERN})\((?P<constraint>{'|'.join(get_args(ValueConstraints))}),(?P<value>{VALUE_PATTERN})\)$"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
CARDINALITY_CONSTRAINT_REGEX = re.compile(
|
|
38
|
+
rf"^{EntityTypes.cardinality_constraint}:(?P<property>{PROPERTY_PATTERN})\((?P<constraint>{'|'.join(get_args(CardinalityConstraints))}),(?P<value>{CARDINALITY_VALUE_PATTERN})(?:,(?P<on>{ON_PATTERN}))?\)$"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class NamedIndividualEntity(ConceptualEntity):
|
|
43
|
+
type_: ClassVar[EntityTypes] = EntityTypes.named_individual
|
|
44
|
+
|
|
45
|
+
@model_validator(mode="after")
|
|
46
|
+
def reset_prefix(self) -> Self:
|
|
47
|
+
self.prefix = "ni"
|
|
48
|
+
return self
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ConceptPropertyRestriction(ABC, BaseModel):
|
|
52
|
+
model_config: ClassVar[ConfigDict] = ConfigDict(
|
|
53
|
+
str_strip_whitespace=True,
|
|
54
|
+
arbitrary_types_allowed=True,
|
|
55
|
+
strict=False,
|
|
56
|
+
extra="ignore",
|
|
57
|
+
)
|
|
58
|
+
type_: ClassVar[EntityTypes] = EntityTypes.concept_restriction
|
|
59
|
+
property_: str
|
|
60
|
+
|
|
61
|
+
@classmethod
|
|
62
|
+
def load(cls: "type[T_ConceptPropertyRestriction]", data: Any, **defaults: Any) -> "T_ConceptPropertyRestriction":
|
|
63
|
+
if isinstance(data, cls):
|
|
64
|
+
return data
|
|
65
|
+
elif not isinstance(data, str):
|
|
66
|
+
raise ValueError(f"Cannot load {cls.__name__} from {data}")
|
|
67
|
+
|
|
68
|
+
return cls.model_validate({_PARSE: data, "defaults": defaults})
|
|
69
|
+
|
|
70
|
+
@model_validator(mode="before")
|
|
71
|
+
def _load(cls, data: Any) -> dict:
|
|
72
|
+
defaults = {}
|
|
73
|
+
if isinstance(data, dict) and _PARSE in data:
|
|
74
|
+
defaults = data.get("defaults", {})
|
|
75
|
+
data = data[_PARSE]
|
|
76
|
+
if isinstance(data, dict):
|
|
77
|
+
data.update(defaults)
|
|
78
|
+
return data
|
|
79
|
+
|
|
80
|
+
if not isinstance(data, str):
|
|
81
|
+
raise ValueError(f"Cannot load {cls.__name__} from {data}")
|
|
82
|
+
|
|
83
|
+
return cls._parse(data, defaults)
|
|
84
|
+
|
|
85
|
+
@classmethod
|
|
86
|
+
def _parse(cls, data: str, defaults: dict) -> dict:
|
|
87
|
+
raise NotImplementedError(f"{cls.__name__} must implement _parse method")
|
|
88
|
+
|
|
89
|
+
def dump(self) -> str:
|
|
90
|
+
return self.__str__()
|
|
91
|
+
|
|
92
|
+
def as_tuple(self) -> tuple[str, ...]:
|
|
93
|
+
# We haver overwritten the serialization to str, so we need to do it manually
|
|
94
|
+
extra: tuple[str, ...] = tuple(
|
|
95
|
+
[
|
|
96
|
+
str(v or "")
|
|
97
|
+
for field_name in self.model_fields.keys()
|
|
98
|
+
if (v := getattr(self, field_name)) and field_name not in {"property_"}
|
|
99
|
+
]
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
return self.property_, *extra
|
|
103
|
+
|
|
104
|
+
def __lt__(self, other: object) -> bool:
|
|
105
|
+
if not isinstance(other, ConceptPropertyRestriction):
|
|
106
|
+
return NotImplemented
|
|
107
|
+
return self.as_tuple() < other.as_tuple()
|
|
108
|
+
|
|
109
|
+
def __eq__(self, other: object) -> bool:
|
|
110
|
+
if not isinstance(other, ConceptPropertyRestriction):
|
|
111
|
+
return NotImplemented
|
|
112
|
+
return self.as_tuple() == other.as_tuple()
|
|
113
|
+
|
|
114
|
+
def __hash__(self) -> int:
|
|
115
|
+
return hash(str(self))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
T_ConceptPropertyRestriction = TypeVar("T_ConceptPropertyRestriction", bound="ConceptPropertyRestriction")
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class ConceptPropertyValueConstraint(ConceptPropertyRestriction):
|
|
122
|
+
type_: ClassVar[EntityTypes] = EntityTypes.value_constraint
|
|
123
|
+
constraint: ValueConstraints
|
|
124
|
+
value: RDFLiteral | ConceptEntity | NamedIndividualEntity
|
|
125
|
+
|
|
126
|
+
@field_validator("value")
|
|
127
|
+
def validate_value(cls, value: Any) -> Any:
|
|
128
|
+
if isinstance(value, RDFLiteral) and value.datatype is None:
|
|
129
|
+
raise NeatValueError("RDFLiteral must have a datatype set, which must be one of the XSD types.")
|
|
130
|
+
return value
|
|
131
|
+
|
|
132
|
+
def __str__(self) -> str:
|
|
133
|
+
value_str = (
|
|
134
|
+
f"{self.value.value}^^{remove_namespace_from_uri(cast(URIRef, self.value.datatype))}"
|
|
135
|
+
if isinstance(self.value, RDFLiteral)
|
|
136
|
+
else str(self.value)
|
|
137
|
+
)
|
|
138
|
+
return f"{self.type_}:{self.property_}({self.constraint},{value_str})"
|
|
139
|
+
|
|
140
|
+
@classmethod
|
|
141
|
+
def _parse(cls, data: str, defaults: dict) -> dict:
|
|
142
|
+
if not (result := VALUE_CONSTRAINT_REGEX.match(data)):
|
|
143
|
+
raise NeatValueError(f"Invalid value constraint format: {data}")
|
|
144
|
+
|
|
145
|
+
property_ = result.group("property")
|
|
146
|
+
constraint = result.group("constraint")
|
|
147
|
+
raw_value = result.group("value")
|
|
148
|
+
|
|
149
|
+
value: NamedIndividualEntity | RDFLiteral | ConceptEntity
|
|
150
|
+
# scenario 1: NamedIndividual as value restriction
|
|
151
|
+
if raw_value.startswith("ni:"):
|
|
152
|
+
value = NamedIndividualEntity.load(raw_value)
|
|
153
|
+
# scenario 2: Datatype as value restriction
|
|
154
|
+
elif "^^" in raw_value:
|
|
155
|
+
if len(value_components := raw_value.split("^^")) == 2 and value_components[1] in _XSD_TYPES:
|
|
156
|
+
value = RDFLiteral(value_components[0], datatype=DataType.load(value_components[1]).as_xml_uri_ref())
|
|
157
|
+
else:
|
|
158
|
+
raise NeatValueError(f"Invalid value format for datatype: {raw_value}")
|
|
159
|
+
|
|
160
|
+
# scenario 3: ConceptEntity as value restriction
|
|
161
|
+
else:
|
|
162
|
+
value = ConceptEntity.load(raw_value, **defaults)
|
|
163
|
+
|
|
164
|
+
return dict(property_=property_, constraint=constraint, value=value)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class ConceptPropertyCardinalityConstraint(ConceptPropertyRestriction):
|
|
168
|
+
type_: ClassVar[EntityTypes] = EntityTypes.cardinality_constraint
|
|
169
|
+
constraint: CardinalityConstraints
|
|
170
|
+
value: int = Field(ge=0)
|
|
171
|
+
on: DataType | ConceptEntity | None = None
|
|
172
|
+
|
|
173
|
+
def __str__(self) -> str:
|
|
174
|
+
on_str = f",{self.on}" if self.on else ""
|
|
175
|
+
return f"{self.type_}:{self.property_}({self.constraint},{self.value}{on_str})"
|
|
176
|
+
|
|
177
|
+
@classmethod
|
|
178
|
+
def _parse(cls, data: str, defaults: dict) -> dict:
|
|
179
|
+
if not (result := CARDINALITY_CONSTRAINT_REGEX.match(data)):
|
|
180
|
+
raise NeatValueError(f"Invalid cardinality constraint format: {data}")
|
|
181
|
+
|
|
182
|
+
property_ = result.group("property")
|
|
183
|
+
constraint = result.group("constraint")
|
|
184
|
+
value = result.group("value")
|
|
185
|
+
on = result.group("on")
|
|
186
|
+
if on:
|
|
187
|
+
if on in _XSD_TYPES:
|
|
188
|
+
on = DataType.load(on)
|
|
189
|
+
else:
|
|
190
|
+
on = cast(ConceptEntity, ConceptEntity.load(on, **defaults))
|
|
191
|
+
|
|
192
|
+
return dict(property_=property_, constraint=constraint, value=value, on=on)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def parse_restriction(data: str, **defaults: Any) -> ConceptPropertyRestriction:
|
|
196
|
+
"""Parse a string to create either a value or cardinality restriction.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
data: String representation of the restriction
|
|
200
|
+
**defaults: Default values to use when parsing
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
Either a ConceptPropertyValueConstraint or ConceptPropertyCardinalityConstraint
|
|
204
|
+
|
|
205
|
+
Raises:
|
|
206
|
+
NeatValueError: If the string cannot be parsed as either restriction type
|
|
207
|
+
"""
|
|
208
|
+
# Check for value constraint pattern first (more specific)
|
|
209
|
+
if VALUE_CONSTRAINT_REGEX.match(data):
|
|
210
|
+
try:
|
|
211
|
+
return ConceptPropertyValueConstraint.load(data, **defaults)
|
|
212
|
+
except Exception as e:
|
|
213
|
+
raise NeatValueError(f"Failed to parse value constraint: {data}") from e
|
|
214
|
+
|
|
215
|
+
# Check for cardinality constraint pattern
|
|
216
|
+
if CARDINALITY_CONSTRAINT_REGEX.match(data):
|
|
217
|
+
try:
|
|
218
|
+
return ConceptPropertyCardinalityConstraint.load(data, **defaults)
|
|
219
|
+
except Exception as e:
|
|
220
|
+
raise NeatValueError(f"Failed to parse cardinality constraint: {data}") from e
|
|
221
|
+
|
|
222
|
+
# If neither pattern matches, provide a clear error
|
|
223
|
+
raise NeatValueError(
|
|
224
|
+
f"Invalid restriction format: {data}. "
|
|
225
|
+
f"Expected format: '{EntityTypes.value_constraint}:property(constraint,value)' "
|
|
226
|
+
f"or '{EntityTypes.cardinality_constraint}:property(constraint,value[,on])'"
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
T_ConceptRestriction = TypeVar("T_ConceptRestriction", bound=ConceptPropertyRestriction)
|
|
@@ -22,8 +22,8 @@ from pydantic import (
|
|
|
22
22
|
model_validator,
|
|
23
23
|
)
|
|
24
24
|
|
|
25
|
-
from cognite.neat.core._issues.errors import NeatValueError
|
|
26
|
-
from cognite.neat.core._utils.text import replace_non_alphanumeric_with_underscore
|
|
25
|
+
from cognite.neat._v0.core._issues.errors import NeatValueError
|
|
26
|
+
from cognite.neat._v0.core._utils.text import replace_non_alphanumeric_with_underscore
|
|
27
27
|
|
|
28
28
|
if sys.version_info >= (3, 11):
|
|
29
29
|
from enum import StrEnum
|
|
@@ -32,7 +32,7 @@ else:
|
|
|
32
32
|
from backports.strenum import StrEnum
|
|
33
33
|
from typing_extensions import Self
|
|
34
34
|
|
|
35
|
-
from cognite.neat.core._data_model._constants import (
|
|
35
|
+
from cognite.neat._v0.core._data_model._constants import (
|
|
36
36
|
ENTITY_PATTERN,
|
|
37
37
|
SPLIT_ON_COMMA_PATTERN,
|
|
38
38
|
SPLIT_ON_EDGE_ENTITY_ARGS_PATTERN,
|
|
@@ -59,7 +59,13 @@ class ConceptualEntity(BaseModel, extra="ignore"):
|
|
|
59
59
|
|
|
60
60
|
@classmethod
|
|
61
61
|
@overload
|
|
62
|
-
def load(
|
|
62
|
+
def load(
|
|
63
|
+
cls: "type[T_Entity]",
|
|
64
|
+
data: Any,
|
|
65
|
+
strict: Literal[True],
|
|
66
|
+
return_on_failure: Literal[False] = False,
|
|
67
|
+
**defaults: Any,
|
|
68
|
+
) -> "T_Entity": ...
|
|
63
69
|
|
|
64
70
|
@classmethod
|
|
65
71
|
@overload
|
|
@@ -67,25 +73,59 @@ class ConceptualEntity(BaseModel, extra="ignore"):
|
|
|
67
73
|
cls: "type[T_Entity]",
|
|
68
74
|
data: Any,
|
|
69
75
|
strict: Literal[False] = False,
|
|
76
|
+
return_on_failure: Literal[False] = False,
|
|
70
77
|
**defaults: Any,
|
|
71
78
|
) -> "T_Entity | UnknownEntity": ...
|
|
72
79
|
|
|
73
80
|
@classmethod
|
|
74
|
-
|
|
81
|
+
@overload
|
|
82
|
+
def load(
|
|
83
|
+
cls: "type[T_Entity]",
|
|
84
|
+
data: Any,
|
|
85
|
+
strict: Literal[False] = False,
|
|
86
|
+
return_on_failure: Literal[True] = True,
|
|
87
|
+
**defaults: Any,
|
|
88
|
+
) -> "T_Entity | Any": ...
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
@overload
|
|
92
|
+
def load(
|
|
93
|
+
cls: "type[T_Entity]",
|
|
94
|
+
data: Any,
|
|
95
|
+
strict: Literal[True] = True,
|
|
96
|
+
return_on_failure: Literal[True] = True,
|
|
97
|
+
**defaults: Any,
|
|
98
|
+
) -> "T_Entity | Any": ...
|
|
99
|
+
|
|
100
|
+
@classmethod
|
|
101
|
+
def load(
|
|
102
|
+
cls: "type[T_Entity]", data: Any, strict: bool = False, return_on_failure: bool = False, **defaults: Any
|
|
103
|
+
) -> "T_Entity | UnknownEntity | Any":
|
|
104
|
+
"""Loads an entity from a string or dict representation.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
data: The data to load the entity from. Can be a string or a dict.
|
|
108
|
+
strict: If True, will raise an error if the data is "unknown".
|
|
109
|
+
return_on_failure: If True, will return the input data if loading fails.
|
|
110
|
+
This is used when you want to defer error handling to a later stage.
|
|
111
|
+
defaults: Default values to use when loading the entity. These will be used if the corresponding
|
|
112
|
+
"""
|
|
75
113
|
if isinstance(data, cls):
|
|
76
114
|
return data
|
|
77
115
|
elif isinstance(data, str) and data == str(Unknown):
|
|
78
116
|
if strict:
|
|
79
117
|
raise NeatValueError(f"Failed to load entity {data!s}")
|
|
80
118
|
return UnknownEntity(prefix=Undefined, suffix=Unknown)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
119
|
+
try:
|
|
120
|
+
if defaults and isinstance(defaults, dict):
|
|
121
|
+
# This is a trick to pass in default values
|
|
84
122
|
return cls.model_validate({_PARSE: data, "defaults": defaults})
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
123
|
+
else:
|
|
124
|
+
return cls.model_validate(data)
|
|
125
|
+
except ValueError:
|
|
126
|
+
if return_on_failure:
|
|
127
|
+
return data
|
|
128
|
+
raise
|
|
89
129
|
|
|
90
130
|
@model_validator(mode="before")
|
|
91
131
|
def _load(cls, data: Any) -> "dict | ConceptualEntity":
|
|
@@ -342,7 +382,13 @@ class PhysicalEntity(ConceptualEntity, Generic[T_ID], ABC):
|
|
|
342
382
|
|
|
343
383
|
@classmethod # type: ignore[override]
|
|
344
384
|
@overload
|
|
345
|
-
def load(
|
|
385
|
+
def load(
|
|
386
|
+
cls: "type[T_DMSEntity]",
|
|
387
|
+
data: Any,
|
|
388
|
+
strict: Literal[True],
|
|
389
|
+
return_on_failure: Literal[False] = False,
|
|
390
|
+
**defaults: Any,
|
|
391
|
+
) -> "T_DMSEntity": ...
|
|
346
392
|
|
|
347
393
|
@classmethod
|
|
348
394
|
@overload
|
|
@@ -350,18 +396,56 @@ class PhysicalEntity(ConceptualEntity, Generic[T_ID], ABC):
|
|
|
350
396
|
cls: "type[T_DMSEntity]",
|
|
351
397
|
data: Any,
|
|
352
398
|
strict: Literal[False] = False,
|
|
399
|
+
return_on_failure: Literal[False] = False,
|
|
353
400
|
**defaults: Any,
|
|
354
401
|
) -> "T_DMSEntity | PhysicalUnknownEntity": ...
|
|
355
402
|
|
|
356
403
|
@classmethod
|
|
404
|
+
@overload
|
|
357
405
|
def load(
|
|
358
|
-
cls: "type[T_DMSEntity]",
|
|
359
|
-
|
|
406
|
+
cls: "type[T_DMSEntity]",
|
|
407
|
+
data: Any,
|
|
408
|
+
strict: Literal[False] = False,
|
|
409
|
+
return_on_failure: Literal[True] = True,
|
|
410
|
+
**defaults: Any,
|
|
411
|
+
) -> "T_DMSEntity | Any": ...
|
|
412
|
+
|
|
413
|
+
@classmethod
|
|
414
|
+
@overload
|
|
415
|
+
def load(
|
|
416
|
+
cls: "type[T_DMSEntity]",
|
|
417
|
+
data: Any,
|
|
418
|
+
strict: Literal[True] = True,
|
|
419
|
+
return_on_failure: Literal[True] = True,
|
|
420
|
+
**defaults: Any,
|
|
421
|
+
) -> "T_DMSEntity | Any": ...
|
|
422
|
+
|
|
423
|
+
@classmethod
|
|
424
|
+
def load(
|
|
425
|
+
cls: "type[T_DMSEntity]",
|
|
426
|
+
data: Any,
|
|
427
|
+
strict: Literal[True, False] = False,
|
|
428
|
+
return_on_failure: Literal[True, False] = False,
|
|
429
|
+
**defaults: Any,
|
|
430
|
+
) -> "T_DMSEntity | PhysicalUnknownEntity | Any":
|
|
431
|
+
"""Loads a DMS entity from a string or dict representation.
|
|
432
|
+
|
|
433
|
+
Args:
|
|
434
|
+
data: The data to load the entity from. Can be a string or a dict.
|
|
435
|
+
strict: If True, will raise an error if the data is "unknown".
|
|
436
|
+
return_on_failure: If True, will return the input data if loading fails.
|
|
437
|
+
This is used when you want to defer error handling to a later stage.
|
|
438
|
+
defaults: Default values to use when loading the entity. These will be used if the corresponding
|
|
439
|
+
fields are missing in the input data.
|
|
440
|
+
|
|
441
|
+
"""
|
|
360
442
|
if isinstance(data, str) and data == str(Unknown):
|
|
361
443
|
if strict:
|
|
362
444
|
raise NeatValueError(f"Failed to load entity {data!s}")
|
|
363
445
|
return PhysicalUnknownEntity.from_id(None)
|
|
364
|
-
|
|
446
|
+
if isinstance(data, UnknownEntity):
|
|
447
|
+
return PhysicalUnknownEntity.from_id(None)
|
|
448
|
+
return cast(T_DMSEntity, super().load(data, strict=False, return_on_failure=return_on_failure, **defaults))
|
|
365
449
|
|
|
366
450
|
@property
|
|
367
451
|
def space(self) -> str:
|
|
@@ -495,6 +579,13 @@ class EdgeEntity(PhysicalEntity[None]):
|
|
|
495
579
|
properties: ViewEntity | None = None
|
|
496
580
|
direction: Literal["outwards", "inwards"] = "outwards"
|
|
497
581
|
|
|
582
|
+
@field_validator("direction", mode="before")
|
|
583
|
+
@classmethod
|
|
584
|
+
def _normalize_direction(cls, value: Any) -> str:
|
|
585
|
+
if isinstance(value, str):
|
|
586
|
+
return value.lower()
|
|
587
|
+
return value
|
|
588
|
+
|
|
498
589
|
def dump(self, **defaults: Any) -> str:
|
|
499
590
|
# Add default direction
|
|
500
591
|
return super().dump(**defaults, direction="outwards")
|
|
@@ -569,3 +660,17 @@ class ContainerIndexEntity(PhysicalEntity[None]):
|
|
|
569
660
|
@classmethod
|
|
570
661
|
def from_id(cls, id: None) -> Self:
|
|
571
662
|
return cls(suffix="dummy")
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
class ContainerConstraintEntity(PhysicalEntity[None]):
|
|
666
|
+
type_: ClassVar[EntityTypes] = EntityTypes.container_constraint
|
|
667
|
+
prefix: _UndefinedType | Literal["uniqueness", "requires"] = Undefined # type: ignore[assignment]
|
|
668
|
+
suffix: str
|
|
669
|
+
require: ContainerEntity | None = None
|
|
670
|
+
|
|
671
|
+
def as_id(self) -> None:
|
|
672
|
+
return None
|
|
673
|
+
|
|
674
|
+
@classmethod
|
|
675
|
+
def from_id(cls, id: None) -> Self:
|
|
676
|
+
return cls(suffix="dummy")
|
|
@@ -9,6 +9,7 @@ from pydantic import (
|
|
|
9
9
|
from ._single_value import (
|
|
10
10
|
AssetEntity,
|
|
11
11
|
ConceptEntity,
|
|
12
|
+
ContainerConstraintEntity,
|
|
12
13
|
ContainerEntity,
|
|
13
14
|
ContainerIndexEntity,
|
|
14
15
|
RelationshipEntity,
|
|
@@ -76,6 +77,15 @@ ContainerIndexListType = Annotated[
|
|
|
76
77
|
when_used="unless-none",
|
|
77
78
|
),
|
|
78
79
|
]
|
|
80
|
+
ContainerConstraintListType = Annotated[
|
|
81
|
+
list[ContainerConstraintEntity],
|
|
82
|
+
BeforeValidator(_split_str),
|
|
83
|
+
PlainSerializer(
|
|
84
|
+
_join_str,
|
|
85
|
+
return_type=str,
|
|
86
|
+
when_used="unless-none",
|
|
87
|
+
),
|
|
88
|
+
]
|
|
79
89
|
|
|
80
90
|
ViewEntityList = Annotated[
|
|
81
91
|
list[ViewEntity],
|
|
@@ -3,12 +3,12 @@ from pathlib import Path
|
|
|
3
3
|
|
|
4
4
|
import yaml
|
|
5
5
|
|
|
6
|
-
from cognite.neat.core._data_model._shared import ImportedDataModel
|
|
7
|
-
from cognite.neat.core._data_model.models.physical import (
|
|
6
|
+
from cognite.neat._v0.core._data_model._shared import ImportedDataModel
|
|
7
|
+
from cognite.neat._v0.core._data_model.models.physical import (
|
|
8
8
|
PhysicalDataModel,
|
|
9
9
|
UnverifiedPhysicalDataModel,
|
|
10
10
|
)
|
|
11
|
-
from cognite.neat.core._issues.errors import NeatValueError
|
|
11
|
+
from cognite.neat._v0.core._issues.errors import NeatValueError
|
|
12
12
|
|
|
13
13
|
_CLASSIC_TO_CORE_MAPPING = Path(__file__).resolve().parent / "_classic2core.yaml"
|
|
14
14
|
|
|
@@ -19,8 +19,8 @@ def _read_source_file() -> str:
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def load_classic_to_core_mapping(org_name: str | None, source_space: str, source_version: str) -> PhysicalDataModel:
|
|
22
|
-
from cognite.neat.core._data_model.importers import DictImporter
|
|
23
|
-
from cognite.neat.core._data_model.transformers import VerifyPhysicalDataModel
|
|
22
|
+
from cognite.neat._v0.core._data_model.importers import DictImporter
|
|
23
|
+
from cognite.neat._v0.core._data_model.transformers import VerifyPhysicalDataModel
|
|
24
24
|
|
|
25
25
|
raw_str = _read_source_file()
|
|
26
26
|
if org_name is not None:
|