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,240 @@
|
|
|
1
|
+
"""Storage abstraction for persisting data in both local filesystem and pyodide environments."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import TYPE_CHECKING, Protocol
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
try:
|
|
10
|
+
import asyncio
|
|
11
|
+
|
|
12
|
+
from pyodide.webloop import PyodideTask # type: ignore[import-not-found]
|
|
13
|
+
except ImportError:
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
from cognite.neat._session._usage_analytics._constants import IN_PYODIDE
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class ReadResult(ABC):
|
|
21
|
+
@property
|
|
22
|
+
@abstractmethod
|
|
23
|
+
def is_ready(self) -> bool: ...
|
|
24
|
+
|
|
25
|
+
@abstractmethod
|
|
26
|
+
def get_data(self) -> str: ...
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class ManualReadResult(ReadResult):
|
|
31
|
+
data: str
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def is_ready(self) -> bool:
|
|
35
|
+
return True
|
|
36
|
+
|
|
37
|
+
def get_data(self) -> str:
|
|
38
|
+
return self.data
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class Storage(Protocol):
|
|
42
|
+
"""Protocol for storage implementations."""
|
|
43
|
+
|
|
44
|
+
def read(self, key: str) -> ReadResult:
|
|
45
|
+
"""Read a value from storage."""
|
|
46
|
+
...
|
|
47
|
+
|
|
48
|
+
def write(self, key: str, value: str) -> None:
|
|
49
|
+
"""Write a value to storage."""
|
|
50
|
+
...
|
|
51
|
+
|
|
52
|
+
def delete(self, key: str) -> None:
|
|
53
|
+
"""Delete a value from storage."""
|
|
54
|
+
...
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass
|
|
58
|
+
class FileReadResult(ReadResult):
|
|
59
|
+
data: str
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def is_ready(self) -> bool:
|
|
63
|
+
return True
|
|
64
|
+
|
|
65
|
+
def get_data(self) -> str:
|
|
66
|
+
return self.data
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class FileSystemStorage:
|
|
70
|
+
"""Storage implementation using the filesystem."""
|
|
71
|
+
|
|
72
|
+
ENCODING = "utf-8"
|
|
73
|
+
|
|
74
|
+
def __init__(self, base_dir: Path) -> None:
|
|
75
|
+
self._base_dir = base_dir
|
|
76
|
+
|
|
77
|
+
def _get_path(self, key: str) -> Path:
|
|
78
|
+
return self._base_dir / f"{key}.bin"
|
|
79
|
+
|
|
80
|
+
def read(self, key: str) -> ReadResult:
|
|
81
|
+
path = self._get_path(key)
|
|
82
|
+
if path.exists():
|
|
83
|
+
return FileReadResult(path.read_text(encoding=self.ENCODING))
|
|
84
|
+
return FileReadResult("")
|
|
85
|
+
|
|
86
|
+
def write(self, key: str, value: str) -> None:
|
|
87
|
+
path = self._get_path(key)
|
|
88
|
+
path.write_text(value, encoding=self.ENCODING)
|
|
89
|
+
|
|
90
|
+
def delete(self, key: str) -> None:
|
|
91
|
+
path = self._get_path(key)
|
|
92
|
+
path.unlink(missing_ok=True)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@dataclass
|
|
96
|
+
class PyodideResult(ReadResult):
|
|
97
|
+
task: "PyodideTask"
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def is_ready(self) -> bool:
|
|
101
|
+
return self.task.done()
|
|
102
|
+
|
|
103
|
+
def get_data(self) -> str:
|
|
104
|
+
return self.task.result()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class LocalStorageAdapter:
|
|
108
|
+
"""
|
|
109
|
+
Storage implementation using browser IndexedDB for pyodide environments.
|
|
110
|
+
|
|
111
|
+
This adapter provides a synchronous interface to the asynchronous IndexedDB API
|
|
112
|
+
by managing an asyncio event loop.
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
_db_name = "neat-storage"
|
|
116
|
+
_store_name = "keyval"
|
|
117
|
+
_db_version = 1
|
|
118
|
+
|
|
119
|
+
def __init__(self) -> None:
|
|
120
|
+
self._loop = self._get_or_create_event_loop()
|
|
121
|
+
|
|
122
|
+
@staticmethod
|
|
123
|
+
def _get_or_create_event_loop() -> "asyncio.AbstractEventLoop":
|
|
124
|
+
"""Gets the current asyncio event loop or creates a new one."""
|
|
125
|
+
import asyncio
|
|
126
|
+
|
|
127
|
+
try:
|
|
128
|
+
return asyncio.get_event_loop()
|
|
129
|
+
except RuntimeError:
|
|
130
|
+
loop = asyncio.new_event_loop()
|
|
131
|
+
asyncio.set_event_loop(loop)
|
|
132
|
+
return loop
|
|
133
|
+
|
|
134
|
+
def _execute_db_operation(self, operation: str, key: str, value: str | None = None) -> "PyodideTask":
|
|
135
|
+
"""Executes a database operation by creating and calling a JS function."""
|
|
136
|
+
|
|
137
|
+
async def db_operation() -> str:
|
|
138
|
+
import js # type: ignore[import-not-found]
|
|
139
|
+
from pyodide.code import run_js # type: ignore[import-not-found]
|
|
140
|
+
from pyodide.ffi import to_js # type: ignore[import-not-found]
|
|
141
|
+
|
|
142
|
+
# Convert Python values to JS
|
|
143
|
+
js_key = to_js(key)
|
|
144
|
+
js_value = to_js(value if value is not None else "")
|
|
145
|
+
|
|
146
|
+
# Store values in js namespace temporarily to pass them safely
|
|
147
|
+
js._idb_key = js_key
|
|
148
|
+
js._idb_value = js_value
|
|
149
|
+
|
|
150
|
+
try:
|
|
151
|
+
# Create and execute the function directly in JavaScript context using run_js
|
|
152
|
+
js_code = f"""
|
|
153
|
+
(async () => {{
|
|
154
|
+
const dbName = "{self._db_name}";
|
|
155
|
+
const dbVersion = {self._db_version};
|
|
156
|
+
const storeName = "{self._store_name}";
|
|
157
|
+
const operation = "{operation}";
|
|
158
|
+
|
|
159
|
+
return new Promise((resolve, reject) => {{
|
|
160
|
+
const request = indexedDB.open(dbName, dbVersion);
|
|
161
|
+
|
|
162
|
+
request.onerror = (event) => reject(event.target.error);
|
|
163
|
+
|
|
164
|
+
request.onupgradeneeded = (event) => {{
|
|
165
|
+
const db = event.target.result;
|
|
166
|
+
if (!db.objectStoreNames.contains(storeName)) {{
|
|
167
|
+
db.createObjectStore(storeName);
|
|
168
|
+
}}
|
|
169
|
+
}};
|
|
170
|
+
|
|
171
|
+
request.onsuccess = (event) => {{
|
|
172
|
+
const db = event.target.result;
|
|
173
|
+
const mode = (operation === "read") ? "readonly" : "readwrite";
|
|
174
|
+
try {{
|
|
175
|
+
const transaction = db.transaction([storeName], mode);
|
|
176
|
+
const store = transaction.objectStore(storeName);
|
|
177
|
+
|
|
178
|
+
let storeRequest;
|
|
179
|
+
if (operation === "read") {{
|
|
180
|
+
storeRequest = store.get(_idb_key);
|
|
181
|
+
}} else if (operation === "write") {{
|
|
182
|
+
storeRequest = store.put(_idb_value, _idb_key);
|
|
183
|
+
}} else if (operation === "delete") {{
|
|
184
|
+
storeRequest = store.delete(_idb_key);
|
|
185
|
+
}} else {{
|
|
186
|
+
db.close();
|
|
187
|
+
return reject(new Error(`Unknown operation: ${{operation}}`));
|
|
188
|
+
}}
|
|
189
|
+
|
|
190
|
+
storeRequest.onsuccess = () => resolve(storeRequest.result ?? "");
|
|
191
|
+
storeRequest.onerror = (event) => reject(event.target.error);
|
|
192
|
+
|
|
193
|
+
transaction.oncomplete = () => db.close();
|
|
194
|
+
transaction.onerror = (event) => reject(event.target.error);
|
|
195
|
+
|
|
196
|
+
}} catch (error) {{
|
|
197
|
+
db.close();
|
|
198
|
+
reject(error);
|
|
199
|
+
}}
|
|
200
|
+
}};
|
|
201
|
+
}});
|
|
202
|
+
}})()
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
# Use run_js which properly returns an awaitable promise
|
|
206
|
+
result = await run_js(js_code)
|
|
207
|
+
return str(result) if result is not None else ""
|
|
208
|
+
finally:
|
|
209
|
+
# Clean up js namespace
|
|
210
|
+
try:
|
|
211
|
+
del js._idb_key
|
|
212
|
+
del js._idb_value
|
|
213
|
+
except Exception:
|
|
214
|
+
pass
|
|
215
|
+
|
|
216
|
+
try:
|
|
217
|
+
return self._loop.run_until_complete(db_operation())
|
|
218
|
+
except Exception:
|
|
219
|
+
return ""
|
|
220
|
+
|
|
221
|
+
def read(self, key: str) -> ReadResult:
|
|
222
|
+
return PyodideResult(self._execute_db_operation("read", key))
|
|
223
|
+
|
|
224
|
+
def write(self, key: str, value: str) -> None:
|
|
225
|
+
self._execute_db_operation("write", key, value)
|
|
226
|
+
|
|
227
|
+
def delete(self, key: str) -> None:
|
|
228
|
+
self._execute_db_operation("delete", key)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def get_storage(base_dir: Path | None = None) -> Storage:
|
|
232
|
+
"""Get the appropriate storage implementation for the current environment."""
|
|
233
|
+
if IN_PYODIDE:
|
|
234
|
+
return LocalStorageAdapter()
|
|
235
|
+
else:
|
|
236
|
+
if base_dir is None:
|
|
237
|
+
import tempfile
|
|
238
|
+
|
|
239
|
+
base_dir = Path(tempfile.gettempdir()).resolve()
|
|
240
|
+
return FileSystemStorage(base_dir)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from functools import wraps
|
|
3
|
+
from typing import Any, Protocol, TypeVar
|
|
4
|
+
|
|
5
|
+
from cognite.neat._issues import ConsistencyError, Recommendation
|
|
6
|
+
from cognite.neat._session._usage_analytics._collector import Collector
|
|
7
|
+
from cognite.neat._store._store import NeatStore
|
|
8
|
+
from cognite.neat._utils.text import NEWLINE, split_on_capitals
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class HasStore(Protocol):
|
|
12
|
+
_store: NeatStore
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
T_Class = TypeVar("T_Class", bound=HasStore)
|
|
16
|
+
|
|
17
|
+
_COLLECTOR = Collector()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def session_wrapper(cls: type[T_Class]) -> type[T_Class]:
|
|
21
|
+
# 1. Define the method decorator inside
|
|
22
|
+
def _handle_method_call(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
23
|
+
"""Decorator to handle exceptions and print provenance length"""
|
|
24
|
+
|
|
25
|
+
@wraps(func)
|
|
26
|
+
def wrapper(self: HasStore, *args: Any, **kwargs: Any) -> Any:
|
|
27
|
+
display_name = f"{' '.join(split_on_capitals(cls.__name__))} - {func.__name__}"
|
|
28
|
+
identifier = f"{cls.__name__}.{func.__name__}"
|
|
29
|
+
try:
|
|
30
|
+
res = func(self, *args, **kwargs)
|
|
31
|
+
if not self._store.provenance or "DataModel" not in identifier:
|
|
32
|
+
print(f"{display_name} ✅")
|
|
33
|
+
if _COLLECTOR.can_collect:
|
|
34
|
+
_COLLECTOR.collect("action", {"action": identifier, "success": True})
|
|
35
|
+
return res
|
|
36
|
+
change = self._store.provenance[-1]
|
|
37
|
+
|
|
38
|
+
recommendation_count = (
|
|
39
|
+
len(recommendations)
|
|
40
|
+
if change.issues and (recommendations := change.issues.by_type().get(Recommendation))
|
|
41
|
+
else 0
|
|
42
|
+
)
|
|
43
|
+
consistency_errors_count = (
|
|
44
|
+
len(consistency_errors)
|
|
45
|
+
if change.issues and (consistency_errors := change.issues.by_type().get(ConsistencyError))
|
|
46
|
+
else 0
|
|
47
|
+
)
|
|
48
|
+
syntax_errors_count = len(change.errors) if change.errors else 0
|
|
49
|
+
errors_count = consistency_errors_count + syntax_errors_count
|
|
50
|
+
total_insights = recommendation_count + consistency_errors_count + syntax_errors_count
|
|
51
|
+
|
|
52
|
+
data_model_not_read = not change.successful and "ReadPhysicalDataModel" in identifier
|
|
53
|
+
|
|
54
|
+
if not change.successful:
|
|
55
|
+
success_icon = "❌"
|
|
56
|
+
elif change.successful and consistency_errors_count:
|
|
57
|
+
success_icon = "⚠️"
|
|
58
|
+
else:
|
|
59
|
+
success_icon = "✅"
|
|
60
|
+
|
|
61
|
+
print(
|
|
62
|
+
f"{display_name} "
|
|
63
|
+
f"{success_icon}"
|
|
64
|
+
f"{f' | Insights: {total_insights} (of which {errors_count} errors)' if total_insights > 0 else ''}"
|
|
65
|
+
f"{NEWLINE + '⚠️ Data model not read into session' if data_model_not_read else ''}"
|
|
66
|
+
f"{NEWLINE + '📋 For details on issues run .issues' if change.issues or change.errors else ''}"
|
|
67
|
+
f"{NEWLINE + '📊 For details on result run .result' if change.result else ''}"
|
|
68
|
+
)
|
|
69
|
+
if _COLLECTOR.can_collect:
|
|
70
|
+
event = change.as_mixpanel_event()
|
|
71
|
+
event["action"] = identifier
|
|
72
|
+
_COLLECTOR.collect("action", event)
|
|
73
|
+
if change.result:
|
|
74
|
+
event = change.result.as_mixpanel_event()
|
|
75
|
+
event["action"] = identifier
|
|
76
|
+
_COLLECTOR.collect("deployment", event)
|
|
77
|
+
|
|
78
|
+
return res
|
|
79
|
+
|
|
80
|
+
# if an error occurs, we catch it and print it out instead of
|
|
81
|
+
# getting a full traceback
|
|
82
|
+
except Exception as e:
|
|
83
|
+
print(f"{display_name} ❌")
|
|
84
|
+
print(f"{e!s}")
|
|
85
|
+
if _COLLECTOR.can_collect:
|
|
86
|
+
_COLLECTOR.collect("action", {"action": identifier, "success": False, "error_message": str(e)})
|
|
87
|
+
|
|
88
|
+
return wrapper
|
|
89
|
+
|
|
90
|
+
# Iterate through all attributes of the class
|
|
91
|
+
for attr_name in dir(cls):
|
|
92
|
+
# Skip private/protected methods (starting with _)
|
|
93
|
+
if not attr_name.startswith("_"):
|
|
94
|
+
attr = getattr(cls, attr_name)
|
|
95
|
+
# Only wrap callable methods
|
|
96
|
+
if callable(attr):
|
|
97
|
+
# Replace the original method with wrapped version
|
|
98
|
+
setattr(cls, attr_name, _handle_method_call(attr))
|
|
99
|
+
|
|
100
|
+
# Return the modified class
|
|
101
|
+
return cls
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class State(ABC):
|
|
6
|
+
def __init__(self) -> None:
|
|
7
|
+
# this will be reference to the actual store in the session
|
|
8
|
+
# used to store data models and instances, here only as a placeholder
|
|
9
|
+
self._store = None
|
|
10
|
+
|
|
11
|
+
@abstractmethod
|
|
12
|
+
def transition(self, event: Any) -> "State":
|
|
13
|
+
"""
|
|
14
|
+
Handle events that are delegated to this State.
|
|
15
|
+
"""
|
|
16
|
+
raise NotImplementedError("on_event() must be implemented by the subclass.")
|
|
17
|
+
|
|
18
|
+
def can_transition(self, event: Any) -> bool:
|
|
19
|
+
"""
|
|
20
|
+
Check if the state can transition on the given event.
|
|
21
|
+
"""
|
|
22
|
+
# avoiding circular import
|
|
23
|
+
from cognite.neat._state_machine._states import ForbiddenState
|
|
24
|
+
|
|
25
|
+
return not isinstance(self.transition(event), ForbiddenState)
|
|
26
|
+
|
|
27
|
+
def __repr__(self) -> str:
|
|
28
|
+
"""
|
|
29
|
+
Leverages the __str__ method to describe the State.
|
|
30
|
+
"""
|
|
31
|
+
return self.__str__()
|
|
32
|
+
|
|
33
|
+
def __str__(self) -> str:
|
|
34
|
+
"""
|
|
35
|
+
Returns the name of the State.
|
|
36
|
+
"""
|
|
37
|
+
return self.__class__.__name__
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from cognite.neat._data_model.exporters import DMSExporter
|
|
4
|
+
from cognite.neat._data_model.importers import DMSImporter
|
|
5
|
+
|
|
6
|
+
from ._base import State
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Undo:
|
|
10
|
+
"""
|
|
11
|
+
Event to trigger undoing the last action.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ForbiddenState(State):
|
|
18
|
+
"""
|
|
19
|
+
State representing forbidden transitions - returns to previous state.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, previous_state: State):
|
|
23
|
+
self.previous_state = previous_state
|
|
24
|
+
|
|
25
|
+
def transition(self, event: Any) -> State:
|
|
26
|
+
# only "undo" to trigger going back to previous state
|
|
27
|
+
if isinstance(event, Undo):
|
|
28
|
+
return self.previous_state
|
|
29
|
+
return self
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class EmptyState(State):
|
|
33
|
+
"""
|
|
34
|
+
The initial state with empty NEAT store.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def transition(self, event: Any) -> State:
|
|
38
|
+
if isinstance(event, DMSImporter):
|
|
39
|
+
return PhysicalState()
|
|
40
|
+
return ForbiddenState(self)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class PhysicalState(State):
|
|
44
|
+
"""
|
|
45
|
+
State with physical model loaded.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def transition(self, event: Any) -> State:
|
|
49
|
+
if isinstance(event, DMSExporter):
|
|
50
|
+
return PhysicalState()
|
|
51
|
+
|
|
52
|
+
return ForbiddenState(self)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
from collections import UserList
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from cognite.neat._data_model.deployer.data_classes import DeploymentResult
|
|
8
|
+
from cognite.neat._issues import ConsistencyError, IssueList, ModelSyntaxError
|
|
9
|
+
from cognite.neat._state_machine import State
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class Change:
|
|
14
|
+
agent: str
|
|
15
|
+
activity: str
|
|
16
|
+
source_state: State
|
|
17
|
+
start: datetime
|
|
18
|
+
end: datetime
|
|
19
|
+
|
|
20
|
+
target_state: State | None = field(default=None)
|
|
21
|
+
source_entity: str | None = field(default="ExternalEntity")
|
|
22
|
+
target_entity: str | None = field(default="FailedEntity")
|
|
23
|
+
issues: IssueList | None = field(default=None)
|
|
24
|
+
errors: IssueList | None = field(default=None)
|
|
25
|
+
# for time being setting to Any, can be refined later
|
|
26
|
+
result: DeploymentResult | None = field(default=None)
|
|
27
|
+
description: str | None = field(default=None)
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def standardize_activity_name(activity: str, start: datetime, end: datetime) -> str:
|
|
31
|
+
"""Create standardized activity name"""
|
|
32
|
+
return f"{activity}_{start.timestamp()}-{end.timestamp()}"
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def successful(self) -> bool:
|
|
36
|
+
"""Check if change was successful"""
|
|
37
|
+
return not self.errors
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def error_count(self) -> int:
|
|
41
|
+
"""Get number of errors"""
|
|
42
|
+
return sum(
|
|
43
|
+
1
|
|
44
|
+
for issue in itertools.chain(self.issues or [], self.errors or [])
|
|
45
|
+
if isinstance(issue, ModelSyntaxError | ConsistencyError)
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
def as_mixpanel_event(self) -> dict[str, Any]:
|
|
49
|
+
"""Convert change to mixpanel event format"""
|
|
50
|
+
return {
|
|
51
|
+
"agent": self.agent,
|
|
52
|
+
"activity": self.activity,
|
|
53
|
+
"sourceEntity": self.source_entity,
|
|
54
|
+
"targetEntity": self.target_entity,
|
|
55
|
+
"sourceState": type(self.source_state).__name__,
|
|
56
|
+
"targetState": type(self.target_state).__name__ if self.target_state else "None",
|
|
57
|
+
"duration_ms": int((self.end - self.start).total_seconds() * 1000),
|
|
58
|
+
"successful": self.successful,
|
|
59
|
+
"issues": [issue.code or "<no code>" for issue in self.issues] if self.issues else [],
|
|
60
|
+
"errors": [error.code or "<no code>" for error in self.errors] if self.errors else [],
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class Provenance(UserList[Change]):
|
|
65
|
+
def __delitem__(self, *args: Any, **kwargs: Any) -> None:
|
|
66
|
+
raise TypeError("Cannot delete change from provenance")
|
|
67
|
+
|
|
68
|
+
def __setitem__(self, *args: Any, **kwargs: Any) -> None:
|
|
69
|
+
raise TypeError("Cannot modify change from provenance")
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def last_change(self) -> Change | None:
|
|
73
|
+
return self[-1] if len(self) > 0 else None
|
|
74
|
+
|
|
75
|
+
def can_agent_do_activity(self, activity: Any) -> bool:
|
|
76
|
+
"Check if activity can be performed based on provenance"
|
|
77
|
+
raise NotImplementedError("Not implemented yet")
|
|
78
|
+
|
|
79
|
+
def provenance_without_failures(self) -> "Provenance":
|
|
80
|
+
"""This method removes all the failed changes from the provenance list."""
|
|
81
|
+
raise NotImplementedError("Not implemented yet")
|
|
82
|
+
|
|
83
|
+
def last_physical_data_model_read(self) -> Change | None:
|
|
84
|
+
"""Get last physical data model read change"""
|
|
85
|
+
for change in reversed(self):
|
|
86
|
+
if change.activity.startswith("to_data_model"):
|
|
87
|
+
return change
|
|
88
|
+
return None
|