cognite-neat 0.123.26__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/{core → _v0/core}/_data_model/importers/_rdf/_owl2data_model.py +41 -21
- cognite/neat/{core → _v0/core}/_data_model/importers/_rdf/_shared.py +9 -9
- 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/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.26.dist-info/METADATA +0 -144
- cognite_neat-0.123.26.dist-info/RECORD +0 -201
- cognite_neat-0.123.26.dist-info/WHEEL +0 -4
- cognite_neat-0.123.26.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,235 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import Annotated, Any, Literal
|
|
3
|
+
|
|
4
|
+
from pydantic import Field, Json, TypeAdapter, field_serializer
|
|
5
|
+
from pydantic_core.core_schema import FieldSerializationInfo
|
|
6
|
+
|
|
7
|
+
from cognite.neat._utils.useful_types import BaseModelObject
|
|
8
|
+
|
|
9
|
+
from ._base import Resource, WriteableResource
|
|
10
|
+
from ._constants import CONTAINER_AND_VIEW_PROPERTIES_IDENTIFIER_PATTERN
|
|
11
|
+
from ._data_types import DataType
|
|
12
|
+
from ._references import ContainerDirectReference, ContainerReference, NodeReference, ViewDirectReference, ViewReference
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ViewPropertyDefinition(Resource, ABC):
|
|
16
|
+
connection_type: str
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ViewCoreProperty(ViewPropertyDefinition, ABC):
|
|
20
|
+
# Core properties do not have connection type in the API, but we add it here such that
|
|
21
|
+
# we can use it as a discriminator in unions. The exclude=True ensures that it is not
|
|
22
|
+
# sent to the API.
|
|
23
|
+
connection_type: Literal["primary_property"] = Field(default="primary_property", exclude=True)
|
|
24
|
+
name: str | None = Field(
|
|
25
|
+
default=None,
|
|
26
|
+
description="Readable property name.",
|
|
27
|
+
max_length=255,
|
|
28
|
+
)
|
|
29
|
+
description: str | None = Field(
|
|
30
|
+
default=None,
|
|
31
|
+
description="Description of the content and suggested use for this property..",
|
|
32
|
+
max_length=1024,
|
|
33
|
+
)
|
|
34
|
+
container: ContainerReference = Field(
|
|
35
|
+
description="Reference to the container where this property is defined.",
|
|
36
|
+
)
|
|
37
|
+
container_property_identifier: str = Field(
|
|
38
|
+
description="Identifier of the property in the container.",
|
|
39
|
+
min_length=1,
|
|
40
|
+
max_length=255,
|
|
41
|
+
pattern=CONTAINER_AND_VIEW_PROPERTIES_IDENTIFIER_PATTERN,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
@field_serializer("container", mode="plain")
|
|
45
|
+
@classmethod
|
|
46
|
+
def serialize_container(cls, container: ContainerReference, info: FieldSerializationInfo) -> dict[str, Any]:
|
|
47
|
+
output = container.model_dump(**vars(info))
|
|
48
|
+
output["type"] = "container"
|
|
49
|
+
return output
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ViewCorePropertyRequest(ViewCoreProperty):
|
|
53
|
+
source: ViewReference | None = Field(
|
|
54
|
+
default=None,
|
|
55
|
+
description="Indicates on what type a referenced direct relation is expected to be. "
|
|
56
|
+
"Only applicable for direct relation properties.",
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
@field_serializer("source", mode="plain")
|
|
60
|
+
@classmethod
|
|
61
|
+
def serialize_source(cls, source: ViewReference | None, info: FieldSerializationInfo) -> dict[str, Any] | None:
|
|
62
|
+
if source is None:
|
|
63
|
+
return None
|
|
64
|
+
output = source.model_dump(**vars(info))
|
|
65
|
+
output["type"] = "view"
|
|
66
|
+
return output
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class ConstraintOrIndexState(BaseModelObject):
|
|
70
|
+
nullability: Literal["current", "pending", "failed"] | None = Field(
|
|
71
|
+
None,
|
|
72
|
+
description="""For properties that have isNullable set to false, this field describes the validity of the
|
|
73
|
+
not-null constraint. It is not specified for nullable properties.
|
|
74
|
+
|
|
75
|
+
Possible values are:
|
|
76
|
+
|
|
77
|
+
"failed": The property contains null values, violating the constraint. This can occur if a property with
|
|
78
|
+
existing nulls was made non-nullable. New null values will still be rejected.
|
|
79
|
+
"current": The constraint is satisfied; all values in the property are not null.
|
|
80
|
+
"pending": The constraint validity has not yet been computed.
|
|
81
|
+
""",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class ViewCorePropertyResponse(ViewCoreProperty, WriteableResource[ViewCorePropertyRequest]):
|
|
86
|
+
immutable: bool | None = Field(
|
|
87
|
+
default=None,
|
|
88
|
+
description="Should updates to this property be rejected after the initial population?",
|
|
89
|
+
)
|
|
90
|
+
nullable: bool | None = Field(
|
|
91
|
+
default=None,
|
|
92
|
+
description="Does this property need to be set to a value, or not?",
|
|
93
|
+
)
|
|
94
|
+
auto_increment: bool | None = Field(
|
|
95
|
+
default=None,
|
|
96
|
+
description="Increment the property based on its highest current value (max value).",
|
|
97
|
+
)
|
|
98
|
+
default_value: str | int | bool | dict[str, Json] | None = Field(
|
|
99
|
+
default=None,
|
|
100
|
+
description="Default value to use when you do not specify a value for the property.",
|
|
101
|
+
)
|
|
102
|
+
constraint_state: ConstraintOrIndexState = Field(
|
|
103
|
+
description="Describes the validity of constraints defined on this property"
|
|
104
|
+
)
|
|
105
|
+
type: DataType = Field(description="The type of data you can store in this property.")
|
|
106
|
+
|
|
107
|
+
def as_request(self) -> ViewCorePropertyRequest:
|
|
108
|
+
return ViewCorePropertyRequest.model_validate(self.model_dump(by_alias=True))
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class ConnectionPropertyDefinition(ViewPropertyDefinition, ABC):
|
|
112
|
+
name: str | None = Field(
|
|
113
|
+
default=None,
|
|
114
|
+
description="Readable property name.",
|
|
115
|
+
max_length=255,
|
|
116
|
+
)
|
|
117
|
+
description: str | None = Field(
|
|
118
|
+
default=None,
|
|
119
|
+
description="Description of the content and suggested use for this property..",
|
|
120
|
+
max_length=1024,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class EdgeProperty(ConnectionPropertyDefinition, ABC):
|
|
125
|
+
source: ViewReference = Field(
|
|
126
|
+
description="The target node(s) of this connection can be read through the view specified in 'source'."
|
|
127
|
+
)
|
|
128
|
+
type: NodeReference = Field(
|
|
129
|
+
description="Reference to the node pointed to by the direct relation. The reference consists of a "
|
|
130
|
+
"space and an external-id."
|
|
131
|
+
)
|
|
132
|
+
edge_source: ViewReference | None = Field(
|
|
133
|
+
None, description="The edge(s) of this connection can be read through the view specified in 'edgeSource'."
|
|
134
|
+
)
|
|
135
|
+
direction: Literal["outwards", "inwards"] = Field(
|
|
136
|
+
"outwards", description="The direction of the edge(s) of this connection."
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
@field_serializer("source", "edge_source", mode="plain")
|
|
140
|
+
@classmethod
|
|
141
|
+
def serialize_source(cls, source: ViewReference | None, info: FieldSerializationInfo) -> dict[str, Any] | None:
|
|
142
|
+
if source is None:
|
|
143
|
+
return None
|
|
144
|
+
output = source.model_dump(**vars(info))
|
|
145
|
+
output["type"] = "view"
|
|
146
|
+
return output
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class SingleEdgeProperty(EdgeProperty):
|
|
150
|
+
connection_type: Literal["single_edge_connection"] = "single_edge_connection"
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class MultiEdgeProperty(EdgeProperty):
|
|
154
|
+
connection_type: Literal["multi_edge_connection"] = "multi_edge_connection"
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class ReverseDirectRelationProperty(ConnectionPropertyDefinition, ABC):
|
|
158
|
+
source: ViewReference = Field(
|
|
159
|
+
description="The node(s) containing the direct relation property can be read "
|
|
160
|
+
"through the view specified in 'source'."
|
|
161
|
+
)
|
|
162
|
+
through: ContainerDirectReference | ViewDirectReference = Field(
|
|
163
|
+
description="The view of the node containing the direct relation property."
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
@field_serializer("source", mode="plain")
|
|
167
|
+
@classmethod
|
|
168
|
+
def serialize_source(cls, source: ViewReference, info: FieldSerializationInfo) -> dict[str, Any] | None:
|
|
169
|
+
output = source.model_dump(**vars(info))
|
|
170
|
+
output["type"] = "view"
|
|
171
|
+
return output
|
|
172
|
+
|
|
173
|
+
@field_serializer("through", mode="plain")
|
|
174
|
+
@classmethod
|
|
175
|
+
def serialize_through(
|
|
176
|
+
cls, through: ContainerDirectReference | ViewDirectReference, info: FieldSerializationInfo
|
|
177
|
+
) -> dict[str, Any]:
|
|
178
|
+
output = through.model_dump(**vars(info))
|
|
179
|
+
if isinstance(through, ContainerDirectReference):
|
|
180
|
+
output["source"]["type"] = "container"
|
|
181
|
+
else:
|
|
182
|
+
output["source"]["type"] = "view"
|
|
183
|
+
return output
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class SingleReverseDirectRelationPropertyRequest(ReverseDirectRelationProperty):
|
|
187
|
+
connection_type: Literal["single_reverse_direct_relation"] = "single_reverse_direct_relation"
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class MultiReverseDirectRelationPropertyRequest(ReverseDirectRelationProperty):
|
|
191
|
+
connection_type: Literal["multi_reverse_direct_relation"] = "multi_reverse_direct_relation"
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class SingleReverseDirectRelationPropertyResponse(
|
|
195
|
+
ReverseDirectRelationProperty, WriteableResource[SingleReverseDirectRelationPropertyRequest]
|
|
196
|
+
):
|
|
197
|
+
connection_type: Literal["single_reverse_direct_relation"] = "single_reverse_direct_relation"
|
|
198
|
+
targets_list: bool = Field(
|
|
199
|
+
description="Whether or not this reverse direct relation targets a list of direct relations.",
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
def as_request(self) -> SingleReverseDirectRelationPropertyRequest:
|
|
203
|
+
return SingleReverseDirectRelationPropertyRequest.model_validate(self.model_dump(by_alias=True))
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class MultiReverseDirectRelationPropertyResponse(
|
|
207
|
+
ReverseDirectRelationProperty, WriteableResource[MultiReverseDirectRelationPropertyRequest]
|
|
208
|
+
):
|
|
209
|
+
connection_type: Literal["multi_reverse_direct_relation"] = "multi_reverse_direct_relation"
|
|
210
|
+
targets_list: bool = Field(
|
|
211
|
+
description="Whether or not this reverse direct relation targets a list of direct relations.",
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
def as_request(self) -> MultiReverseDirectRelationPropertyRequest:
|
|
215
|
+
return MultiReverseDirectRelationPropertyRequest.model_validate(self.model_dump(by_alias=True))
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
ViewRequestProperty = Annotated[
|
|
219
|
+
SingleEdgeProperty
|
|
220
|
+
| MultiEdgeProperty
|
|
221
|
+
| SingleReverseDirectRelationPropertyRequest
|
|
222
|
+
| MultiReverseDirectRelationPropertyRequest
|
|
223
|
+
| ViewCorePropertyRequest,
|
|
224
|
+
Field(discriminator="connection_type"),
|
|
225
|
+
]
|
|
226
|
+
ViewResponseProperty = Annotated[
|
|
227
|
+
SingleEdgeProperty
|
|
228
|
+
| MultiEdgeProperty
|
|
229
|
+
| SingleReverseDirectRelationPropertyResponse
|
|
230
|
+
| MultiReverseDirectRelationPropertyResponse
|
|
231
|
+
| ViewCorePropertyResponse,
|
|
232
|
+
Field(discriminator="connection_type"),
|
|
233
|
+
]
|
|
234
|
+
|
|
235
|
+
ViewRequestPropertyAdapter: TypeAdapter[ViewRequestProperty] = TypeAdapter(ViewRequestProperty)
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from abc import ABC
|
|
3
|
+
from typing import Any, Literal, TypeVar
|
|
4
|
+
|
|
5
|
+
from pydantic import Field, field_serializer, field_validator, model_validator
|
|
6
|
+
from pydantic_core.core_schema import FieldSerializationInfo
|
|
7
|
+
|
|
8
|
+
from cognite.neat._utils.text import humanize_collection
|
|
9
|
+
|
|
10
|
+
from . import DirectNodeRelation
|
|
11
|
+
from ._base import APIResource, Resource, WriteableResource
|
|
12
|
+
from ._constants import (
|
|
13
|
+
CONTAINER_AND_VIEW_PROPERTIES_IDENTIFIER_PATTERN,
|
|
14
|
+
DM_EXTERNAL_ID_PATTERN,
|
|
15
|
+
DM_VERSION_PATTERN,
|
|
16
|
+
FORBIDDEN_CONTAINER_AND_VIEW_EXTERNAL_IDS,
|
|
17
|
+
FORBIDDEN_CONTAINER_AND_VIEW_PROPERTIES_IDENTIFIER,
|
|
18
|
+
SPACE_FORMAT_PATTERN,
|
|
19
|
+
)
|
|
20
|
+
from ._references import ContainerReference, NodeReference, ViewReference
|
|
21
|
+
from ._view_filter import Filter
|
|
22
|
+
from ._view_property import (
|
|
23
|
+
EdgeProperty,
|
|
24
|
+
ViewCorePropertyRequest,
|
|
25
|
+
ViewCorePropertyResponse,
|
|
26
|
+
ViewRequestProperty,
|
|
27
|
+
ViewResponseProperty,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
KEY_PATTERN = re.compile(CONTAINER_AND_VIEW_PROPERTIES_IDENTIFIER_PATTERN)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class View(Resource, APIResource[ViewReference], ABC):
|
|
34
|
+
space: str = Field(
|
|
35
|
+
description="Id of the space that the view belongs to.",
|
|
36
|
+
min_length=1,
|
|
37
|
+
max_length=43,
|
|
38
|
+
pattern=SPACE_FORMAT_PATTERN,
|
|
39
|
+
)
|
|
40
|
+
external_id: str = Field(
|
|
41
|
+
description="External-id of the view.",
|
|
42
|
+
min_length=1,
|
|
43
|
+
max_length=255,
|
|
44
|
+
pattern=DM_EXTERNAL_ID_PATTERN,
|
|
45
|
+
)
|
|
46
|
+
version: str = Field(
|
|
47
|
+
description="Version of the view.",
|
|
48
|
+
max_length=43,
|
|
49
|
+
pattern=DM_VERSION_PATTERN,
|
|
50
|
+
)
|
|
51
|
+
name: str | None = Field(
|
|
52
|
+
default=None,
|
|
53
|
+
description="name for the view.",
|
|
54
|
+
max_length=255,
|
|
55
|
+
)
|
|
56
|
+
description: str | None = Field(
|
|
57
|
+
default=None,
|
|
58
|
+
description="Description of the view.",
|
|
59
|
+
max_length=1024,
|
|
60
|
+
)
|
|
61
|
+
filter: Filter | None = Field(
|
|
62
|
+
default=None,
|
|
63
|
+
description="A filter Domain Specific Language (DSL) used to select which instances the view should include.",
|
|
64
|
+
)
|
|
65
|
+
implements: list[ViewReference] | None = Field(
|
|
66
|
+
default=None,
|
|
67
|
+
description="References to the views from where this view will inherit properties.",
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
def as_reference(self) -> ViewReference:
|
|
71
|
+
return ViewReference(space=self.space, external_id=self.external_id, version=self.version)
|
|
72
|
+
|
|
73
|
+
@model_validator(mode="before")
|
|
74
|
+
def set_connection_type_on_primary_properties(cls, data: dict) -> dict:
|
|
75
|
+
if "properties" not in data:
|
|
76
|
+
return data
|
|
77
|
+
properties = data["properties"]
|
|
78
|
+
if not isinstance(properties, dict):
|
|
79
|
+
return data
|
|
80
|
+
# We assume all properties without connectionType are core properties.
|
|
81
|
+
# The reason we set connectionType it easy for pydantic to discriminate the union.
|
|
82
|
+
# This also leads to better error messages, as if there is a union and pydantic do not know which
|
|
83
|
+
# type to pick it will give errors from all type in the union.
|
|
84
|
+
new_properties: dict[str, Any] = {}
|
|
85
|
+
for prop_id, prop in properties.items():
|
|
86
|
+
if isinstance(prop, dict) and "connectionType" not in prop:
|
|
87
|
+
prop_copy = prop.copy()
|
|
88
|
+
prop_copy["connectionType"] = "primary_property"
|
|
89
|
+
new_properties[prop_id] = prop_copy
|
|
90
|
+
else:
|
|
91
|
+
new_properties[prop_id] = prop
|
|
92
|
+
if new_properties:
|
|
93
|
+
new_data = data.copy()
|
|
94
|
+
new_data["properties"] = new_properties
|
|
95
|
+
return new_data
|
|
96
|
+
|
|
97
|
+
return data
|
|
98
|
+
|
|
99
|
+
@field_validator("external_id", mode="after")
|
|
100
|
+
def check_forbidden_external_id_value(cls, val: str) -> str:
|
|
101
|
+
"""Check the external_id not present in forbidden set"""
|
|
102
|
+
if val in FORBIDDEN_CONTAINER_AND_VIEW_EXTERNAL_IDS:
|
|
103
|
+
raise ValueError(
|
|
104
|
+
f"'{val}' is a reserved view External ID. Reserved External IDs are: "
|
|
105
|
+
f"{humanize_collection(FORBIDDEN_CONTAINER_AND_VIEW_EXTERNAL_IDS)}"
|
|
106
|
+
)
|
|
107
|
+
return val
|
|
108
|
+
|
|
109
|
+
@field_serializer("implements", mode="plain")
|
|
110
|
+
@classmethod
|
|
111
|
+
def serialize_implements(
|
|
112
|
+
cls, implements: list[ViewReference] | None, info: FieldSerializationInfo
|
|
113
|
+
) -> list[dict[str, Any]] | None:
|
|
114
|
+
if implements is None:
|
|
115
|
+
return None
|
|
116
|
+
output: list[dict[str, Any]] = []
|
|
117
|
+
for view in implements:
|
|
118
|
+
dumped = view.model_dump(**vars(info))
|
|
119
|
+
dumped["type"] = "view"
|
|
120
|
+
output.append(dumped)
|
|
121
|
+
return output
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class ViewRequest(View):
|
|
125
|
+
properties: dict[str, ViewRequestProperty] = Field(
|
|
126
|
+
description="View with included properties and expected edges, indexed by a unique space-local identifier."
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
@field_validator("properties", mode="after")
|
|
130
|
+
def validate_properties_identifier(cls, val: dict[str, ViewRequestProperty]) -> dict[str, ViewRequestProperty]:
|
|
131
|
+
"""Validate properties Identifier"""
|
|
132
|
+
return _validate_properties_keys(val)
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def used_containers(self) -> set[ContainerReference]:
|
|
136
|
+
"""Get all containers referenced by this view."""
|
|
137
|
+
return {prop.container for prop in self.properties.values() if isinstance(prop, ViewCorePropertyRequest)}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class ViewResponse(View, WriteableResource[ViewRequest]):
|
|
141
|
+
properties: dict[str, ViewResponseProperty] = Field(
|
|
142
|
+
description="List of properties and connections included in this view."
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
created_time: int = Field(
|
|
146
|
+
description="When the view was created. The number of milliseconds since 00:00:00 Thursday, 1 January 1970, "
|
|
147
|
+
"Coordinated Universal Time (UTC), minus leap seconds."
|
|
148
|
+
)
|
|
149
|
+
last_updated_time: int = Field(
|
|
150
|
+
description="When the view was last updated. The number of milliseconds since 00:00:00 Thursday, "
|
|
151
|
+
"1 January 1970, Coordinated Universal Time (UTC), minus leap seconds."
|
|
152
|
+
)
|
|
153
|
+
writable: bool = Field(
|
|
154
|
+
description="oes the view support write operations, i.e. is it writable? "
|
|
155
|
+
"You can write to a view if the view maps all non-nullable properties."
|
|
156
|
+
)
|
|
157
|
+
queryable: bool = Field(
|
|
158
|
+
description="Does the view support queries, i.e. is it queryable? You can query a view if "
|
|
159
|
+
"it either has a filter or at least one property mapped to a container."
|
|
160
|
+
)
|
|
161
|
+
used_for: Literal["node", "edge", "all"] = Field(description="Should this operation apply to nodes, edges or both.")
|
|
162
|
+
is_global: bool = Field(description="Is this a global view.")
|
|
163
|
+
mapped_containers: list[ContainerReference] = Field(
|
|
164
|
+
description="List of containers with properties mapped by this view."
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
@field_validator("properties", mode="after")
|
|
168
|
+
def validate_properties_identifier(cls, val: dict[str, ViewResponseProperty]) -> dict[str, ViewResponseProperty]:
|
|
169
|
+
"""Validate properties Identifier"""
|
|
170
|
+
return _validate_properties_keys(val)
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def node_types(self) -> list[NodeReference]:
|
|
174
|
+
"""Get all node types referenced by this view."""
|
|
175
|
+
nodes_refs: set[NodeReference] = set()
|
|
176
|
+
for prop in self.properties.values():
|
|
177
|
+
if isinstance(prop, EdgeProperty):
|
|
178
|
+
nodes_refs.add(prop.type)
|
|
179
|
+
return list(nodes_refs)
|
|
180
|
+
|
|
181
|
+
def as_request(self) -> ViewRequest:
|
|
182
|
+
dumped = self.model_dump(by_alias=True, exclude={"properties"})
|
|
183
|
+
properties: dict[str, Any] = {}
|
|
184
|
+
for key, value in self.properties.items():
|
|
185
|
+
if isinstance(value, ViewCorePropertyResponse) and isinstance(value.type, DirectNodeRelation):
|
|
186
|
+
# Special case. In the request the source of DirectNodeRelation is set on the Property object,
|
|
187
|
+
# while in the response it is set on the DirectNodeRelation object.
|
|
188
|
+
request_object = value.as_request().model_dump(by_alias=True)
|
|
189
|
+
request_object["source"] = value.type.source.model_dump(by_alias=True) if value.type.source else None
|
|
190
|
+
properties[key] = request_object
|
|
191
|
+
elif isinstance(value, WriteableResource):
|
|
192
|
+
properties[key] = value.as_request().model_dump(by_alias=True)
|
|
193
|
+
else:
|
|
194
|
+
properties[key] = value.model_dump(by_alias=True)
|
|
195
|
+
|
|
196
|
+
dumped["properties"] = properties
|
|
197
|
+
return ViewRequest.model_validate(dumped)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
T_Property = TypeVar("T_Property")
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def _validate_properties_keys(properties: dict[str, T_Property]) -> dict[str, T_Property]:
|
|
204
|
+
"""Validate keys of a properties dictionary."""
|
|
205
|
+
errors: list[str] = []
|
|
206
|
+
for key in properties:
|
|
207
|
+
if not KEY_PATTERN.match(key):
|
|
208
|
+
errors.append(f"Property '{key}' does not match the required pattern: {KEY_PATTERN.pattern}")
|
|
209
|
+
if key in FORBIDDEN_CONTAINER_AND_VIEW_PROPERTIES_IDENTIFIER:
|
|
210
|
+
errors.append(
|
|
211
|
+
f"'{key}' is a reserved property identifier. Reserved identifiers are: "
|
|
212
|
+
f"{humanize_collection(FORBIDDEN_CONTAINER_AND_VIEW_PROPERTIES_IDENTIFIER)}"
|
|
213
|
+
)
|
|
214
|
+
if errors:
|
|
215
|
+
raise ValueError("; ".join(errors))
|
|
216
|
+
return properties
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from ._base import ConceptEntity, UnknownEntity
|
|
2
|
+
from ._constants import Undefined, Unknown
|
|
3
|
+
from ._data_types import (
|
|
4
|
+
AnyURI,
|
|
5
|
+
Boolean,
|
|
6
|
+
DataType,
|
|
7
|
+
Date,
|
|
8
|
+
DateTime,
|
|
9
|
+
DateTimeStamp,
|
|
10
|
+
Double,
|
|
11
|
+
Enum,
|
|
12
|
+
File,
|
|
13
|
+
Float,
|
|
14
|
+
Integer,
|
|
15
|
+
Json,
|
|
16
|
+
Long,
|
|
17
|
+
Sequence,
|
|
18
|
+
String,
|
|
19
|
+
Timeseries,
|
|
20
|
+
)
|
|
21
|
+
from ._identifiers import URI, NameSpace
|
|
22
|
+
from ._parser import ParsedEntity, parse_entities, parse_entity
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
"URI",
|
|
26
|
+
"AnyURI",
|
|
27
|
+
"Boolean",
|
|
28
|
+
"ConceptEntity",
|
|
29
|
+
"DataType",
|
|
30
|
+
"Date",
|
|
31
|
+
"DateTime",
|
|
32
|
+
"DateTimeStamp",
|
|
33
|
+
"Double",
|
|
34
|
+
"Enum",
|
|
35
|
+
"File",
|
|
36
|
+
"Float",
|
|
37
|
+
"Integer",
|
|
38
|
+
"Json",
|
|
39
|
+
"Long",
|
|
40
|
+
"NameSpace",
|
|
41
|
+
"ParsedEntity",
|
|
42
|
+
"Sequence",
|
|
43
|
+
"String",
|
|
44
|
+
"Timeseries",
|
|
45
|
+
"Undefined",
|
|
46
|
+
"Unknown",
|
|
47
|
+
"UnknownEntity",
|
|
48
|
+
"parse_entities",
|
|
49
|
+
"parse_entity",
|
|
50
|
+
]
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from functools import total_ordering
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, Field, field_validator, model_serializer
|
|
5
|
+
|
|
6
|
+
from ._constants import (
|
|
7
|
+
PREFIX_PATTERN,
|
|
8
|
+
SUFFIX_PATTERN,
|
|
9
|
+
VERSION_PATTERN,
|
|
10
|
+
Undefined,
|
|
11
|
+
Unknown,
|
|
12
|
+
_UndefinedType,
|
|
13
|
+
_UnknownType,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@total_ordering
|
|
18
|
+
class Entity(BaseModel, extra="ignore", populate_by_name=True):
|
|
19
|
+
"""Entity is a concept, class, property, datatype in semantics sense."""
|
|
20
|
+
|
|
21
|
+
prefix: str | _UndefinedType = Field(default=Undefined, pattern=PREFIX_PATTERN, min_length=1, max_length=43)
|
|
22
|
+
suffix: str = Field(min_length=1, max_length=255, pattern=SUFFIX_PATTERN)
|
|
23
|
+
|
|
24
|
+
@model_serializer(when_used="unless-none", return_type=str)
|
|
25
|
+
def as_str(self) -> str:
|
|
26
|
+
return str(self)
|
|
27
|
+
|
|
28
|
+
@field_validator("*", mode="before")
|
|
29
|
+
def strip_string(cls, value: Any) -> Any:
|
|
30
|
+
if isinstance(value, str):
|
|
31
|
+
return value.strip()
|
|
32
|
+
elif isinstance(value, list):
|
|
33
|
+
return [entry.strip() if isinstance(entry, str) else entry for entry in value]
|
|
34
|
+
return value
|
|
35
|
+
|
|
36
|
+
def as_tuple(self) -> tuple[str, ...]:
|
|
37
|
+
# We haver overwritten the serialization to str, so we need to do it manually
|
|
38
|
+
extra: tuple[str, ...] = tuple(
|
|
39
|
+
[
|
|
40
|
+
str(v or "")
|
|
41
|
+
for field_name in self.model_fields.keys()
|
|
42
|
+
if (v := getattr(self, field_name)) and field_name not in {"prefix", "suffix"}
|
|
43
|
+
]
|
|
44
|
+
)
|
|
45
|
+
if isinstance(self.prefix, _UndefinedType):
|
|
46
|
+
return str(self.suffix), *extra
|
|
47
|
+
else:
|
|
48
|
+
return self.prefix, str(self.suffix), *extra
|
|
49
|
+
|
|
50
|
+
def __lt__(self, other: object) -> bool:
|
|
51
|
+
if type(other) is not type(self):
|
|
52
|
+
return NotImplemented
|
|
53
|
+
return self.as_tuple() < other.as_tuple() # type: ignore[attr-defined]
|
|
54
|
+
|
|
55
|
+
def __eq__(self, other: object) -> bool:
|
|
56
|
+
# We need to be explicit that we are not allowing comparison between different types
|
|
57
|
+
if type(other) is not type(self):
|
|
58
|
+
# requires explicit raising as NotImplemented would lead to running comparison
|
|
59
|
+
raise TypeError(f"'==' not supported between instances of {type(self).__name__} and {type(other).__name__}")
|
|
60
|
+
return self.as_tuple() == other.as_tuple() # type: ignore[attr-defined]
|
|
61
|
+
|
|
62
|
+
def __hash__(self) -> int:
|
|
63
|
+
return hash(f"{type(self).__name__}({self})")
|
|
64
|
+
|
|
65
|
+
def __str__(self) -> str:
|
|
66
|
+
# there are three cases for string representation:
|
|
67
|
+
# 1. only suffix is present -> return str(suffix)
|
|
68
|
+
# 2. prefix and suffix are present -> return "prefix:suffix"
|
|
69
|
+
# 3. prefix, suffix and other fields are present -> return "prefix:suffix(field1=value1,field2=value2)"
|
|
70
|
+
|
|
71
|
+
model_dump = {k: v for k in self.model_fields if (v := getattr(self, k)) is not None}
|
|
72
|
+
|
|
73
|
+
base_str = f"{self.prefix}:{self.suffix}" if not isinstance(self.prefix, _UndefinedType) else str(self.suffix)
|
|
74
|
+
|
|
75
|
+
extra_fields = {
|
|
76
|
+
(self.model_fields[k].alias or k): v for k, v in model_dump.items() if k not in {"prefix", "suffix"}
|
|
77
|
+
}
|
|
78
|
+
if extra_fields:
|
|
79
|
+
extra_str = ",".join([f"{k}={v}" for k, v in extra_fields.items()])
|
|
80
|
+
return f"{base_str}({extra_str})"
|
|
81
|
+
else:
|
|
82
|
+
return base_str
|
|
83
|
+
|
|
84
|
+
def __repr__(self) -> str:
|
|
85
|
+
# We have overwritten the serialization to str, so we need to do it manually
|
|
86
|
+
model_dump = {k: v for k in self.model_fields if (v := getattr(self, k)) is not None}
|
|
87
|
+
args = ",".join([f"{k}={v!r}" for k, v in model_dump.items()])
|
|
88
|
+
return f"{type(self).__name__}({args})"
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class ConceptEntity(Entity):
|
|
92
|
+
version: str | None = Field(default=None, pattern=VERSION_PATTERN, max_length=43)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class UnknownEntity(ConceptEntity):
|
|
96
|
+
prefix: _UndefinedType = Undefined
|
|
97
|
+
suffix: _UnknownType = Unknown # type: ignore[assignment]
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def id(self) -> str:
|
|
101
|
+
return str(Unknown)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class _UndefinedType(BaseModel): ...
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class _UnknownType(BaseModel):
|
|
8
|
+
def __str__(self) -> str:
|
|
9
|
+
return "#N/A"
|
|
10
|
+
|
|
11
|
+
def __hash__(self) -> int:
|
|
12
|
+
return hash(str(self))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# This is a trick to make Undefined and Unknown singletons
|
|
16
|
+
Undefined = _UndefinedType()
|
|
17
|
+
Unknown = _UnknownType()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
PREFIX_PATTERN = r"^[a-zA-Z][a-zA-Z0-9_-]{0,41}[a-zA-Z0-9]?$"
|
|
21
|
+
SUFFIX_PATTERN = r"^[a-zA-Z0-9._~?@!$&'*+,;=%-]+$"
|
|
22
|
+
VERSION_PATTERN = r"^[a-zA-Z0-9]([.a-zA-Z0-9_-]{0,41}[a-zA-Z0-9])?$"
|