cognite-neat 0.107.0__tar.gz → 0.109.0__tar.gz
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-0.107.0 → cognite_neat-0.109.0}/PKG-INFO +1 -1
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_constants.py +35 -1
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/_shared.py +4 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_classic_cdf/_base.py +115 -14
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_classic_cdf/_classic.py +87 -6
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_classic_cdf/_relationships.py +48 -12
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_classic_cdf/_sequences.py +19 -1
- cognite_neat-0.109.0/cognite/neat/_graph/extractors/_dms.py +307 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_dms_graph.py +54 -4
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_mock_graph_generator.py +1 -1
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_rdf_file.py +3 -2
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/loaders/__init__.py +1 -3
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/loaders/_rdf2dms.py +20 -10
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/queries/_base.py +144 -84
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/queries/_construct.py +1 -1
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/transformers/__init__.py +3 -1
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/transformers/_base.py +4 -4
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/transformers/_classic_cdf.py +13 -13
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/transformers/_prune_graph.py +3 -3
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/transformers/_rdfpath.py +3 -4
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/transformers/_value_type.py +71 -13
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/errors/__init__.py +2 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/errors/_external.py +8 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/errors/_resources.py +1 -1
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/warnings/__init__.py +0 -2
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/warnings/_models.py +1 -1
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/warnings/_properties.py +0 -8
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/warnings/_resources.py +1 -1
- cognite_neat-0.109.0/cognite/neat/_rules/catalog/classic_model.xlsx +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/exporters/_rules2instance_template.py +3 -3
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/exporters/_rules2yaml.py +1 -1
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/__init__.py +3 -1
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_dtdl2rules/spec.py +1 -2
- cognite_neat-0.109.0/cognite/neat/_rules/importers/_rdf/__init__.py +5 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_rdf/_base.py +2 -2
- cognite_neat-0.109.0/cognite/neat/_rules/importers/_rdf/_inference2rules.py +578 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/_base_rules.py +22 -11
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/dms/_exporter.py +5 -4
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/dms/_rules.py +1 -8
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/dms/_rules_input.py +4 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/information/_rules_input.py +5 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/transformers/__init__.py +10 -3
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/transformers/_base.py +6 -1
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/transformers/_converters.py +530 -364
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/transformers/_mapping.py +4 -4
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/_base.py +100 -47
- cognite_neat-0.109.0/cognite/neat/_session/_create.py +133 -0
- cognite_neat-0.109.0/cognite/neat/_session/_drop.py +103 -0
- cognite_neat-0.109.0/cognite/neat/_session/_fix.py +28 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/_inspect.py +22 -7
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/_mapping.py +8 -8
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/_prepare.py +3 -247
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/_read.py +138 -17
- cognite_neat-0.109.0/cognite/neat/_session/_set.py +95 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/_show.py +16 -43
- cognite_neat-0.109.0/cognite/neat/_session/_state.py +100 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/_to.py +11 -4
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/_wizard.py +1 -1
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/exceptions.py +8 -1
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_store/_graph_store.py +301 -146
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_store/_provenance.py +36 -20
- cognite_neat-0.109.0/cognite/neat/_store/_rules_store.py +386 -0
- cognite_neat-0.109.0/cognite/neat/_store/exceptions.py +59 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/auth.py +5 -3
- cognite_neat-0.109.0/cognite/neat/_version.py +2 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/pyproject.toml +1 -1
- cognite_neat-0.107.0/cognite/neat/_graph/extractors/_dms.py +0 -192
- cognite_neat-0.107.0/cognite/neat/_rules/catalog/classic_model.xlsx +0 -0
- cognite_neat-0.107.0/cognite/neat/_rules/importers/_rdf/__init__.py +0 -5
- cognite_neat-0.107.0/cognite/neat/_rules/importers/_rdf/_inference2rules.py +0 -294
- cognite_neat-0.107.0/cognite/neat/_session/_drop.py +0 -45
- cognite_neat-0.107.0/cognite/neat/_session/_set.py +0 -46
- cognite_neat-0.107.0/cognite/neat/_session/_state.py +0 -99
- cognite_neat-0.107.0/cognite/neat/_store/_rules_store.py +0 -400
- cognite_neat-0.107.0/cognite/neat/_store/exceptions.py +0 -23
- cognite_neat-0.107.0/cognite/neat/_version.py +0 -2
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/LICENSE +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/README.md +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_client/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_client/_api/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_client/_api/data_modeling_loaders.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_client/_api/schema.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_client/_api_client.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_client/data_classes/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_client/data_classes/data_modeling.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_client/data_classes/neat_sequence.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_client/data_classes/schema.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_client/testing.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_config.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/_tracking/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/_tracking/base.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/_tracking/log.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/examples/Knowledge-Graph-Nordic44-dirty.xml +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/examples/Knowledge-Graph-Nordic44.xml +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/examples/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/examples/skos-capturing-sheet-wind-topics.xlsx +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_base.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_classic_cdf/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_classic_cdf/_assets.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_classic_cdf/_data_sets.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_classic_cdf/_events.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_classic_cdf/_files.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_classic_cdf/_labels.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_classic_cdf/_timeseries.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_dexpi.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_iodd.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/loaders/_base.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/queries/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/queries/_shared.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/transformers/_iodd.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/_base.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/errors/_general.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/errors/_properties.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/errors/_workflow.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/formatters.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/warnings/_external.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/warnings/_general.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_issues/warnings/user_modeling.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/_constants.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/_shared.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/analysis/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/analysis/_base.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/analysis/_dms.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/analysis/_information.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/catalog/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/catalog/hello_world_pump.xlsx +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/catalog/info-rules-imf.xlsx +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/exporters/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/exporters/_base.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/exporters/_rules2dms.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/exporters/_rules2excel.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/exporters/_rules2ontology.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/exporters/_validation.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_base.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_dms2rules.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_dtdl2rules/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_dtdl2rules/_unit_lookup.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_dtdl2rules/dtdl_converter.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_dtdl2rules/dtdl_importer.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_rdf/_imf2rules.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_rdf/_owl2rules.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_rdf/_shared.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_spreadsheet2rules.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/importers/_yaml2rules.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/_base_input.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/_rdfpath.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/_types.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/data_types.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/dms/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/dms/_validation.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/entities/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/entities/_constants.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/entities/_loaders.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/entities/_multi_value.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/entities/_single_value.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/entities/_types.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/entities/_wrapped.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/information/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/information/_rules.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/information/_validation.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/mapping/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/mapping/_classic2core.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/models/mapping/_classic2core.yaml +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_rules/transformers/_verification.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/_collector.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/engine/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/engine/_import.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/engine/_interface.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_session/engine/_load.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_shared.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_store/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/auxiliary.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/collection_.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/graph_transformations_report.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/io_.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/rdf_.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/reader/__init__.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/reader/_base.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/spreadsheet.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/text.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/time_.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/upload.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_utils/xml_.py +0 -0
- {cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/py.typed +0 -0
|
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
|
|
|
5
5
|
from cognite.client import data_modeling as dm
|
|
6
6
|
from cognite.client.data_classes.data_modeling.ids import DataModelId
|
|
7
7
|
from rdflib import DC, DCTERMS, FOAF, OWL, RDF, RDFS, SH, SKOS, XSD, Namespace, URIRef
|
|
8
|
+
from rdflib.namespace import DefinedNamespace
|
|
8
9
|
|
|
9
10
|
from cognite import neat
|
|
10
11
|
|
|
@@ -73,10 +74,22 @@ DEFAULT_NAMESPACE = Namespace("http://purl.org/cognite/neat/")
|
|
|
73
74
|
CDF_NAMESPACE = Namespace("https://cognitedata.com/")
|
|
74
75
|
DEFAULT_BASE_URI = URIRef(DEFAULT_NAMESPACE)
|
|
75
76
|
CLASSIC_CDF_NAMESPACE = Namespace("http://purl.org/cognite/cdf-classic#")
|
|
76
|
-
UNKNOWN_TYPE = DEFAULT_NAMESPACE.UnknownType
|
|
77
77
|
XML_SCHEMA_NAMESPACE = Namespace("http://www.w3.org/2001/XMLSchema#")
|
|
78
78
|
|
|
79
79
|
|
|
80
|
+
class NEAT(DefinedNamespace):
|
|
81
|
+
"""
|
|
82
|
+
NEAT internal data model used for internal purposes of the NEAT library
|
|
83
|
+
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
_fail = True
|
|
87
|
+
_NS = Namespace("http://thisisneat.io/internal/")
|
|
88
|
+
|
|
89
|
+
UnknownType: URIRef # Unknown type used to express that the type of a subject is unknown
|
|
90
|
+
EmptyType: URIRef # Empty type used to express that the type of a subject is empty
|
|
91
|
+
|
|
92
|
+
|
|
80
93
|
def get_default_prefixes_and_namespaces() -> dict[str, Namespace]:
|
|
81
94
|
return {
|
|
82
95
|
"owl": OWL._NS,
|
|
@@ -154,3 +167,24 @@ READONLY_PROPERTIES_BY_CONTAINER: Mapping[dm.ContainerId, frozenset[str]] = {
|
|
|
154
167
|
|
|
155
168
|
def is_readonly_property(container: dm.ContainerId, property_: str) -> bool:
|
|
156
169
|
return container in READONLY_PROPERTIES_BY_CONTAINER and property_ in READONLY_PROPERTIES_BY_CONTAINER[container]
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
DMS_RESERVED_PROPERTIES = frozenset(
|
|
173
|
+
{
|
|
174
|
+
"createdTime",
|
|
175
|
+
"deletedTime",
|
|
176
|
+
"edge_id",
|
|
177
|
+
"extensions",
|
|
178
|
+
"externalId",
|
|
179
|
+
"lastUpdatedTime",
|
|
180
|
+
"node_id",
|
|
181
|
+
"project_id",
|
|
182
|
+
"property_group",
|
|
183
|
+
"seq",
|
|
184
|
+
"space",
|
|
185
|
+
"version",
|
|
186
|
+
"tg_table_name",
|
|
187
|
+
"startNode",
|
|
188
|
+
"endNode",
|
|
189
|
+
}
|
|
190
|
+
)
|
|
@@ -7,6 +7,10 @@ MIMETypes: TypeAlias = Literal[
|
|
|
7
7
|
RDFTypes: TypeAlias = Literal["xml", "rdf", "owl", "n3", "ttl", "turtle", "nt", "nq", "nquads", "trig"]
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
def quad_formats() -> list[str]:
|
|
11
|
+
return ["trig", "nquads", "nq", "nt"]
|
|
12
|
+
|
|
13
|
+
|
|
10
14
|
def rdflib_to_oxi_type(rdflib_format: str) -> str | None:
|
|
11
15
|
"""Convert an RDFlib format to a MIME type.
|
|
12
16
|
|
{cognite_neat-0.107.0 → cognite_neat-0.109.0}/cognite/neat/_graph/extractors/_classic_cdf/_base.py
RENAMED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import re
|
|
3
3
|
import sys
|
|
4
|
+
import typing
|
|
5
|
+
import urllib.parse
|
|
4
6
|
import warnings
|
|
5
7
|
from abc import ABC, abstractmethod
|
|
6
8
|
from collections.abc import Callable, Iterable, Sequence, Set
|
|
@@ -16,7 +18,8 @@ from rdflib import RDF, XSD, Literal, Namespace, URIRef
|
|
|
16
18
|
|
|
17
19
|
from cognite.neat._constants import DEFAULT_NAMESPACE
|
|
18
20
|
from cognite.neat._graph.extractors._base import BaseExtractor
|
|
19
|
-
from cognite.neat._issues.
|
|
21
|
+
from cognite.neat._issues.errors import NeatValueError
|
|
22
|
+
from cognite.neat._issues.warnings import CDFAuthWarning, NeatValueWarning
|
|
20
23
|
from cognite.neat._shared import Triple
|
|
21
24
|
from cognite.neat._utils.auxiliary import string_to_ideal_type
|
|
22
25
|
from cognite.neat._utils.collection_ import iterate_progress_bar_if_above_config_threshold
|
|
@@ -72,6 +75,8 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
|
|
|
72
75
|
camel_case (bool, optional): Whether to use camelCase instead of snake_case for property names.
|
|
73
76
|
Defaults to True.
|
|
74
77
|
as_write (bool, optional): Whether to use the write/request format of the items. Defaults to False.
|
|
78
|
+
prefix (str, optional): A prefix to add to the rdf type. Defaults to None.
|
|
79
|
+
identifier (Literal["id", "externalId"], optional): The identifier to use. Defaults to "id".
|
|
75
80
|
"""
|
|
76
81
|
|
|
77
82
|
_default_rdf_type: str
|
|
@@ -90,6 +95,7 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
|
|
|
90
95
|
camel_case: bool = True,
|
|
91
96
|
as_write: bool = False,
|
|
92
97
|
prefix: str | None = None,
|
|
98
|
+
identifier: typing.Literal["id", "externalId"] = "id",
|
|
93
99
|
):
|
|
94
100
|
self.namespace = namespace or DEFAULT_NAMESPACE
|
|
95
101
|
self.items = items
|
|
@@ -101,9 +107,18 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
|
|
|
101
107
|
self.camel_case = camel_case
|
|
102
108
|
self.as_write = as_write
|
|
103
109
|
self.prefix = prefix
|
|
110
|
+
self.identifier = identifier
|
|
111
|
+
# If identifier=externalId, we need to keep track of the external ids
|
|
112
|
+
# and use them in linking of Files, Sequences, TimeSeries, and Events.
|
|
113
|
+
self.asset_external_ids_by_id: dict[int, str] = {}
|
|
114
|
+
self.lookup_dataset_external_id: Callable[[int], str] | None = None
|
|
115
|
+
# Used by the ClassicGraphExtractor to log URIRefs
|
|
116
|
+
self._log_urirefs = False
|
|
117
|
+
self._uriref_by_external_id: dict[str, URIRef] = {}
|
|
104
118
|
|
|
105
119
|
def extract(self) -> Iterable[Triple]:
|
|
106
120
|
"""Extracts an asset with the given asset_id."""
|
|
121
|
+
from ._assets import AssetsExtractor
|
|
107
122
|
|
|
108
123
|
if self.total is not None and self.total > 0:
|
|
109
124
|
to_iterate = iterate_progress_bar_if_above_config_threshold(
|
|
@@ -111,21 +126,40 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
|
|
|
111
126
|
)
|
|
112
127
|
else:
|
|
113
128
|
to_iterate = self.items
|
|
129
|
+
if self.identifier == "externalId" and isinstance(self, AssetsExtractor):
|
|
130
|
+
to_iterate = self._store_asset_external_ids(to_iterate) # type: ignore[attr-defined]
|
|
131
|
+
|
|
114
132
|
for no, asset in enumerate(to_iterate):
|
|
115
133
|
yield from self._item2triples(asset)
|
|
116
134
|
if self.limit and no >= self.limit:
|
|
117
135
|
break
|
|
118
136
|
|
|
137
|
+
def _store_asset_external_ids(self, items: Iterable[T_CogniteResource]) -> Iterable[T_CogniteResource]:
|
|
138
|
+
for item in items:
|
|
139
|
+
if hasattr(item, "id") and hasattr(item, "external_id"):
|
|
140
|
+
self.asset_external_ids_by_id[item.id] = item.external_id
|
|
141
|
+
yield item
|
|
142
|
+
|
|
119
143
|
def _item2triples(self, item: T_CogniteResource) -> list[Triple]:
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
144
|
+
if self.identifier == "id":
|
|
145
|
+
id_value: str | None
|
|
146
|
+
if hasattr(item, "id"):
|
|
147
|
+
id_value = str(item.id)
|
|
148
|
+
else:
|
|
149
|
+
id_value = self._fallback_id(item)
|
|
150
|
+
if id_value is None:
|
|
151
|
+
return []
|
|
152
|
+
id_suffix = id_value
|
|
153
|
+
elif self.identifier == "externalId":
|
|
154
|
+
if not hasattr(item, "external_id"):
|
|
155
|
+
return []
|
|
156
|
+
id_suffix = self._external_id_as_uri_suffix(item.external_id)
|
|
123
157
|
else:
|
|
124
|
-
|
|
125
|
-
if id_value is None:
|
|
126
|
-
return []
|
|
158
|
+
raise NeatValueError(f"Unknown identifier {self.identifier}")
|
|
127
159
|
|
|
128
|
-
id_ = self.namespace[f"{self._instance_id_prefix}{
|
|
160
|
+
id_ = self.namespace[f"{self._instance_id_prefix}{id_suffix}"]
|
|
161
|
+
if self._log_urirefs and hasattr(item, "external_id"):
|
|
162
|
+
self._uriref_by_external_id[item.external_id] = id_
|
|
129
163
|
|
|
130
164
|
type_ = self._get_rdf_type(item)
|
|
131
165
|
|
|
@@ -154,10 +188,25 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
|
|
|
154
188
|
"""This can be overridden to handle special cases for the item."""
|
|
155
189
|
return []
|
|
156
190
|
|
|
191
|
+
@classmethod
|
|
192
|
+
def _external_id_as_uri_suffix(cls, external_id: str | None) -> str:
|
|
193
|
+
if external_id == "":
|
|
194
|
+
warnings.warn(NeatValueWarning(f"Empty external id in {cls._default_rdf_type}"), stacklevel=2)
|
|
195
|
+
return "empty"
|
|
196
|
+
elif external_id == "\x00":
|
|
197
|
+
warnings.warn(NeatValueWarning(f"Null external id in {cls._default_rdf_type}"), stacklevel=2)
|
|
198
|
+
return "null"
|
|
199
|
+
elif external_id is None:
|
|
200
|
+
warnings.warn(NeatValueWarning(f"None external id in {cls._default_rdf_type}"), stacklevel=2)
|
|
201
|
+
return "None"
|
|
202
|
+
# The external ID needs to pass the ^[^\\x00]{1,256}$ regex for the DMS API.
|
|
203
|
+
# In addition, neat internals requires the external ID to be a valid URI.
|
|
204
|
+
return urllib.parse.quote(external_id)
|
|
205
|
+
|
|
157
206
|
def _fallback_id(self, item: T_CogniteResource) -> str | None:
|
|
158
207
|
raise AttributeError(
|
|
159
208
|
f"Item of type {type(item)} does not have an id attribute. "
|
|
160
|
-
|
|
209
|
+
"Please implement the _fallback_id method in the extractor."
|
|
161
210
|
)
|
|
162
211
|
|
|
163
212
|
def _metadata_to_triples(self, id_: URIRef, metadata: dict[str, str]) -> Iterable[Triple]:
|
|
@@ -181,10 +230,29 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
|
|
|
181
230
|
return self._SPACE_PATTERN.sub("_", type_)
|
|
182
231
|
|
|
183
232
|
def _as_object(self, raw: Any, key: str) -> Literal | URIRef:
|
|
233
|
+
"""Return properly formatted object part of s-p-o triple"""
|
|
184
234
|
if key in {"data_set_id", "dataSetId"}:
|
|
185
|
-
|
|
235
|
+
if self.identifier == "externalId" and self.lookup_dataset_external_id:
|
|
236
|
+
try:
|
|
237
|
+
data_set_external_id = self.lookup_dataset_external_id(raw)
|
|
238
|
+
except KeyError:
|
|
239
|
+
return Literal("Unknown data set")
|
|
240
|
+
else:
|
|
241
|
+
return self.namespace[
|
|
242
|
+
f"{InstanceIdPrefix.data_set}{self._external_id_as_uri_suffix(data_set_external_id)}"
|
|
243
|
+
]
|
|
244
|
+
else:
|
|
245
|
+
return self.namespace[f"{InstanceIdPrefix.data_set}{raw}"]
|
|
186
246
|
elif key in {"assetId", "asset_id", "assetIds", "asset_ids", "parentId", "rootId", "parent_id", "root_id"}:
|
|
187
|
-
|
|
247
|
+
if self.identifier == "id":
|
|
248
|
+
return self.namespace[f"{InstanceIdPrefix.asset}{raw}"]
|
|
249
|
+
else:
|
|
250
|
+
try:
|
|
251
|
+
asset_external_id = self._external_id_as_uri_suffix(self.asset_external_ids_by_id[raw])
|
|
252
|
+
except KeyError:
|
|
253
|
+
return Literal("Unknown asset", datatype=XSD.string)
|
|
254
|
+
else:
|
|
255
|
+
return self.namespace[f"{InstanceIdPrefix.asset}{asset_external_id}"]
|
|
188
256
|
elif key in {
|
|
189
257
|
"startTime",
|
|
190
258
|
"endTime",
|
|
@@ -223,10 +291,21 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
|
|
|
223
291
|
camel_case: bool = True,
|
|
224
292
|
as_write: bool = False,
|
|
225
293
|
prefix: str | None = None,
|
|
294
|
+
identifier: typing.Literal["id", "externalId"] = "id",
|
|
226
295
|
):
|
|
227
296
|
total, items = cls._handle_no_access(lambda: cls._from_dataset(client, data_set_external_id))
|
|
228
297
|
return cls(
|
|
229
|
-
items,
|
|
298
|
+
items,
|
|
299
|
+
namespace,
|
|
300
|
+
to_type,
|
|
301
|
+
total,
|
|
302
|
+
limit,
|
|
303
|
+
unpack_metadata,
|
|
304
|
+
skip_metadata_values,
|
|
305
|
+
camel_case,
|
|
306
|
+
as_write,
|
|
307
|
+
prefix,
|
|
308
|
+
identifier,
|
|
230
309
|
)
|
|
231
310
|
|
|
232
311
|
@classmethod
|
|
@@ -249,10 +328,21 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
|
|
|
249
328
|
camel_case: bool = True,
|
|
250
329
|
as_write: bool = False,
|
|
251
330
|
prefix: str | None = None,
|
|
331
|
+
identifier: typing.Literal["id", "externalId"] = "id",
|
|
252
332
|
):
|
|
253
333
|
total, items = cls._handle_no_access(lambda: cls._from_hierarchy(client, root_asset_external_id))
|
|
254
334
|
return cls(
|
|
255
|
-
items,
|
|
335
|
+
items,
|
|
336
|
+
namespace,
|
|
337
|
+
to_type,
|
|
338
|
+
total,
|
|
339
|
+
limit,
|
|
340
|
+
unpack_metadata,
|
|
341
|
+
skip_metadata_values,
|
|
342
|
+
camel_case,
|
|
343
|
+
as_write,
|
|
344
|
+
prefix,
|
|
345
|
+
identifier,
|
|
256
346
|
)
|
|
257
347
|
|
|
258
348
|
@classmethod
|
|
@@ -274,10 +364,21 @@ class ClassicCDFBaseExtractor(BaseExtractor, ABC, Generic[T_CogniteResource]):
|
|
|
274
364
|
camel_case: bool = True,
|
|
275
365
|
as_write: bool = False,
|
|
276
366
|
prefix: str | None = None,
|
|
367
|
+
identifier: typing.Literal["id", "externalId"] = "id",
|
|
277
368
|
):
|
|
278
369
|
total, items = cls._from_file(file_path)
|
|
279
370
|
return cls(
|
|
280
|
-
items,
|
|
371
|
+
items,
|
|
372
|
+
namespace,
|
|
373
|
+
to_type,
|
|
374
|
+
total,
|
|
375
|
+
limit,
|
|
376
|
+
unpack_metadata,
|
|
377
|
+
skip_metadata_values,
|
|
378
|
+
camel_case,
|
|
379
|
+
as_write,
|
|
380
|
+
prefix,
|
|
381
|
+
identifier,
|
|
281
382
|
)
|
|
282
383
|
|
|
283
384
|
@classmethod
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
import urllib.parse
|
|
1
3
|
import warnings
|
|
2
4
|
from collections import defaultdict
|
|
3
5
|
from collections.abc import Iterable, Sequence
|
|
@@ -9,8 +11,8 @@ from rdflib import Namespace, URIRef
|
|
|
9
11
|
|
|
10
12
|
from cognite.neat._constants import CLASSIC_CDF_NAMESPACE, DEFAULT_NAMESPACE, get_default_prefixes_and_namespaces
|
|
11
13
|
from cognite.neat._graph.extractors._base import KnowledgeGraphExtractor
|
|
12
|
-
from cognite.neat._issues.errors import NeatValueError
|
|
13
|
-
from cognite.neat._issues.warnings import CDFAuthWarning
|
|
14
|
+
from cognite.neat._issues.errors import NeatValueError, ResourceNotFoundError
|
|
15
|
+
from cognite.neat._issues.warnings import CDFAuthWarning, NeatValueWarning
|
|
14
16
|
from cognite.neat._rules._shared import ReadRules
|
|
15
17
|
from cognite.neat._rules.catalog import classic_model
|
|
16
18
|
from cognite.neat._rules.models import InformationInputRules, InformationRules
|
|
@@ -101,6 +103,7 @@ class ClassicGraphExtractor(KnowledgeGraphExtractor):
|
|
|
101
103
|
namespace: Namespace | None = None,
|
|
102
104
|
limit_per_type: int | None = None,
|
|
103
105
|
prefix: str | None = None,
|
|
106
|
+
identifier: typing.Literal["id", "externalId"] = "id",
|
|
104
107
|
):
|
|
105
108
|
self._client = client
|
|
106
109
|
if sum([bool(data_set_external_id), bool(root_asset_external_id)]) != 1:
|
|
@@ -115,16 +118,23 @@ class ClassicGraphExtractor(KnowledgeGraphExtractor):
|
|
|
115
118
|
camel_case=True,
|
|
116
119
|
limit=limit_per_type,
|
|
117
120
|
prefix=prefix,
|
|
121
|
+
identifier=identifier,
|
|
118
122
|
)
|
|
123
|
+
self._identifier = identifier
|
|
119
124
|
self._prefix = prefix
|
|
120
125
|
self._limit_per_type = limit_per_type
|
|
121
126
|
|
|
127
|
+
self._uris_by_external_id_by_type: dict[InstanceIdPrefix, dict[str, URIRef]] = defaultdict(dict)
|
|
122
128
|
self._source_external_ids_by_type: dict[InstanceIdPrefix, set[str]] = defaultdict(set)
|
|
123
129
|
self._target_external_ids_by_type: dict[InstanceIdPrefix, set[str]] = defaultdict(set)
|
|
130
|
+
self._relationship_subject_predicate_type_external_id: list[tuple[URIRef, URIRef, str, str]] = []
|
|
124
131
|
self._labels: set[str] = set()
|
|
125
132
|
self._data_set_ids: set[int] = set()
|
|
133
|
+
self._data_set_external_ids: set[str] = set()
|
|
126
134
|
self._extracted_labels = False
|
|
127
135
|
self._extracted_data_sets = False
|
|
136
|
+
self._asset_external_ids_by_id: dict[int, str] = {}
|
|
137
|
+
self._dataset_external_ids_by_id: dict[int, str] = {}
|
|
128
138
|
|
|
129
139
|
def _get_activity_names(self) -> list[str]:
|
|
130
140
|
activities = [data_access_object.extractor_cls.__name__ for data_access_object in self._classic_node_types] + [
|
|
@@ -138,12 +148,17 @@ class ClassicGraphExtractor(KnowledgeGraphExtractor):
|
|
|
138
148
|
|
|
139
149
|
def extract(self) -> Iterable[Triple]:
|
|
140
150
|
"""Extracts all classic CDF Resources."""
|
|
151
|
+
self._validate_exists()
|
|
152
|
+
|
|
141
153
|
yield from self._extract_core_start_nodes()
|
|
142
154
|
|
|
143
155
|
yield from self._extract_start_node_relationships()
|
|
144
156
|
|
|
145
157
|
yield from self._extract_core_end_nodes()
|
|
146
158
|
|
|
159
|
+
if self._identifier == "id":
|
|
160
|
+
yield from self._extract_relationship_target_triples()
|
|
161
|
+
|
|
147
162
|
try:
|
|
148
163
|
yield from self._extract_labels()
|
|
149
164
|
except CogniteAPIError as e:
|
|
@@ -209,7 +224,17 @@ class ClassicGraphExtractor(KnowledgeGraphExtractor):
|
|
|
209
224
|
else:
|
|
210
225
|
resource = "unknown"
|
|
211
226
|
external_id = "unknown"
|
|
212
|
-
return DEFAULT_NAMESPACE[f"{self._client.config.project}/{resource}/{external_id}"]
|
|
227
|
+
return DEFAULT_NAMESPACE[f"{self._client.config.project}/{resource}/{urllib.parse.quote(external_id)}"]
|
|
228
|
+
|
|
229
|
+
def _validate_exists(self) -> None:
|
|
230
|
+
if self._data_set_external_id:
|
|
231
|
+
if self._client.data_sets.retrieve(external_id=self._data_set_external_id) is None:
|
|
232
|
+
raise ResourceNotFoundError(self._data_set_external_id, "data set")
|
|
233
|
+
elif self._root_asset_external_id:
|
|
234
|
+
if self._client.assets.retrieve(external_id=self._root_asset_external_id) is None:
|
|
235
|
+
raise ResourceNotFoundError(self._root_asset_external_id, "root asset")
|
|
236
|
+
else:
|
|
237
|
+
raise ValueError("Exactly one of data_set_external_id or root_asset_external_id must be set.")
|
|
213
238
|
|
|
214
239
|
def _extract_core_start_nodes(self):
|
|
215
240
|
for core_node in self._classic_node_types:
|
|
@@ -224,8 +249,20 @@ class ClassicGraphExtractor(KnowledgeGraphExtractor):
|
|
|
224
249
|
else:
|
|
225
250
|
raise ValueError("Exactly one of data_set_external_id or root_asset_external_id must be set.")
|
|
226
251
|
|
|
252
|
+
if self._identifier == "externalId":
|
|
253
|
+
if isinstance(extractor, AssetsExtractor):
|
|
254
|
+
self._asset_external_ids_by_id = extractor.asset_external_ids_by_id
|
|
255
|
+
else:
|
|
256
|
+
extractor.asset_external_ids_by_id = self._asset_external_ids_by_id
|
|
257
|
+
extractor.lookup_dataset_external_id = self._lookup_dataset
|
|
258
|
+
elif self._identifier == "id":
|
|
259
|
+
extractor._log_urirefs = True
|
|
260
|
+
|
|
227
261
|
yield from self._extract_with_logging_label_dataset(extractor, core_node.resource_type)
|
|
228
262
|
|
|
263
|
+
if self._identifier == "id":
|
|
264
|
+
self._uris_by_external_id_by_type[core_node.resource_type].update(extractor._uriref_by_external_id)
|
|
265
|
+
|
|
229
266
|
def _extract_start_node_relationships(self):
|
|
230
267
|
for start_resource_type, source_external_ids in self._source_external_ids_by_type.items():
|
|
231
268
|
start_type = start_resource_type.removesuffix("_")
|
|
@@ -236,6 +273,8 @@ class ClassicGraphExtractor(KnowledgeGraphExtractor):
|
|
|
236
273
|
extractor = RelationshipsExtractor(relationship_iterator, **self._extractor_args)
|
|
237
274
|
# This is a private attribute, but we need to set it to log the target nodes.
|
|
238
275
|
extractor._log_target_nodes = True
|
|
276
|
+
if self._identifier == "id":
|
|
277
|
+
extractor._uri_by_external_id_by_by_type = self._uris_by_external_id_by_type
|
|
239
278
|
|
|
240
279
|
yield from extractor.extract()
|
|
241
280
|
|
|
@@ -254,6 +293,11 @@ class ClassicGraphExtractor(KnowledgeGraphExtractor):
|
|
|
254
293
|
):
|
|
255
294
|
self._target_external_ids_by_type[end_type].add(external_id)
|
|
256
295
|
|
|
296
|
+
if self._identifier == "id":
|
|
297
|
+
# We need to store all future target triples which we will lookup after fetching
|
|
298
|
+
# the target nodes.
|
|
299
|
+
self._relationship_subject_predicate_type_external_id.extend(extractor._target_triples)
|
|
300
|
+
|
|
257
301
|
def _extract_core_end_nodes(self):
|
|
258
302
|
for core_node in self._classic_node_types:
|
|
259
303
|
target_external_ids = self._target_external_ids_by_type[core_node.resource_type]
|
|
@@ -264,8 +308,26 @@ class ClassicGraphExtractor(KnowledgeGraphExtractor):
|
|
|
264
308
|
):
|
|
265
309
|
resource_iterator = api.retrieve_multiple(external_ids=list(chunk), ignore_unknown_ids=True)
|
|
266
310
|
extractor = core_node.extractor_cls(resource_iterator, **self._extractor_args)
|
|
311
|
+
|
|
312
|
+
extractor.asset_external_ids_by_id = self._asset_external_ids_by_id
|
|
313
|
+
extractor.lookup_dataset_external_id = self._lookup_dataset
|
|
314
|
+
if self._identifier == "id":
|
|
315
|
+
extractor._log_urirefs = True
|
|
316
|
+
|
|
267
317
|
yield from self._extract_with_logging_label_dataset(extractor)
|
|
268
318
|
|
|
319
|
+
if self._identifier == "id":
|
|
320
|
+
self._uris_by_external_id_by_type[core_node.resource_type].update(extractor._uriref_by_external_id)
|
|
321
|
+
|
|
322
|
+
def _extract_relationship_target_triples(self):
|
|
323
|
+
for id_, predicate, type_, external_id in self._relationship_subject_predicate_type_external_id:
|
|
324
|
+
try:
|
|
325
|
+
object_uri = self._uris_by_external_id_by_type[InstanceIdPrefix.from_str(type_)][external_id]
|
|
326
|
+
except KeyError:
|
|
327
|
+
warnings.warn(NeatValueWarning(f"Missing externalId {external_id} for {type_}"), stacklevel=2)
|
|
328
|
+
else:
|
|
329
|
+
yield id_, predicate, object_uri
|
|
330
|
+
|
|
269
331
|
def _extract_labels(self):
|
|
270
332
|
for chunk in self._chunk(list(self._labels), description="Extracting labels"):
|
|
271
333
|
label_iterator = self._client.labels.retrieve(external_id=list(chunk), ignore_unknown_ids=True)
|
|
@@ -275,6 +337,11 @@ class ClassicGraphExtractor(KnowledgeGraphExtractor):
|
|
|
275
337
|
for chunk in self._chunk(list(self._data_set_ids), description="Extracting data sets"):
|
|
276
338
|
data_set_iterator = self._client.data_sets.retrieve_multiple(ids=list(chunk), ignore_unknown_ids=True)
|
|
277
339
|
yield from DataSetExtractor(data_set_iterator, **self._extractor_args).extract()
|
|
340
|
+
for chunk in self._chunk(list(self._data_set_external_ids), description="Extracting data sets"):
|
|
341
|
+
data_set_iterator = self._client.data_sets.retrieve_multiple(
|
|
342
|
+
external_ids=list(chunk), ignore_unknown_ids=True
|
|
343
|
+
)
|
|
344
|
+
yield from DataSetExtractor(data_set_iterator, **self._extractor_args).extract()
|
|
278
345
|
|
|
279
346
|
def _extract_with_logging_label_dataset(
|
|
280
347
|
self, extractor: ClassicCDFBaseExtractor, resource_type: InstanceIdPrefix | None = None
|
|
@@ -285,9 +352,11 @@ class ClassicGraphExtractor(KnowledgeGraphExtractor):
|
|
|
285
352
|
elif triple[1] == self._namespace.labels:
|
|
286
353
|
self._labels.add(remove_namespace_from_uri(triple[2]).removeprefix(InstanceIdPrefix.label))
|
|
287
354
|
elif triple[1] == self._namespace.dataSetId:
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
355
|
+
identifier = remove_namespace_from_uri(triple[2]).removeprefix(InstanceIdPrefix.data_set)
|
|
356
|
+
try:
|
|
357
|
+
self._data_set_ids.add(int(identifier))
|
|
358
|
+
except ValueError:
|
|
359
|
+
self._data_set_external_ids.add(identifier)
|
|
291
360
|
yield triple
|
|
292
361
|
|
|
293
362
|
@staticmethod
|
|
@@ -297,3 +366,15 @@ class ClassicGraphExtractor(KnowledgeGraphExtractor):
|
|
|
297
366
|
return iterate_progress_bar(to_iterate, (len(items) // 1_000) + 1, description)
|
|
298
367
|
else:
|
|
299
368
|
return to_iterate
|
|
369
|
+
|
|
370
|
+
def _lookup_dataset(self, dataset_id: int) -> str:
|
|
371
|
+
if dataset_id not in self._dataset_external_ids_by_id:
|
|
372
|
+
try:
|
|
373
|
+
if (dataset := self._client.data_sets.retrieve(id=dataset_id)) and dataset.external_id:
|
|
374
|
+
self._dataset_external_ids_by_id[dataset_id] = dataset.external_id
|
|
375
|
+
else:
|
|
376
|
+
raise KeyError(f"Could not find dataset with id {dataset_id}.")
|
|
377
|
+
except CogniteAPIError as e:
|
|
378
|
+
warnings.warn(CDFAuthWarning("lookup dataset", str(e)), stacklevel=2)
|
|
379
|
+
return f"{InstanceIdPrefix.data_set}{dataset_id}"
|
|
380
|
+
return self._dataset_external_ids_by_id[dataset_id]
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
import warnings
|
|
1
3
|
from collections import defaultdict
|
|
2
4
|
from collections.abc import Callable, Iterable, Set
|
|
3
5
|
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
4
7
|
|
|
5
8
|
from cognite.client import CogniteClient
|
|
6
9
|
from cognite.client.data_classes import Relationship, RelationshipList
|
|
7
|
-
from rdflib import Namespace
|
|
10
|
+
from rdflib import Namespace, URIRef
|
|
8
11
|
|
|
12
|
+
from cognite.neat._issues.warnings import NeatValueWarning
|
|
13
|
+
from cognite.neat._shared import Triple
|
|
9
14
|
from cognite.neat._utils.auxiliary import create_sha256_hash
|
|
10
15
|
|
|
11
16
|
from ._base import DEFAULT_SKIP_METADATA_VALUES, ClassicCDFBaseExtractor, InstanceIdPrefix, T_CogniteResource
|
|
@@ -29,9 +34,17 @@ class RelationshipsExtractor(ClassicCDFBaseExtractor[Relationship]):
|
|
|
29
34
|
camel_case: bool = True,
|
|
30
35
|
as_write: bool = False,
|
|
31
36
|
prefix: str | None = None,
|
|
37
|
+
identifier: typing.Literal["id", "externalId"] = "id",
|
|
32
38
|
):
|
|
39
|
+
# This is used by the ClassicExtractor to log the target nodes, such
|
|
40
|
+
# that it can extract them.
|
|
41
|
+
# It is private to avoid exposing it to the user.
|
|
42
|
+
self._target_external_ids_by_type: dict[InstanceIdPrefix, set[str]] = defaultdict(set)
|
|
43
|
+
self._log_target_nodes = False
|
|
44
|
+
# Ensure that this becomes an iterator, even if it is a list.
|
|
45
|
+
to_iterate = (self._log_target_nodes_if_set(item) for item in items)
|
|
33
46
|
super().__init__(
|
|
34
|
-
|
|
47
|
+
to_iterate,
|
|
35
48
|
namespace=namespace,
|
|
36
49
|
to_type=to_type,
|
|
37
50
|
total=total,
|
|
@@ -41,12 +54,39 @@ class RelationshipsExtractor(ClassicCDFBaseExtractor[Relationship]):
|
|
|
41
54
|
camel_case=camel_case,
|
|
42
55
|
as_write=as_write,
|
|
43
56
|
prefix=prefix,
|
|
57
|
+
identifier=identifier,
|
|
44
58
|
)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
self.
|
|
59
|
+
self._uri_by_external_id_by_by_type: dict[InstanceIdPrefix, dict[str, URIRef]] = defaultdict(dict)
|
|
60
|
+
self._target_triples: list[tuple[URIRef, URIRef, str, str]] = []
|
|
61
|
+
|
|
62
|
+
def _log_target_nodes_if_set(self, item: Relationship) -> Relationship:
|
|
63
|
+
if not self._log_target_nodes:
|
|
64
|
+
return item
|
|
65
|
+
if item.target_type and item.target_external_id:
|
|
66
|
+
self._target_external_ids_by_type[InstanceIdPrefix.from_str(item.target_type)].add(item.target_external_id)
|
|
67
|
+
return item
|
|
68
|
+
|
|
69
|
+
def _item2triples_special_cases(self, id_: URIRef, dumped: dict[str, Any]) -> list[Triple]:
|
|
70
|
+
if self.identifier == "externalId":
|
|
71
|
+
return []
|
|
72
|
+
triples: list[Triple] = []
|
|
73
|
+
if (source_external_id := dumped.pop("sourceExternalId")) and "sourceType" in dumped:
|
|
74
|
+
source_type = dumped["sourceType"]
|
|
75
|
+
try:
|
|
76
|
+
source_uri = self._uri_by_external_id_by_by_type[InstanceIdPrefix.from_str(source_type)][
|
|
77
|
+
source_external_id
|
|
78
|
+
]
|
|
79
|
+
except KeyError:
|
|
80
|
+
warnings.warn(
|
|
81
|
+
NeatValueWarning(f"Missing externalId {source_external_id} for {source_type}"), stacklevel=2
|
|
82
|
+
)
|
|
83
|
+
else:
|
|
84
|
+
triples.append((id_, self.namespace["sourceExternalId"], source_uri))
|
|
85
|
+
if (target_external_id := dumped.pop("targetExternalId")) and "targetType" in dumped:
|
|
86
|
+
target_type = dumped["targetType"]
|
|
87
|
+
# We do not yet have the target nodes, so we log them for later extraction.
|
|
88
|
+
self._target_triples.append((id_, self.namespace["targetExternalId"], target_type, target_external_id))
|
|
89
|
+
return triples
|
|
50
90
|
|
|
51
91
|
@classmethod
|
|
52
92
|
def _from_dataset(
|
|
@@ -69,10 +109,6 @@ class RelationshipsExtractor(ClassicCDFBaseExtractor[Relationship]):
|
|
|
69
109
|
return len(relationships), relationships
|
|
70
110
|
|
|
71
111
|
def _fallback_id(self, item: Relationship) -> str | None:
|
|
72
|
-
if item.external_id
|
|
73
|
-
if self._log_target_nodes and item.target_type and item.target_external_id:
|
|
74
|
-
self._target_external_ids_by_type[InstanceIdPrefix.from_str(item.target_type)].add(
|
|
75
|
-
item.target_external_id
|
|
76
|
-
)
|
|
112
|
+
if item.external_id:
|
|
77
113
|
return create_sha256_hash(item.external_id)
|
|
78
114
|
return None
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import itertools
|
|
2
2
|
import json
|
|
3
|
+
import typing
|
|
3
4
|
from collections.abc import Callable, Iterable, Set
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from typing import Any
|
|
@@ -53,10 +54,21 @@ class SequencesExtractor(ClassicCDFBaseExtractor[NeatSequence]):
|
|
|
53
54
|
camel_case: bool = True,
|
|
54
55
|
as_write: bool = False,
|
|
55
56
|
prefix: str | None = None,
|
|
57
|
+
identifier: typing.Literal["id", "externalId"] = "id",
|
|
56
58
|
unpack_columns: bool = False,
|
|
57
59
|
):
|
|
58
60
|
super().__init__(
|
|
59
|
-
items,
|
|
61
|
+
items,
|
|
62
|
+
namespace,
|
|
63
|
+
to_type,
|
|
64
|
+
total,
|
|
65
|
+
limit,
|
|
66
|
+
unpack_metadata,
|
|
67
|
+
skip_metadata_values,
|
|
68
|
+
camel_case,
|
|
69
|
+
as_write,
|
|
70
|
+
prefix,
|
|
71
|
+
identifier,
|
|
60
72
|
)
|
|
61
73
|
self.unpack_columns = unpack_columns
|
|
62
74
|
|
|
@@ -73,6 +85,7 @@ class SequencesExtractor(ClassicCDFBaseExtractor[NeatSequence]):
|
|
|
73
85
|
camel_case: bool = True,
|
|
74
86
|
as_write: bool = False,
|
|
75
87
|
prefix: str | None = None,
|
|
88
|
+
identifier: typing.Literal["id", "externalId"] = "id",
|
|
76
89
|
unpack_columns: bool = False,
|
|
77
90
|
):
|
|
78
91
|
total, items = cls._handle_no_access(lambda: cls._from_dataset(client, data_set_external_id))
|
|
@@ -87,6 +100,7 @@ class SequencesExtractor(ClassicCDFBaseExtractor[NeatSequence]):
|
|
|
87
100
|
camel_case,
|
|
88
101
|
as_write,
|
|
89
102
|
prefix,
|
|
103
|
+
identifier,
|
|
90
104
|
unpack_columns,
|
|
91
105
|
)
|
|
92
106
|
|
|
@@ -103,6 +117,7 @@ class SequencesExtractor(ClassicCDFBaseExtractor[NeatSequence]):
|
|
|
103
117
|
camel_case: bool = True,
|
|
104
118
|
as_write: bool = False,
|
|
105
119
|
prefix: str | None = None,
|
|
120
|
+
identifier: typing.Literal["id", "externalId"] = "id",
|
|
106
121
|
unpack_columns: bool = False,
|
|
107
122
|
):
|
|
108
123
|
total, items = cls._handle_no_access(lambda: cls._from_hierarchy(client, root_asset_external_id))
|
|
@@ -117,6 +132,7 @@ class SequencesExtractor(ClassicCDFBaseExtractor[NeatSequence]):
|
|
|
117
132
|
camel_case,
|
|
118
133
|
as_write,
|
|
119
134
|
prefix,
|
|
135
|
+
identifier,
|
|
120
136
|
unpack_columns,
|
|
121
137
|
)
|
|
122
138
|
|
|
@@ -132,6 +148,7 @@ class SequencesExtractor(ClassicCDFBaseExtractor[NeatSequence]):
|
|
|
132
148
|
camel_case: bool = True,
|
|
133
149
|
as_write: bool = False,
|
|
134
150
|
prefix: str | None = None,
|
|
151
|
+
identifier: typing.Literal["id", "externalId"] = "id",
|
|
135
152
|
unpack_columns: bool = False,
|
|
136
153
|
):
|
|
137
154
|
total, items = cls._from_file(file_path)
|
|
@@ -146,6 +163,7 @@ class SequencesExtractor(ClassicCDFBaseExtractor[NeatSequence]):
|
|
|
146
163
|
camel_case,
|
|
147
164
|
as_write,
|
|
148
165
|
prefix,
|
|
166
|
+
identifier,
|
|
149
167
|
unpack_columns,
|
|
150
168
|
)
|
|
151
169
|
|