dsp-tools 9.1.0.post11__py3-none-any.whl → 18.3.0.post13__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.
- dsp_tools/__init__.py +4 -0
- dsp_tools/cli/args.py +36 -0
- dsp_tools/cli/call_action.py +51 -231
- dsp_tools/cli/call_action_files_only.py +101 -0
- dsp_tools/cli/call_action_with_network.py +207 -0
- dsp_tools/cli/create_parsers.py +156 -58
- dsp_tools/cli/entry_point.py +56 -26
- dsp_tools/cli/utils.py +87 -0
- dsp_tools/clients/CLAUDE.md +420 -0
- dsp_tools/clients/authentication_client.py +14 -0
- dsp_tools/clients/authentication_client_live.py +66 -0
- dsp_tools/{utils → clients}/connection.py +2 -18
- dsp_tools/clients/connection_live.py +233 -0
- dsp_tools/clients/fuseki_metrics.py +60 -0
- dsp_tools/clients/group_user_clients.py +35 -0
- dsp_tools/clients/group_user_clients_live.py +181 -0
- dsp_tools/clients/legal_info_client.py +23 -0
- dsp_tools/clients/legal_info_client_live.py +132 -0
- dsp_tools/clients/list_client.py +49 -0
- dsp_tools/clients/list_client_live.py +166 -0
- dsp_tools/clients/metadata_client.py +24 -0
- dsp_tools/clients/metadata_client_live.py +47 -0
- dsp_tools/clients/ontology_clients.py +49 -0
- dsp_tools/clients/ontology_create_client_live.py +166 -0
- dsp_tools/clients/ontology_get_client_live.py +80 -0
- dsp_tools/clients/permissions_client.py +68 -0
- dsp_tools/clients/project_client.py +16 -0
- dsp_tools/clients/project_client_live.py +66 -0
- dsp_tools/commands/create/communicate_problems.py +24 -0
- dsp_tools/commands/create/create.py +134 -0
- dsp_tools/commands/create/create_on_server/cardinalities.py +111 -0
- dsp_tools/commands/create/create_on_server/classes.py +99 -0
- dsp_tools/commands/create/create_on_server/complete_ontologies.py +116 -0
- dsp_tools/commands/create/create_on_server/default_permissions.py +134 -0
- dsp_tools/commands/create/create_on_server/group_users.py +165 -0
- dsp_tools/commands/create/create_on_server/lists.py +163 -0
- dsp_tools/commands/create/create_on_server/mappers.py +12 -0
- dsp_tools/commands/create/create_on_server/onto_utils.py +74 -0
- dsp_tools/commands/create/create_on_server/ontology.py +52 -0
- dsp_tools/commands/create/create_on_server/project.py +68 -0
- dsp_tools/commands/create/create_on_server/properties.py +119 -0
- dsp_tools/commands/create/exceptions.py +29 -0
- dsp_tools/commands/create/lists_only.py +66 -0
- dsp_tools/commands/create/models/create_problems.py +87 -0
- dsp_tools/commands/create/models/parsed_ontology.py +88 -0
- dsp_tools/commands/create/models/parsed_project.py +81 -0
- dsp_tools/commands/create/models/rdf_ontology.py +12 -0
- dsp_tools/commands/create/models/server_project_info.py +100 -0
- dsp_tools/commands/create/parsing/parse_lists.py +45 -0
- dsp_tools/commands/create/parsing/parse_ontology.py +243 -0
- dsp_tools/commands/create/parsing/parse_project.py +149 -0
- dsp_tools/commands/create/parsing/parsing_utils.py +40 -0
- dsp_tools/commands/create/project_validate.py +595 -0
- dsp_tools/commands/create/serialisation/ontology.py +119 -0
- dsp_tools/commands/create/serialisation/project.py +44 -0
- dsp_tools/commands/excel2json/CLAUDE.md +101 -0
- dsp_tools/commands/excel2json/json_header.py +57 -23
- dsp_tools/commands/excel2json/{new_lists → lists}/compliance_checks.py +26 -26
- dsp_tools/commands/excel2json/{new_lists/make_new_lists.py → lists/make_lists.py} +19 -18
- dsp_tools/commands/excel2json/{new_lists → lists}/models/input_error.py +1 -12
- dsp_tools/commands/excel2json/{new_lists → lists}/models/serialise.py +9 -5
- dsp_tools/commands/excel2json/{new_lists → lists}/utils.py +4 -4
- dsp_tools/commands/excel2json/models/input_error.py +31 -11
- dsp_tools/commands/excel2json/models/json_header.py +53 -15
- dsp_tools/commands/excel2json/models/ontology.py +4 -3
- dsp_tools/commands/excel2json/{lists.py → old_lists.py} +26 -112
- dsp_tools/commands/excel2json/project.py +78 -34
- dsp_tools/commands/excel2json/properties.py +57 -36
- dsp_tools/commands/excel2json/resources.py +32 -12
- dsp_tools/commands/excel2json/utils.py +20 -1
- dsp_tools/commands/excel2xml/__init__.py +2 -2
- dsp_tools/commands/excel2xml/excel2xml_cli.py +7 -15
- dsp_tools/commands/excel2xml/excel2xml_lib.py +138 -493
- dsp_tools/commands/excel2xml/propertyelement.py +5 -5
- dsp_tools/commands/{project → get}/get.py +29 -13
- dsp_tools/commands/get/get_permissions.py +257 -0
- dsp_tools/commands/get/get_permissions_legacy.py +89 -0
- dsp_tools/commands/{project/models → get/legacy_models}/context.py +6 -6
- dsp_tools/commands/{project/models → get/legacy_models}/group.py +5 -10
- dsp_tools/commands/{project/models → get/legacy_models}/listnode.py +5 -35
- dsp_tools/commands/{project/models → get/legacy_models}/model.py +1 -1
- dsp_tools/commands/{project/models → get/legacy_models}/ontology.py +9 -14
- dsp_tools/commands/{project/models → get/legacy_models}/project.py +13 -6
- dsp_tools/commands/{project/models → get/legacy_models}/propertyclass.py +9 -16
- dsp_tools/commands/{project/models → get/legacy_models}/resourceclass.py +8 -46
- dsp_tools/commands/{project/models → get/legacy_models}/user.py +19 -60
- dsp_tools/commands/get/models/permissions_models.py +10 -0
- dsp_tools/commands/id2iri.py +20 -10
- dsp_tools/commands/ingest_xmlupload/bulk_ingest_client.py +81 -56
- dsp_tools/commands/ingest_xmlupload/create_resources/apply_ingest_id.py +4 -10
- dsp_tools/commands/ingest_xmlupload/create_resources/upload_xml.py +97 -37
- dsp_tools/commands/ingest_xmlupload/create_resources/user_information.py +2 -2
- dsp_tools/commands/ingest_xmlupload/ingest_files/ingest_files.py +9 -10
- dsp_tools/commands/ingest_xmlupload/upload_files/filechecker.py +3 -3
- dsp_tools/commands/ingest_xmlupload/upload_files/input_error.py +2 -10
- dsp_tools/commands/ingest_xmlupload/upload_files/upload_failures.py +12 -2
- dsp_tools/commands/ingest_xmlupload/upload_files/upload_files.py +8 -9
- dsp_tools/commands/resume_xmlupload/resume_xmlupload.py +18 -18
- dsp_tools/commands/start_stack.py +126 -77
- dsp_tools/commands/update_legal/CLAUDE.md +344 -0
- dsp_tools/commands/update_legal/__init__.py +0 -0
- dsp_tools/commands/update_legal/core.py +182 -0
- dsp_tools/commands/update_legal/csv_operations.py +135 -0
- dsp_tools/commands/update_legal/models.py +87 -0
- dsp_tools/commands/update_legal/xml_operations.py +247 -0
- dsp_tools/commands/validate_data/CLAUDE.md +159 -0
- dsp_tools/commands/validate_data/__init__.py +0 -0
- dsp_tools/commands/validate_data/constants.py +59 -0
- dsp_tools/commands/validate_data/mappers.py +143 -0
- dsp_tools/commands/validate_data/models/__init__.py +0 -0
- dsp_tools/commands/validate_data/models/api_responses.py +45 -0
- dsp_tools/commands/validate_data/models/input_problems.py +119 -0
- dsp_tools/commands/validate_data/models/rdf_like_data.py +117 -0
- dsp_tools/commands/validate_data/models/validation.py +106 -0
- dsp_tools/commands/validate_data/prepare_data/__init__.py +0 -0
- dsp_tools/commands/validate_data/prepare_data/get_rdf_like_data.py +296 -0
- dsp_tools/commands/validate_data/prepare_data/make_data_graph.py +91 -0
- dsp_tools/commands/validate_data/prepare_data/prepare_data.py +184 -0
- dsp_tools/commands/validate_data/process_validation_report/__init__.py +0 -0
- dsp_tools/commands/validate_data/process_validation_report/get_user_validation_message.py +358 -0
- dsp_tools/commands/validate_data/process_validation_report/query_validation_result.py +507 -0
- dsp_tools/commands/validate_data/process_validation_report/reformat_validation_results.py +150 -0
- dsp_tools/commands/validate_data/shacl_cli_validator.py +70 -0
- dsp_tools/commands/validate_data/sparql/__init__.py +0 -0
- dsp_tools/commands/{xml_validate/sparql/resource_shacl.py → validate_data/sparql/cardinality_shacl.py} +45 -47
- dsp_tools/commands/validate_data/sparql/construct_shacl.py +92 -0
- dsp_tools/commands/validate_data/sparql/legal_info_shacl.py +36 -0
- dsp_tools/commands/validate_data/sparql/value_shacl.py +357 -0
- dsp_tools/commands/validate_data/utils.py +59 -0
- dsp_tools/commands/validate_data/validate_data.py +283 -0
- dsp_tools/commands/validate_data/validation/__init__.py +0 -0
- dsp_tools/commands/validate_data/validation/check_duplicate_files.py +55 -0
- dsp_tools/commands/validate_data/validation/check_for_unknown_classes.py +67 -0
- dsp_tools/commands/validate_data/validation/get_validation_report.py +94 -0
- dsp_tools/commands/validate_data/validation/validate_ontology.py +107 -0
- dsp_tools/commands/xmlupload/CLAUDE.md +292 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/__init__.py +0 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/constants.py +63 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/jsonld_utils.py +44 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/make_file_value.py +77 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/make_resource_and_values.py +114 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/make_values.py +262 -0
- dsp_tools/commands/xmlupload/models/bitstream_info.py +18 -0
- dsp_tools/commands/xmlupload/models/formatted_text_value.py +0 -25
- dsp_tools/commands/xmlupload/models/ingest.py +56 -70
- dsp_tools/commands/xmlupload/models/input_problems.py +6 -14
- dsp_tools/commands/xmlupload/models/lookup_models.py +21 -0
- dsp_tools/commands/xmlupload/models/permission.py +0 -39
- dsp_tools/commands/xmlupload/models/{deserialise/xmlpermission.py → permissions_parsed.py} +2 -2
- dsp_tools/commands/xmlupload/models/processed/__init__.py +0 -0
- dsp_tools/commands/xmlupload/models/processed/file_values.py +29 -0
- dsp_tools/commands/xmlupload/models/processed/res.py +27 -0
- dsp_tools/commands/xmlupload/models/processed/values.py +101 -0
- dsp_tools/commands/xmlupload/models/rdf_models.py +26 -0
- dsp_tools/commands/xmlupload/models/upload_clients.py +3 -3
- dsp_tools/commands/xmlupload/models/upload_state.py +2 -4
- dsp_tools/commands/xmlupload/prepare_xml_input/__init__.py +0 -0
- dsp_tools/commands/xmlupload/{ark2iri.py → prepare_xml_input/ark2iri.py} +1 -1
- dsp_tools/commands/xmlupload/prepare_xml_input/get_processed_resources.py +252 -0
- dsp_tools/commands/xmlupload/{iiif_uri_validator.py → prepare_xml_input/iiif_uri_validator.py} +2 -14
- dsp_tools/commands/xmlupload/{list_client.py → prepare_xml_input/list_client.py} +15 -10
- dsp_tools/commands/xmlupload/prepare_xml_input/prepare_xml_input.py +67 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/read_validate_xml_file.py +58 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/transform_input_values.py +118 -0
- dsp_tools/commands/xmlupload/resource_create_client.py +7 -468
- dsp_tools/commands/xmlupload/richtext_id2iri.py +37 -0
- dsp_tools/commands/xmlupload/stash/{construct_and_analyze_graph.py → analyse_circular_reference_graph.py} +64 -157
- dsp_tools/commands/xmlupload/stash/create_info_for_graph.py +53 -0
- dsp_tools/commands/xmlupload/stash/graph_models.py +13 -8
- dsp_tools/commands/xmlupload/stash/stash_circular_references.py +48 -115
- dsp_tools/commands/xmlupload/stash/stash_models.py +4 -9
- dsp_tools/commands/xmlupload/stash/upload_stashed_resptr_props.py +34 -40
- dsp_tools/commands/xmlupload/stash/upload_stashed_xml_texts.py +98 -108
- dsp_tools/commands/xmlupload/upload_config.py +8 -0
- dsp_tools/commands/xmlupload/write_diagnostic_info.py +14 -9
- dsp_tools/commands/xmlupload/xmlupload.py +214 -192
- dsp_tools/config/__init__.py +0 -0
- dsp_tools/config/logger_config.py +69 -0
- dsp_tools/{utils → config}/warnings_config.py +4 -1
- dsp_tools/error/__init__.py +0 -0
- dsp_tools/error/custom_warnings.py +39 -0
- dsp_tools/error/exceptions.py +204 -0
- dsp_tools/error/problems.py +10 -0
- dsp_tools/error/xmllib_errors.py +20 -0
- dsp_tools/error/xmllib_warnings.py +54 -0
- dsp_tools/error/xmllib_warnings_util.py +159 -0
- dsp_tools/error/xsd_validation_error_msg.py +19 -0
- dsp_tools/legacy_models/__init__.py +0 -0
- dsp_tools/{models → legacy_models}/datetimestamp.py +7 -7
- dsp_tools/{models → legacy_models}/langstring.py +1 -1
- dsp_tools/{models → legacy_models}/projectContext.py +4 -4
- dsp_tools/resources/schema/data.xsd +108 -83
- dsp_tools/resources/schema/lists-only.json +4 -23
- dsp_tools/resources/schema/project.json +80 -35
- dsp_tools/resources/schema/properties-only.json +1 -4
- dsp_tools/resources/start-stack/docker-compose.override-host.j2 +11 -0
- dsp_tools/resources/start-stack/docker-compose.yml +34 -30
- dsp_tools/resources/start-stack/dsp-app-config.json +45 -0
- dsp_tools/resources/start-stack/dsp-app-config.override-host.j2 +26 -0
- dsp_tools/resources/validate_data/api-shapes-resource-cardinalities.ttl +191 -0
- dsp_tools/resources/validate_data/api-shapes.ttl +804 -0
- dsp_tools/resources/validate_data/shacl-cli-image.yml +4 -0
- dsp_tools/resources/validate_data/validate-ontology.ttl +99 -0
- dsp_tools/utils/ansi_colors.py +32 -0
- dsp_tools/utils/data_formats/__init__.py +0 -0
- dsp_tools/utils/{date_util.py → data_formats/date_util.py} +13 -1
- dsp_tools/utils/data_formats/iri_util.py +30 -0
- dsp_tools/utils/{shared.py → data_formats/shared.py} +1 -35
- dsp_tools/utils/{uri_util.py → data_formats/uri_util.py} +12 -2
- dsp_tools/utils/fuseki_bloating.py +63 -0
- dsp_tools/utils/json_parsing.py +22 -0
- dsp_tools/utils/rdf_constants.py +42 -0
- dsp_tools/utils/rdflib_utils.py +10 -0
- dsp_tools/utils/replace_id_with_iri.py +66 -0
- dsp_tools/utils/request_utils.py +238 -0
- dsp_tools/utils/xml_parsing/__init__.py +0 -0
- dsp_tools/utils/xml_parsing/get_lookups.py +32 -0
- dsp_tools/utils/xml_parsing/get_parsed_resources.py +325 -0
- dsp_tools/utils/xml_parsing/models/__init__.py +0 -0
- dsp_tools/utils/xml_parsing/models/parsed_resource.py +76 -0
- dsp_tools/utils/xml_parsing/parse_clean_validate_xml.py +137 -0
- dsp_tools/xmllib/CLAUDE.md +302 -0
- dsp_tools/xmllib/__init__.py +49 -0
- dsp_tools/xmllib/general_functions.py +877 -0
- dsp_tools/xmllib/internal/__init__.py +0 -0
- dsp_tools/xmllib/internal/checkers.py +162 -0
- dsp_tools/xmllib/internal/circumvent_circular_imports.py +36 -0
- dsp_tools/xmllib/internal/constants.py +46 -0
- dsp_tools/xmllib/internal/input_converters.py +155 -0
- dsp_tools/xmllib/internal/serialise_file_value.py +57 -0
- dsp_tools/xmllib/internal/serialise_resource.py +177 -0
- dsp_tools/xmllib/internal/serialise_values.py +152 -0
- dsp_tools/xmllib/internal/type_aliases.py +11 -0
- dsp_tools/xmllib/models/config_options.py +28 -0
- dsp_tools/xmllib/models/date_formats.py +48 -0
- dsp_tools/xmllib/models/dsp_base_resources.py +1380 -400
- dsp_tools/xmllib/models/internal/__init__.py +0 -0
- dsp_tools/xmllib/models/internal/file_values.py +172 -0
- dsp_tools/xmllib/models/internal/geometry.py +162 -0
- dsp_tools/xmllib/models/{migration_metadata.py → internal/migration_metadata.py} +14 -10
- dsp_tools/xmllib/models/internal/serialise_permissions.py +66 -0
- dsp_tools/xmllib/models/internal/values.py +342 -0
- dsp_tools/xmllib/models/licenses/__init__.py +0 -0
- dsp_tools/xmllib/models/licenses/other.py +59 -0
- dsp_tools/xmllib/models/licenses/recommended.py +107 -0
- dsp_tools/xmllib/models/permissions.py +41 -0
- dsp_tools/xmllib/models/res.py +1782 -0
- dsp_tools/xmllib/models/root.py +313 -26
- dsp_tools/xmllib/value_checkers.py +310 -47
- dsp_tools/xmllib/value_converters.py +765 -8
- dsp_tools-18.3.0.post13.dist-info/METADATA +90 -0
- dsp_tools-18.3.0.post13.dist-info/RECORD +286 -0
- dsp_tools-18.3.0.post13.dist-info/WHEEL +4 -0
- {dsp_tools-9.1.0.post11.dist-info → dsp_tools-18.3.0.post13.dist-info}/entry_points.txt +1 -0
- dsp_tools/commands/project/create/project_create.py +0 -1107
- dsp_tools/commands/project/create/project_create_lists.py +0 -204
- dsp_tools/commands/project/create/project_validate.py +0 -453
- dsp_tools/commands/project/models/project_definition.py +0 -12
- dsp_tools/commands/rosetta.py +0 -124
- dsp_tools/commands/template.py +0 -30
- dsp_tools/commands/xml_validate/api_connection.py +0 -122
- dsp_tools/commands/xml_validate/deserialise_input.py +0 -135
- dsp_tools/commands/xml_validate/make_data_rdf.py +0 -193
- dsp_tools/commands/xml_validate/models/data_deserialised.py +0 -108
- dsp_tools/commands/xml_validate/models/data_rdf.py +0 -214
- dsp_tools/commands/xml_validate/models/input_problems.py +0 -191
- dsp_tools/commands/xml_validate/models/validation.py +0 -29
- dsp_tools/commands/xml_validate/reformat_validaton_result.py +0 -89
- dsp_tools/commands/xml_validate/sparql/construct_shapes.py +0 -16
- dsp_tools/commands/xml_validate/xml_validate.py +0 -151
- dsp_tools/commands/xmlupload/check_consistency_with_ontology.py +0 -253
- dsp_tools/commands/xmlupload/models/deserialise/deserialise_value.py +0 -236
- dsp_tools/commands/xmlupload/models/deserialise/xmlresource.py +0 -171
- dsp_tools/commands/xmlupload/models/namespace_context.py +0 -39
- dsp_tools/commands/xmlupload/models/ontology_lookup_models.py +0 -161
- dsp_tools/commands/xmlupload/models/ontology_problem_models.py +0 -178
- dsp_tools/commands/xmlupload/models/serialise/jsonld_serialiser.py +0 -40
- dsp_tools/commands/xmlupload/models/serialise/serialise_value.py +0 -51
- dsp_tools/commands/xmlupload/ontology_client.py +0 -92
- dsp_tools/commands/xmlupload/project_client.py +0 -91
- dsp_tools/commands/xmlupload/read_validate_xml_file.py +0 -99
- dsp_tools/models/custom_warnings.py +0 -31
- dsp_tools/models/exceptions.py +0 -90
- dsp_tools/resources/0100-template-repo/template.json +0 -45
- dsp_tools/resources/0100-template-repo/template.xml +0 -27
- dsp_tools/resources/start-stack/docker-compose-validation.yml +0 -5
- dsp_tools/resources/start-stack/start-stack-config.yml +0 -4
- dsp_tools/resources/xml_validate/api-shapes.ttl +0 -411
- dsp_tools/resources/xml_validate/replace_namespace.xslt +0 -61
- dsp_tools/utils/connection_live.py +0 -383
- dsp_tools/utils/iri_util.py +0 -14
- dsp_tools/utils/logger_config.py +0 -41
- dsp_tools/utils/set_encoder.py +0 -20
- dsp_tools/utils/xml_utils.py +0 -145
- dsp_tools/utils/xml_validation.py +0 -197
- dsp_tools/utils/xml_validation_models.py +0 -68
- dsp_tools/xmllib/models/file_values.py +0 -78
- dsp_tools/xmllib/models/resource.py +0 -415
- dsp_tools/xmllib/models/values.py +0 -428
- dsp_tools-9.1.0.post11.dist-info/METADATA +0 -130
- dsp_tools-9.1.0.post11.dist-info/RECORD +0 -167
- dsp_tools-9.1.0.post11.dist-info/WHEEL +0 -4
- dsp_tools-9.1.0.post11.dist-info/licenses/LICENSE +0 -674
- /dsp_tools/{commands/excel2json/new_lists → clients}/__init__.py +0 -0
- /dsp_tools/commands/{excel2json/new_lists/models → create}/__init__.py +0 -0
- /dsp_tools/commands/{project → create/create_on_server}/__init__.py +0 -0
- /dsp_tools/commands/{project/create → create/models}/__init__.py +0 -0
- /dsp_tools/commands/{project/models → create/parsing}/__init__.py +0 -0
- /dsp_tools/commands/{xml_validate → create/serialisation}/__init__.py +0 -0
- /dsp_tools/commands/{xml_validate/models → excel2json/lists}/__init__.py +0 -0
- /dsp_tools/commands/{xml_validate/sparql → excel2json/lists/models}/__init__.py +0 -0
- /dsp_tools/commands/excel2json/{new_lists → lists}/models/deserialise.py +0 -0
- /dsp_tools/commands/{xmlupload/models/deserialise → get}/__init__.py +0 -0
- /dsp_tools/commands/{xmlupload/models/serialise → get/legacy_models}/__init__.py +0 -0
- /dsp_tools/commands/{project/models → get/legacy_models}/helpers.py +0 -0
- /dsp_tools/{models → commands/get/models}/__init__.py +0 -0
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from abc import ABC
|
|
4
|
-
from dataclasses import dataclass
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
@dataclass
|
|
8
|
-
class ProjectDeserialised:
|
|
9
|
-
info: ProjectInformation
|
|
10
|
-
data: DataDeserialised
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@dataclass
|
|
14
|
-
class ProjectInformation:
|
|
15
|
-
shortcode: str
|
|
16
|
-
default_onto: str
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@dataclass
|
|
20
|
-
class DataDeserialised:
|
|
21
|
-
resources: list[AbstractResource]
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@dataclass
|
|
25
|
-
class AbstractResource(ABC):
|
|
26
|
-
res_id: str
|
|
27
|
-
label: str
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@dataclass
|
|
31
|
-
class ResourceDeserialised(AbstractResource):
|
|
32
|
-
res_class: str
|
|
33
|
-
values: list[ValueDeserialised]
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@dataclass
|
|
37
|
-
class AnnotationDeserialised(AbstractResource): ...
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
@dataclass
|
|
41
|
-
class RegionDeserialised(AbstractResource): ...
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@dataclass
|
|
45
|
-
class LinkObjDeserialised(AbstractResource): ...
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@dataclass
|
|
49
|
-
class VideoSegmentDeserialised(AbstractResource): ...
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@dataclass
|
|
53
|
-
class AudioSegmentDeserialised(AbstractResource): ...
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
@dataclass
|
|
57
|
-
class ValueDeserialised:
|
|
58
|
-
prop_name: str
|
|
59
|
-
object_value: str | None
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
@dataclass
|
|
63
|
-
class BooleanValueDeserialised(ValueDeserialised): ...
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
@dataclass
|
|
67
|
-
class ColorValueDeserialised(ValueDeserialised): ...
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@dataclass
|
|
71
|
-
class DateValueDeserialised(ValueDeserialised): ...
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
@dataclass
|
|
75
|
-
class DecimalValueDeserialised(ValueDeserialised): ...
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
@dataclass
|
|
79
|
-
class GeonameValueDeserialised(ValueDeserialised): ...
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
@dataclass
|
|
83
|
-
class IntValueDeserialised(ValueDeserialised): ...
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
@dataclass
|
|
87
|
-
class LinkValueDeserialised(ValueDeserialised): ...
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
@dataclass
|
|
91
|
-
class ListValueDeserialised(ValueDeserialised):
|
|
92
|
-
list_name: str
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
@dataclass
|
|
96
|
-
class SimpleTextDeserialised(ValueDeserialised): ...
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
@dataclass
|
|
100
|
-
class RichtextDeserialised(ValueDeserialised): ...
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
@dataclass
|
|
104
|
-
class TimeValueDeserialised(ValueDeserialised): ...
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@dataclass
|
|
108
|
-
class UriValueDeserialised(ValueDeserialised): ...
|
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from abc import ABC
|
|
4
|
-
from dataclasses import dataclass
|
|
5
|
-
from uuid import uuid4
|
|
6
|
-
|
|
7
|
-
from rdflib import RDF
|
|
8
|
-
from rdflib import RDFS
|
|
9
|
-
from rdflib import Graph
|
|
10
|
-
from rdflib import Literal
|
|
11
|
-
from rdflib import Namespace
|
|
12
|
-
from rdflib import URIRef
|
|
13
|
-
|
|
14
|
-
KNORA_API = Namespace("http://api.knora.org/ontology/knora-api/v2#")
|
|
15
|
-
API_SHAPES = Namespace("http://api.knora.org/ontology/knora-api/shapes/v2#")
|
|
16
|
-
DATA = Namespace("http://data/")
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@dataclass
|
|
20
|
-
class DataRDF:
|
|
21
|
-
triples: list[RDFTriples]
|
|
22
|
-
|
|
23
|
-
def make_graph(self) -> Graph:
|
|
24
|
-
g = Graph()
|
|
25
|
-
for r in self.triples:
|
|
26
|
-
g += r.make_graph()
|
|
27
|
-
return g
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class RDFTriples(ABC):
|
|
31
|
-
def make_graph(self) -> Graph:
|
|
32
|
-
raise NotImplementedError
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@dataclass
|
|
36
|
-
class ResourceRDF(RDFTriples):
|
|
37
|
-
res_iri: URIRef
|
|
38
|
-
res_class: URIRef
|
|
39
|
-
label: Literal
|
|
40
|
-
|
|
41
|
-
def make_graph(self) -> Graph:
|
|
42
|
-
g = Graph()
|
|
43
|
-
g.add((self.res_iri, RDF.type, self.res_class))
|
|
44
|
-
g.add((self.res_iri, RDFS.label, self.label))
|
|
45
|
-
return g
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@dataclass
|
|
49
|
-
class ValueRDF(RDFTriples):
|
|
50
|
-
prop_name: URIRef
|
|
51
|
-
object_value: URIRef | Literal
|
|
52
|
-
res_iri: URIRef
|
|
53
|
-
|
|
54
|
-
def make_graph(self) -> Graph:
|
|
55
|
-
raise NotImplementedError
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@dataclass
|
|
59
|
-
class BooleanValueRDF(ValueRDF):
|
|
60
|
-
object_value: Literal
|
|
61
|
-
|
|
62
|
-
def make_graph(self) -> Graph:
|
|
63
|
-
g = Graph()
|
|
64
|
-
val_iri = DATA[str(uuid4())]
|
|
65
|
-
g.add((val_iri, RDF.type, KNORA_API.BooleanValue))
|
|
66
|
-
g.add((val_iri, KNORA_API.booleanValueAsBoolean, self.object_value))
|
|
67
|
-
g.add((self.res_iri, self.prop_name, val_iri))
|
|
68
|
-
return g
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
@dataclass
|
|
72
|
-
class ColorValueRDF(ValueRDF):
|
|
73
|
-
object_value: Literal
|
|
74
|
-
|
|
75
|
-
def make_graph(self) -> Graph:
|
|
76
|
-
g = Graph()
|
|
77
|
-
val_iri = DATA[str(uuid4())]
|
|
78
|
-
g.add((val_iri, RDF.type, KNORA_API.ColorValue))
|
|
79
|
-
g.add((val_iri, KNORA_API.colorValueAsColor, self.object_value))
|
|
80
|
-
g.add((self.res_iri, self.prop_name, val_iri))
|
|
81
|
-
return g
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
@dataclass
|
|
85
|
-
class DateValueRDF(ValueRDF):
|
|
86
|
-
object_value: Literal
|
|
87
|
-
|
|
88
|
-
def make_graph(self) -> Graph:
|
|
89
|
-
g = Graph()
|
|
90
|
-
val_iri = DATA[str(uuid4())]
|
|
91
|
-
g.add((val_iri, RDF.type, KNORA_API.DateValue))
|
|
92
|
-
g.add((val_iri, KNORA_API.valueAsString, self.object_value))
|
|
93
|
-
g.add((self.res_iri, self.prop_name, val_iri))
|
|
94
|
-
return g
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
@dataclass
|
|
98
|
-
class DecimalValueRDF(ValueRDF):
|
|
99
|
-
object_value: Literal
|
|
100
|
-
|
|
101
|
-
def make_graph(self) -> Graph:
|
|
102
|
-
g = Graph()
|
|
103
|
-
val_iri = DATA[str(uuid4())]
|
|
104
|
-
g.add((val_iri, RDF.type, KNORA_API.DecimalValue))
|
|
105
|
-
g.add((val_iri, KNORA_API.decimalValueAsDecimal, self.object_value))
|
|
106
|
-
g.add((self.res_iri, self.prop_name, val_iri))
|
|
107
|
-
return g
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
@dataclass
|
|
111
|
-
class GeonameValueRDF(ValueRDF):
|
|
112
|
-
object_value: Literal
|
|
113
|
-
|
|
114
|
-
def make_graph(self) -> Graph:
|
|
115
|
-
g = Graph()
|
|
116
|
-
val_iri = DATA[str(uuid4())]
|
|
117
|
-
g.add((val_iri, RDF.type, KNORA_API.GeonameValue))
|
|
118
|
-
g.add((val_iri, KNORA_API.geonameValueAsGeonameCode, self.object_value))
|
|
119
|
-
g.add((self.res_iri, self.prop_name, val_iri))
|
|
120
|
-
return g
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
@dataclass
|
|
124
|
-
class IntValueRDF(ValueRDF):
|
|
125
|
-
object_value: Literal
|
|
126
|
-
|
|
127
|
-
def make_graph(self) -> Graph:
|
|
128
|
-
g = Graph()
|
|
129
|
-
val_iri = DATA[str(uuid4())]
|
|
130
|
-
g.add((val_iri, RDF.type, KNORA_API.IntValue))
|
|
131
|
-
g.add((val_iri, KNORA_API.intValueAsInt, self.object_value))
|
|
132
|
-
g.add((self.res_iri, self.prop_name, val_iri))
|
|
133
|
-
return g
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
@dataclass
|
|
137
|
-
class LinkValueRDF(ValueRDF):
|
|
138
|
-
object_value: URIRef
|
|
139
|
-
|
|
140
|
-
def make_graph(self) -> Graph:
|
|
141
|
-
g = Graph()
|
|
142
|
-
val_iri = DATA[str(uuid4())]
|
|
143
|
-
g.add((val_iri, RDF.type, KNORA_API.LinkValue))
|
|
144
|
-
g.add((val_iri, API_SHAPES.linkValueHasTargetID, self.object_value))
|
|
145
|
-
g.add((self.res_iri, self.prop_name, val_iri))
|
|
146
|
-
return g
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
@dataclass
|
|
150
|
-
class ListValueRDF(ValueRDF):
|
|
151
|
-
prop_name: URIRef
|
|
152
|
-
object_value: Literal
|
|
153
|
-
list_name: Literal
|
|
154
|
-
|
|
155
|
-
def make_graph(self) -> Graph:
|
|
156
|
-
g = Graph()
|
|
157
|
-
val_iri = DATA[str(uuid4())]
|
|
158
|
-
g.add((val_iri, RDF.type, KNORA_API.ListValue))
|
|
159
|
-
g.add((val_iri, API_SHAPES.listNodeAsString, self.object_value))
|
|
160
|
-
g.add((val_iri, API_SHAPES.listNameAsString, self.list_name))
|
|
161
|
-
g.add((self.res_iri, self.prop_name, val_iri))
|
|
162
|
-
return g
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
@dataclass
|
|
166
|
-
class SimpleTextRDF(ValueRDF):
|
|
167
|
-
object_value: Literal
|
|
168
|
-
|
|
169
|
-
def make_graph(self) -> Graph:
|
|
170
|
-
g = Graph()
|
|
171
|
-
val_iri = DATA[str(uuid4())]
|
|
172
|
-
g.add((val_iri, RDF.type, KNORA_API.TextValue))
|
|
173
|
-
g.add((val_iri, KNORA_API.valueAsString, self.object_value))
|
|
174
|
-
g.add((self.res_iri, self.prop_name, val_iri))
|
|
175
|
-
return g
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
@dataclass
|
|
179
|
-
class RichtextRDF(ValueRDF):
|
|
180
|
-
object_value: Literal
|
|
181
|
-
|
|
182
|
-
def make_graph(self) -> Graph:
|
|
183
|
-
g = Graph()
|
|
184
|
-
val_iri = DATA[str(uuid4())]
|
|
185
|
-
g.add((val_iri, RDF.type, KNORA_API.TextValue))
|
|
186
|
-
g.add((val_iri, KNORA_API.textValueAsXml, self.object_value))
|
|
187
|
-
g.add((self.res_iri, self.prop_name, val_iri))
|
|
188
|
-
return g
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
@dataclass
|
|
192
|
-
class TimeValueRDF(ValueRDF):
|
|
193
|
-
object_value: Literal
|
|
194
|
-
|
|
195
|
-
def make_graph(self) -> Graph:
|
|
196
|
-
g = Graph()
|
|
197
|
-
val_iri = DATA[str(uuid4())]
|
|
198
|
-
g.add((val_iri, RDF.type, KNORA_API.TimeValue))
|
|
199
|
-
g.add((val_iri, KNORA_API.timeValueAsTimeStamp, self.object_value))
|
|
200
|
-
g.add((self.res_iri, self.prop_name, val_iri))
|
|
201
|
-
return g
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
@dataclass
|
|
205
|
-
class UriValueRDF(ValueRDF):
|
|
206
|
-
object_value: Literal
|
|
207
|
-
|
|
208
|
-
def make_graph(self) -> Graph:
|
|
209
|
-
g = Graph()
|
|
210
|
-
val_iri = DATA[str(uuid4())]
|
|
211
|
-
g.add((val_iri, RDF.type, KNORA_API.UriValue))
|
|
212
|
-
g.add((val_iri, KNORA_API.uriValueAsUri, self.object_value))
|
|
213
|
-
g.add((self.res_iri, self.prop_name, val_iri))
|
|
214
|
-
return g
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import warnings
|
|
4
|
-
from abc import ABC
|
|
5
|
-
from collections import defaultdict
|
|
6
|
-
from dataclasses import dataclass
|
|
7
|
-
from datetime import datetime
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
|
|
10
|
-
import pandas as pd
|
|
11
|
-
from rdflib import Graph
|
|
12
|
-
|
|
13
|
-
from dsp_tools.commands.xml_validate.models.validation import UnexpectedComponent
|
|
14
|
-
from dsp_tools.models.custom_warnings import DspToolsUserWarning
|
|
15
|
-
|
|
16
|
-
LIST_SEPARATOR = "\n - "
|
|
17
|
-
GRAND_SEPARATOR = "\n\n----------------------------\n"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@dataclass
|
|
21
|
-
class UnexpectedResults:
|
|
22
|
-
components: list[UnexpectedComponent]
|
|
23
|
-
|
|
24
|
-
def save_inform_user(self, results_graph: Graph, shacl: Graph, data: Graph) -> None:
|
|
25
|
-
cwdr = Path.cwd()
|
|
26
|
-
prefix = f"{datetime.now()!s}_"
|
|
27
|
-
components = sorted(x.component_type for x in self.components)
|
|
28
|
-
msg = (
|
|
29
|
-
f"Unexpected violations were found in the validation results:"
|
|
30
|
-
f"{LIST_SEPARATOR}{LIST_SEPARATOR.join(components)}\n"
|
|
31
|
-
f"Please contact the development team with the files starting with the timestamp '{prefix}' "
|
|
32
|
-
f"in the directory '{cwdr}'."
|
|
33
|
-
)
|
|
34
|
-
save_path = cwdr / f"{prefix}validation_result.ttl"
|
|
35
|
-
results_graph.serialize(save_path)
|
|
36
|
-
shacl_p = cwdr / f"{prefix}shacl.ttl"
|
|
37
|
-
shacl.serialize(shacl_p)
|
|
38
|
-
data_p = cwdr / f"{prefix}data.ttl"
|
|
39
|
-
data.serialize(data_p)
|
|
40
|
-
warnings.warn(DspToolsUserWarning(msg))
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
@dataclass
|
|
44
|
-
class AllProblems:
|
|
45
|
-
problems: list[InputProblem]
|
|
46
|
-
unexpected_results: UnexpectedResults | None
|
|
47
|
-
|
|
48
|
-
def get_msg(self, file_path: Path) -> str:
|
|
49
|
-
coll = self._make_collection()
|
|
50
|
-
title_msg = f"\nDuring the validation of the data {len(self.problems)} errors were found:\n\n"
|
|
51
|
-
if len(self.problems) > 50:
|
|
52
|
-
out_path = file_path.parent / f"{file_path.stem}_validation_errors.csv"
|
|
53
|
-
self._save_as_csv(out_path)
|
|
54
|
-
out_message = (
|
|
55
|
-
title_msg + f"Due to the large number or errors, the validation errors were saved at:\n{out_path}"
|
|
56
|
-
)
|
|
57
|
-
else:
|
|
58
|
-
msg = [x.get_msg() for x in coll]
|
|
59
|
-
out_message = title_msg + GRAND_SEPARATOR.join(msg)
|
|
60
|
-
return out_message
|
|
61
|
-
|
|
62
|
-
def _make_collection(self) -> list[ResourceProblemCollection]:
|
|
63
|
-
d = defaultdict(list)
|
|
64
|
-
for e in self.problems:
|
|
65
|
-
d[e.res_id].append(e)
|
|
66
|
-
collection_list = []
|
|
67
|
-
for k, v in d.items():
|
|
68
|
-
collection_list.append(ResourceProblemCollection(k, v))
|
|
69
|
-
return sorted(collection_list, key=lambda x: x.res_id)
|
|
70
|
-
|
|
71
|
-
def _save_as_csv(self, out_path: Path) -> None:
|
|
72
|
-
all_problems = [x.to_dict() for x in self.problems]
|
|
73
|
-
df = pd.DataFrame.from_records(all_problems)
|
|
74
|
-
df = df.sort_values(by=["Resource Type", "Resource ID", "Property"])
|
|
75
|
-
df.to_csv(out_path, index=False)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
@dataclass
|
|
79
|
-
class ResourceProblemCollection:
|
|
80
|
-
res_id: str
|
|
81
|
-
problems: list[InputProblem]
|
|
82
|
-
|
|
83
|
-
def get_msg(self) -> str:
|
|
84
|
-
prop_msg = self._msg_for_properties()
|
|
85
|
-
return f"Resource ID: {self.res_id} | Resource Type: {self.problems[0].res_type}\n{prop_msg}"
|
|
86
|
-
|
|
87
|
-
def _msg_for_properties(self) -> str:
|
|
88
|
-
grouped = self._make_collection()
|
|
89
|
-
out_list = []
|
|
90
|
-
for prop_name, problem in grouped.items():
|
|
91
|
-
problem_list = [x.get_msg() for x in problem]
|
|
92
|
-
out_list.append((prop_name, f"{prop_name}{LIST_SEPARATOR}{LIST_SEPARATOR.join(problem_list)}"))
|
|
93
|
-
sorted_list = sorted(out_list, key=lambda x: x[0])
|
|
94
|
-
return "\n".join([x[1] for x in sorted_list])
|
|
95
|
-
|
|
96
|
-
def _make_collection(self) -> dict[str, list[InputProblem]]:
|
|
97
|
-
grouped_dict = defaultdict(list)
|
|
98
|
-
for problem in self.problems:
|
|
99
|
-
grouped_dict[problem.sort_value()].append(problem)
|
|
100
|
-
return grouped_dict
|
|
101
|
-
|
|
102
|
-
def sort_value(self) -> str:
|
|
103
|
-
return self.res_id
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
@dataclass
|
|
107
|
-
class InputProblem(ABC):
|
|
108
|
-
res_id: str
|
|
109
|
-
res_type: str
|
|
110
|
-
prop_name: str
|
|
111
|
-
|
|
112
|
-
@property
|
|
113
|
-
def problem(self) -> str:
|
|
114
|
-
raise NotImplementedError
|
|
115
|
-
|
|
116
|
-
def get_msg(self) -> str:
|
|
117
|
-
raise NotImplementedError
|
|
118
|
-
|
|
119
|
-
def to_dict(self) -> dict[str, str]:
|
|
120
|
-
raise NotImplementedError
|
|
121
|
-
|
|
122
|
-
def _base_dict(self) -> dict[str, str]:
|
|
123
|
-
return {
|
|
124
|
-
"Resource Type": self.res_type,
|
|
125
|
-
"Resource ID": self.res_id,
|
|
126
|
-
"Property": self.prop_name,
|
|
127
|
-
"Problem": self.problem,
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
def sort_value(self) -> str:
|
|
131
|
-
raise NotImplementedError
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
#######################
|
|
135
|
-
# Cardinality Violation
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
@dataclass
|
|
139
|
-
class MaxCardinalityViolation(InputProblem):
|
|
140
|
-
expected_cardinality: str
|
|
141
|
-
|
|
142
|
-
@property
|
|
143
|
-
def problem(self) -> str:
|
|
144
|
-
return "Maximum Cardinality Violation"
|
|
145
|
-
|
|
146
|
-
def get_msg(self) -> str:
|
|
147
|
-
return f"{self.problem} | Expected Cardinality: {self.expected_cardinality}"
|
|
148
|
-
|
|
149
|
-
def to_dict(self) -> dict[str, str]:
|
|
150
|
-
problm_dict = self._base_dict()
|
|
151
|
-
problm_dict["Expected"] = f"Cardinality: {self.expected_cardinality}"
|
|
152
|
-
return problm_dict
|
|
153
|
-
|
|
154
|
-
def sort_value(self) -> str:
|
|
155
|
-
return self.prop_name
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
@dataclass
|
|
159
|
-
class MinCardinalityViolation(InputProblem):
|
|
160
|
-
expected_cardinality: str
|
|
161
|
-
|
|
162
|
-
@property
|
|
163
|
-
def problem(self) -> str:
|
|
164
|
-
return "Minimum Cardinality Violation"
|
|
165
|
-
|
|
166
|
-
def get_msg(self) -> str:
|
|
167
|
-
return f"{self.problem} | Expected Cardinality: {self.expected_cardinality}"
|
|
168
|
-
|
|
169
|
-
def to_dict(self) -> dict[str, str]:
|
|
170
|
-
problm_dict = self._base_dict()
|
|
171
|
-
problm_dict["Expected"] = f"Cardinality: {self.expected_cardinality}"
|
|
172
|
-
return problm_dict
|
|
173
|
-
|
|
174
|
-
def sort_value(self) -> str:
|
|
175
|
-
return self.prop_name
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
@dataclass
|
|
179
|
-
class NonExistentCardinalityViolation(InputProblem):
|
|
180
|
-
@property
|
|
181
|
-
def problem(self) -> str:
|
|
182
|
-
return "The resource class does not have a cardinality for this property."
|
|
183
|
-
|
|
184
|
-
def get_msg(self) -> str:
|
|
185
|
-
return self.problem
|
|
186
|
-
|
|
187
|
-
def to_dict(self) -> dict[str, str]:
|
|
188
|
-
return self._base_dict()
|
|
189
|
-
|
|
190
|
-
def sort_value(self) -> str:
|
|
191
|
-
return self.prop_name
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from dataclasses import dataclass
|
|
4
|
-
|
|
5
|
-
from rdflib import Graph
|
|
6
|
-
from rdflib.term import Node
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@dataclass
|
|
10
|
-
class ValidationReport:
|
|
11
|
-
conforms: bool
|
|
12
|
-
validation_graph: Graph
|
|
13
|
-
shacl_graph: Graph
|
|
14
|
-
data_graph: Graph
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@dataclass
|
|
18
|
-
class UnexpectedComponent:
|
|
19
|
-
component_type: str
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@dataclass
|
|
23
|
-
class ValidationResult:
|
|
24
|
-
source_constraint_component: Node
|
|
25
|
-
res_iri: Node
|
|
26
|
-
res_class: Node
|
|
27
|
-
property: Node
|
|
28
|
-
results_message: str
|
|
29
|
-
value: str | None = None
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
from rdflib import RDF
|
|
2
|
-
from rdflib import SH
|
|
3
|
-
from rdflib import Graph
|
|
4
|
-
from rdflib.term import Node
|
|
5
|
-
|
|
6
|
-
from dsp_tools.commands.xml_validate.models.input_problems import AllProblems
|
|
7
|
-
from dsp_tools.commands.xml_validate.models.input_problems import InputProblem
|
|
8
|
-
from dsp_tools.commands.xml_validate.models.input_problems import MaxCardinalityViolation
|
|
9
|
-
from dsp_tools.commands.xml_validate.models.input_problems import MinCardinalityViolation
|
|
10
|
-
from dsp_tools.commands.xml_validate.models.input_problems import NonExistentCardinalityViolation
|
|
11
|
-
from dsp_tools.commands.xml_validate.models.input_problems import UnexpectedResults
|
|
12
|
-
from dsp_tools.commands.xml_validate.models.validation import UnexpectedComponent
|
|
13
|
-
from dsp_tools.commands.xml_validate.models.validation import ValidationResult
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def reformat_validation_graph(results_graph: Graph, data_graph: Graph) -> AllProblems:
|
|
17
|
-
"""
|
|
18
|
-
Reformats the validation result from an RDF graph into class instances
|
|
19
|
-
that are used to communicate the problems with the user.
|
|
20
|
-
|
|
21
|
-
Args:
|
|
22
|
-
results_graph: Contains the possible validation errors
|
|
23
|
-
data_graph: Graph with the data
|
|
24
|
-
|
|
25
|
-
Returns:
|
|
26
|
-
All Problems
|
|
27
|
-
"""
|
|
28
|
-
reformatted_results = _reformat_result_graph(results_graph, data_graph)
|
|
29
|
-
input_problems, unexpected_components = _transform_violations_into_input_problems(reformatted_results)
|
|
30
|
-
unexpected = UnexpectedResults(unexpected_components) if unexpected_components else None
|
|
31
|
-
return AllProblems(input_problems, unexpected)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def _reformat_result_graph(results_graph: Graph, data_graph: Graph) -> list[ValidationResult]:
|
|
35
|
-
violations = results_graph.subjects(RDF.type, SH.ValidationResult)
|
|
36
|
-
return [_extract_one_violation(x, results_graph, data_graph) for x in violations]
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def _extract_one_violation(bn: Node, results_graph: Graph, data_graph: Graph) -> ValidationResult:
|
|
40
|
-
focus_nd = next(results_graph.objects(bn, SH.focusNode))
|
|
41
|
-
res_type = next(data_graph.objects(focus_nd, RDF.type))
|
|
42
|
-
path = next(results_graph.objects(bn, SH.resultPath))
|
|
43
|
-
component = next(results_graph.objects(bn, SH.sourceConstraintComponent))
|
|
44
|
-
msg = str(next(results_graph.objects(bn, SH.resultMessage)))
|
|
45
|
-
return ValidationResult(
|
|
46
|
-
source_constraint_component=component,
|
|
47
|
-
res_iri=focus_nd,
|
|
48
|
-
res_class=res_type,
|
|
49
|
-
property=path,
|
|
50
|
-
results_message=msg,
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def _transform_violations_into_input_problems(
|
|
55
|
-
violations: list[ValidationResult],
|
|
56
|
-
) -> tuple[list[InputProblem], list[UnexpectedComponent]]:
|
|
57
|
-
input_problems: list[InputProblem] = []
|
|
58
|
-
unexpected_components: list[UnexpectedComponent] = []
|
|
59
|
-
for violation in violations:
|
|
60
|
-
problem = _reformat_one_violation(violation)
|
|
61
|
-
if isinstance(problem, UnexpectedComponent):
|
|
62
|
-
unexpected_components.append(problem)
|
|
63
|
-
else:
|
|
64
|
-
input_problems.append(problem)
|
|
65
|
-
return input_problems, unexpected_components
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def _reformat_one_violation(violation: ValidationResult) -> InputProblem | UnexpectedComponent:
|
|
69
|
-
subject_id = _reformat_data_iri(str(violation.res_iri))
|
|
70
|
-
prop_name = _reformat_onto_iri(str(violation.property))
|
|
71
|
-
res_type = _reformat_onto_iri(str(violation.res_class))
|
|
72
|
-
match violation.source_constraint_component:
|
|
73
|
-
case SH.MaxCountConstraintComponent:
|
|
74
|
-
return MaxCardinalityViolation(subject_id, res_type, prop_name, violation.results_message)
|
|
75
|
-
case SH.MinCountConstraintComponent:
|
|
76
|
-
return MinCardinalityViolation(subject_id, res_type, prop_name, violation.results_message)
|
|
77
|
-
case SH.ClosedConstraintComponent:
|
|
78
|
-
return NonExistentCardinalityViolation(subject_id, res_type, prop_name)
|
|
79
|
-
case _:
|
|
80
|
-
return UnexpectedComponent(str(violation.source_constraint_component))
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def _reformat_onto_iri(prop: str) -> str:
|
|
84
|
-
onto = prop.split("/")[-2]
|
|
85
|
-
return f'{onto}:{prop.split("#")[-1]}'
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def _reformat_data_iri(iri: str) -> str:
|
|
89
|
-
return iri.replace("http://data/", "")
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
from rdflib import Graph
|
|
2
|
-
|
|
3
|
-
from dsp_tools.commands.xml_validate.sparql.resource_shacl import construct_resource_class_node_shape
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def construct_shapes_graph(onto: Graph) -> Graph:
|
|
7
|
-
"""
|
|
8
|
-
Constructs a shapes graph from a project ontology
|
|
9
|
-
|
|
10
|
-
Args:
|
|
11
|
-
onto: ontology as graph
|
|
12
|
-
|
|
13
|
-
Returns:
|
|
14
|
-
shapes graph
|
|
15
|
-
"""
|
|
16
|
-
return construct_resource_class_node_shape(onto)
|