dsp-tools 0.9.13__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 +5 -0
- dsp_tools/cli/args.py +47 -0
- dsp_tools/cli/call_action.py +85 -0
- 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 +479 -0
- dsp_tools/cli/entry_point.py +322 -0
- 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/clients/connection.py +35 -0
- 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 +321 -0
- dsp_tools/commands/excel2json/lists/__init__.py +0 -0
- dsp_tools/commands/excel2json/lists/compliance_checks.py +292 -0
- dsp_tools/commands/excel2json/lists/make_lists.py +247 -0
- dsp_tools/commands/excel2json/lists/models/__init__.py +0 -0
- dsp_tools/commands/excel2json/lists/models/deserialise.py +30 -0
- dsp_tools/commands/excel2json/lists/models/input_error.py +216 -0
- dsp_tools/commands/excel2json/lists/models/serialise.py +57 -0
- dsp_tools/commands/excel2json/lists/utils.py +81 -0
- dsp_tools/commands/excel2json/models/__init__.py +0 -0
- dsp_tools/commands/excel2json/models/input_error.py +416 -0
- dsp_tools/commands/excel2json/models/json_header.py +175 -0
- dsp_tools/commands/excel2json/models/list_node_name.py +16 -0
- dsp_tools/commands/excel2json/models/ontology.py +76 -0
- dsp_tools/commands/excel2json/old_lists.py +328 -0
- dsp_tools/commands/excel2json/project.py +280 -0
- dsp_tools/commands/excel2json/properties.py +370 -0
- dsp_tools/commands/excel2json/resources.py +336 -0
- dsp_tools/commands/excel2json/utils.py +352 -0
- dsp_tools/commands/excel2xml/__init__.py +7 -0
- dsp_tools/commands/excel2xml/excel2xml_cli.py +523 -0
- dsp_tools/commands/excel2xml/excel2xml_lib.py +1953 -0
- dsp_tools/commands/excel2xml/propertyelement.py +47 -0
- dsp_tools/commands/get/__init__.py +0 -0
- dsp_tools/commands/get/get.py +166 -0
- dsp_tools/commands/get/get_permissions.py +257 -0
- dsp_tools/commands/get/get_permissions_legacy.py +89 -0
- dsp_tools/commands/get/legacy_models/__init__.py +0 -0
- dsp_tools/commands/get/legacy_models/context.py +318 -0
- dsp_tools/commands/get/legacy_models/group.py +241 -0
- dsp_tools/commands/get/legacy_models/helpers.py +47 -0
- dsp_tools/commands/get/legacy_models/listnode.py +390 -0
- dsp_tools/commands/get/legacy_models/model.py +12 -0
- dsp_tools/commands/get/legacy_models/ontology.py +324 -0
- dsp_tools/commands/get/legacy_models/project.py +366 -0
- dsp_tools/commands/get/legacy_models/propertyclass.py +417 -0
- dsp_tools/commands/get/legacy_models/resourceclass.py +676 -0
- dsp_tools/commands/get/legacy_models/user.py +438 -0
- dsp_tools/commands/get/models/__init__.py +0 -0
- dsp_tools/commands/get/models/permissions_models.py +10 -0
- dsp_tools/commands/id2iri.py +258 -0
- dsp_tools/commands/ingest_xmlupload/__init__.py +0 -0
- dsp_tools/commands/ingest_xmlupload/bulk_ingest_client.py +178 -0
- dsp_tools/commands/ingest_xmlupload/create_resources/__init__.py +0 -0
- dsp_tools/commands/ingest_xmlupload/create_resources/apply_ingest_id.py +69 -0
- dsp_tools/commands/ingest_xmlupload/create_resources/upload_xml.py +166 -0
- dsp_tools/commands/ingest_xmlupload/create_resources/user_information.py +121 -0
- dsp_tools/commands/ingest_xmlupload/ingest_files/__init__.py +0 -0
- dsp_tools/commands/ingest_xmlupload/ingest_files/ingest_files.py +64 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/__init__.py +0 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/filechecker.py +20 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/input_error.py +57 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/upload_failures.py +66 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/upload_files.py +67 -0
- dsp_tools/commands/resume_xmlupload/__init__.py +0 -0
- dsp_tools/commands/resume_xmlupload/resume_xmlupload.py +96 -0
- dsp_tools/commands/start_stack.py +428 -0
- 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/validate_data/sparql/cardinality_shacl.py +209 -0
- 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/__init__.py +0 -0
- dsp_tools/commands/xmlupload/iri_resolver.py +21 -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/__init__.py +0 -0
- dsp_tools/commands/xmlupload/models/bitstream_info.py +18 -0
- dsp_tools/commands/xmlupload/models/formatted_text_value.py +10 -0
- dsp_tools/commands/xmlupload/models/ingest.py +143 -0
- dsp_tools/commands/xmlupload/models/input_problems.py +58 -0
- dsp_tools/commands/xmlupload/models/lookup_models.py +21 -0
- dsp_tools/commands/xmlupload/models/permission.py +45 -0
- dsp_tools/commands/xmlupload/models/permissions_parsed.py +93 -0
- 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 +14 -0
- dsp_tools/commands/xmlupload/models/upload_state.py +20 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/__init__.py +0 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/ark2iri.py +55 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/get_processed_resources.py +252 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/iiif_uri_validator.py +50 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/list_client.py +120 -0
- 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 +25 -0
- dsp_tools/commands/xmlupload/richtext_id2iri.py +37 -0
- dsp_tools/commands/xmlupload/stash/__init__.py +0 -0
- dsp_tools/commands/xmlupload/stash/analyse_circular_reference_graph.py +236 -0
- dsp_tools/commands/xmlupload/stash/create_info_for_graph.py +53 -0
- dsp_tools/commands/xmlupload/stash/graph_models.py +87 -0
- dsp_tools/commands/xmlupload/stash/stash_circular_references.py +68 -0
- dsp_tools/commands/xmlupload/stash/stash_models.py +109 -0
- dsp_tools/commands/xmlupload/stash/upload_stashed_resptr_props.py +106 -0
- dsp_tools/commands/xmlupload/stash/upload_stashed_xml_texts.py +196 -0
- dsp_tools/commands/xmlupload/upload_config.py +76 -0
- dsp_tools/commands/xmlupload/write_diagnostic_info.py +27 -0
- dsp_tools/commands/xmlupload/xmlupload.py +516 -0
- dsp_tools/config/__init__.py +0 -0
- dsp_tools/config/logger_config.py +69 -0
- dsp_tools/config/warnings_config.py +32 -0
- 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/legacy_models/datetimestamp.py +81 -0
- dsp_tools/legacy_models/langstring.py +253 -0
- dsp_tools/legacy_models/projectContext.py +49 -0
- dsp_tools/py.typed +0 -0
- dsp_tools/resources/schema/data.xsd +648 -0
- dsp_tools/resources/schema/lists-only.json +72 -0
- dsp_tools/resources/schema/project.json +1258 -0
- dsp_tools/resources/schema/properties-only.json +874 -0
- dsp_tools/resources/schema/resources-only.json +140 -0
- dsp_tools/resources/start-stack/docker-compose.override-host.j2 +11 -0
- dsp_tools/resources/start-stack/docker-compose.override.yml +11 -0
- dsp_tools/resources/start-stack/docker-compose.yml +88 -0
- 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/__init__.py +0 -0
- dsp_tools/utils/ansi_colors.py +32 -0
- dsp_tools/utils/data_formats/__init__.py +0 -0
- dsp_tools/utils/data_formats/date_util.py +166 -0
- dsp_tools/utils/data_formats/iri_util.py +30 -0
- dsp_tools/utils/data_formats/shared.py +81 -0
- dsp_tools/utils/data_formats/uri_util.py +76 -0
- 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/__init__.py +0 -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 +1542 -0
- 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/internal/migration_metadata.py +55 -0
- 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 +348 -0
- dsp_tools/xmllib/value_checkers.py +434 -0
- dsp_tools/xmllib/value_converters.py +777 -0
- 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-18.3.0.post13.dist-info/entry_points.txt +3 -0
- dsp_tools-0.9.13.dist-info/LICENSE +0 -674
- dsp_tools-0.9.13.dist-info/METADATA +0 -144
- dsp_tools-0.9.13.dist-info/RECORD +0 -71
- dsp_tools-0.9.13.dist-info/WHEEL +0 -5
- dsp_tools-0.9.13.dist-info/entry_points.txt +0 -3
- dsp_tools-0.9.13.dist-info/top_level.txt +0 -1
- dsplib/models/connection.py +0 -272
- dsplib/models/group.py +0 -296
- dsplib/models/helpers.py +0 -505
- dsplib/models/langstring.py +0 -277
- dsplib/models/listnode.py +0 -578
- dsplib/models/model.py +0 -20
- dsplib/models/ontology.py +0 -448
- dsplib/models/permission.py +0 -112
- dsplib/models/project.py +0 -547
- dsplib/models/propertyclass.py +0 -505
- dsplib/models/resource.py +0 -366
- dsplib/models/resourceclass.py +0 -810
- dsplib/models/sipi.py +0 -30
- dsplib/models/user.py +0 -731
- dsplib/models/value.py +0 -1000
- dsplib/utils/knora-data-schema.xsd +0 -454
- dsplib/utils/knora-schema-lists.json +0 -83
- dsplib/utils/knora-schema.json +0 -434
- dsplib/utils/onto_commons.py +0 -24
- dsplib/utils/onto_create_lists.py +0 -73
- dsplib/utils/onto_create_ontology.py +0 -442
- dsplib/utils/onto_get.py +0 -58
- dsplib/utils/onto_validate.py +0 -33
- dsplib/utils/xml_upload.py +0 -539
- dsplib/widgets/doublepassword.py +0 -80
- knora/MLS-import-libraries.py +0 -84
- knora/dsp_tools.py +0 -96
- knora/dsplib/models/connection.py +0 -272
- knora/dsplib/models/group.py +0 -296
- knora/dsplib/models/helpers.py +0 -506
- knora/dsplib/models/langstring.py +0 -277
- knora/dsplib/models/listnode.py +0 -578
- knora/dsplib/models/model.py +0 -20
- knora/dsplib/models/ontology.py +0 -448
- knora/dsplib/models/permission.py +0 -112
- knora/dsplib/models/project.py +0 -583
- knora/dsplib/models/propertyclass.py +0 -505
- knora/dsplib/models/resource.py +0 -416
- knora/dsplib/models/resourceclass.py +0 -811
- knora/dsplib/models/sipi.py +0 -35
- knora/dsplib/models/user.py +0 -731
- knora/dsplib/models/value.py +0 -1000
- knora/dsplib/utils/knora-data-schema.xsd +0 -464
- knora/dsplib/utils/knora-schema-lists.json +0 -83
- knora/dsplib/utils/knora-schema.json +0 -444
- knora/dsplib/utils/onto_commons.py +0 -24
- knora/dsplib/utils/onto_create_lists.py +0 -73
- knora/dsplib/utils/onto_create_ontology.py +0 -451
- knora/dsplib/utils/onto_get.py +0 -58
- knora/dsplib/utils/onto_validate.py +0 -33
- knora/dsplib/utils/xml_upload.py +0 -540
- knora/dsplib/widgets/doublepassword.py +0 -80
- knora/knora.py +0 -2108
- knora/test.py +0 -99
- knora/testit.py +0 -76
- knora/xml2knora.py +0 -633
- {dsplib → dsp_tools/cli}/__init__.py +0 -0
- {dsplib/models → dsp_tools/clients}/__init__.py +0 -0
- {dsplib/utils → dsp_tools/commands}/__init__.py +0 -0
- {dsplib/widgets → dsp_tools/commands/create}/__init__.py +0 -0
- {knora → dsp_tools/commands/create/create_on_server}/__init__.py +0 -0
- {knora/dsplib → dsp_tools/commands/create/models}/__init__.py +0 -0
- {knora/dsplib/models → dsp_tools/commands/create/parsing}/__init__.py +0 -0
- {knora/dsplib/utils → dsp_tools/commands/create/serialisation}/__init__.py +0 -0
- {knora/dsplib/widgets → dsp_tools/commands/excel2json}/__init__.py +0 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import importlib.resources
|
|
2
|
+
import subprocess
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import yaml
|
|
6
|
+
from loguru import logger
|
|
7
|
+
from rdflib import SH
|
|
8
|
+
from rdflib import Graph
|
|
9
|
+
|
|
10
|
+
from dsp_tools.commands.validate_data.models.api_responses import SHACLValidationReport
|
|
11
|
+
from dsp_tools.commands.validate_data.models.validation import ValidationFilePaths
|
|
12
|
+
from dsp_tools.config.logger_config import LOGGER_SAVEPATH
|
|
13
|
+
from dsp_tools.error.exceptions import InternalError
|
|
14
|
+
from dsp_tools.error.exceptions import ShaclValidationCliError
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ShaclCliValidator:
|
|
18
|
+
def validate(self, file_paths: ValidationFilePaths) -> SHACLValidationReport:
|
|
19
|
+
try:
|
|
20
|
+
self._run_validate_cli(file_paths)
|
|
21
|
+
except subprocess.CalledProcessError as e:
|
|
22
|
+
logger.error(e)
|
|
23
|
+
msg = (
|
|
24
|
+
"Data validation requires Docker. Is your Docker Desktop Application open? "
|
|
25
|
+
"If it is, please contact the DSP-TOOLS development team (at support@dasch.swiss) "
|
|
26
|
+
f"with the log file at {LOGGER_SAVEPATH}."
|
|
27
|
+
)
|
|
28
|
+
logger.error(msg)
|
|
29
|
+
raise ShaclValidationCliError(msg) from None
|
|
30
|
+
return self._parse_validation_result(file_paths.directory / file_paths.report_file)
|
|
31
|
+
|
|
32
|
+
def _run_validate_cli(self, file_paths: ValidationFilePaths) -> None:
|
|
33
|
+
if not (file_paths.directory / file_paths.shacl_file).exists():
|
|
34
|
+
raise InternalError(f"SHACL file not found: {file_paths.shacl_file}")
|
|
35
|
+
if not (file_paths.directory / file_paths.data_file).exists():
|
|
36
|
+
raise InternalError(f"Data file not found: {file_paths.data_file}")
|
|
37
|
+
|
|
38
|
+
# Get relative paths within the container
|
|
39
|
+
shacl_path = f"/data/{file_paths.shacl_file}"
|
|
40
|
+
data_path = f"/data/{file_paths.data_file}"
|
|
41
|
+
report_path = f"/data/{file_paths.report_file}"
|
|
42
|
+
|
|
43
|
+
docker_file = importlib.resources.files("dsp_tools").joinpath("resources/validate_data/shacl-cli-image.yml")
|
|
44
|
+
docker_spec = yaml.safe_load(docker_file.read_bytes())
|
|
45
|
+
docker_image = docker_spec["image"]
|
|
46
|
+
|
|
47
|
+
d_cmd = (
|
|
48
|
+
f"docker run --rm -v {file_paths.directory.absolute()}:/data {docker_image} "
|
|
49
|
+
f"validate --shacl {shacl_path} --data {data_path} --report {report_path}"
|
|
50
|
+
)
|
|
51
|
+
logger.debug(f"Running SHACL validation: {d_cmd}")
|
|
52
|
+
result = subprocess.run(
|
|
53
|
+
d_cmd.split(),
|
|
54
|
+
capture_output=True,
|
|
55
|
+
text=True,
|
|
56
|
+
check=True,
|
|
57
|
+
)
|
|
58
|
+
if result.stdout:
|
|
59
|
+
logger.debug(f"Validation output: {result.stdout}")
|
|
60
|
+
if result.stderr:
|
|
61
|
+
logger.error(f"Validation output error: {result.stderr}")
|
|
62
|
+
|
|
63
|
+
def _parse_validation_result(self, filepath: Path) -> SHACLValidationReport:
|
|
64
|
+
if not filepath.exists():
|
|
65
|
+
raise InternalError(f"SHACL file not found: {filepath}")
|
|
66
|
+
logger.debug(f"Parse validation response: {filepath}.")
|
|
67
|
+
graph = Graph()
|
|
68
|
+
graph.parse(filepath)
|
|
69
|
+
conforms = bool(next(graph.objects(None, SH.conforms)))
|
|
70
|
+
return SHACLValidationReport(conforms=conforms, validation_graph=graph)
|
|
File without changes
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
from loguru import logger
|
|
2
|
+
from rdflib import Graph
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def construct_cardinality_node_shapes(onto: Graph) -> Graph:
|
|
6
|
+
"""
|
|
7
|
+
Returns the sh:NodeShapes for the resource classes in the ontology.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
onto: ontology graph
|
|
11
|
+
|
|
12
|
+
Returns:
|
|
13
|
+
Graph with the resource class node shapes
|
|
14
|
+
"""
|
|
15
|
+
logger.debug("Constructing cardinality shapes for the ontology.")
|
|
16
|
+
g = Graph()
|
|
17
|
+
g += _construct_resource_nodeshape(onto)
|
|
18
|
+
g += _construct_all_cardinalities(onto)
|
|
19
|
+
return g
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _construct_resource_nodeshape(onto_graph: Graph) -> Graph:
|
|
23
|
+
logger.debug("Constructing resource NodeShape")
|
|
24
|
+
query_s = """
|
|
25
|
+
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
26
|
+
PREFIX sh: <http://www.w3.org/ns/shacl#>
|
|
27
|
+
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
|
28
|
+
PREFIX api-shapes: <http://api.knora.org/ontology/knora-api/shapes/v2#>
|
|
29
|
+
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
|
|
30
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
31
|
+
PREFIX dash: <http://datashapes.org/dash#>
|
|
32
|
+
|
|
33
|
+
CONSTRUCT {
|
|
34
|
+
?class a sh:NodeShape ;
|
|
35
|
+
dash:closedByTypes true ;
|
|
36
|
+
sh:property api-shapes:hasPermissions_Cardinality ,
|
|
37
|
+
[
|
|
38
|
+
a sh:PropertyShape ;
|
|
39
|
+
sh:path rdfs:label ;
|
|
40
|
+
sh:minCount 1 ;
|
|
41
|
+
sh:maxCount 1 ;
|
|
42
|
+
sh:severity sh:Violation ;
|
|
43
|
+
sh:message "A label is required"
|
|
44
|
+
] ,
|
|
45
|
+
[
|
|
46
|
+
a sh:PropertyShape ;
|
|
47
|
+
sh:path knora-api:hasStandoffLinkTo
|
|
48
|
+
] .
|
|
49
|
+
} WHERE {
|
|
50
|
+
?class a owl:Class ;
|
|
51
|
+
knora-api:isResourceClass true ;
|
|
52
|
+
knora-api:canBeInstantiated true .
|
|
53
|
+
}
|
|
54
|
+
"""
|
|
55
|
+
if results_graph := onto_graph.query(query_s).graph:
|
|
56
|
+
return results_graph
|
|
57
|
+
return Graph()
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _construct_all_cardinalities(onto_graph: Graph) -> Graph:
|
|
61
|
+
g = Graph()
|
|
62
|
+
g += _construct_1_cardinality(onto_graph)
|
|
63
|
+
g += _construct_0_1_cardinality(onto_graph)
|
|
64
|
+
g += _construct_1_n_cardinality(onto_graph)
|
|
65
|
+
g += _construct_0_n_cardinality(onto_graph)
|
|
66
|
+
return g
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _construct_1_cardinality(onto_graph: Graph) -> Graph:
|
|
70
|
+
logger.debug("Constructing cardinality: 1")
|
|
71
|
+
query_s = """
|
|
72
|
+
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
73
|
+
PREFIX sh: <http://www.w3.org/ns/shacl#>
|
|
74
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
75
|
+
PREFIX api-shapes: <http://api.knora.org/ontology/knora-api/shapes/v2#>
|
|
76
|
+
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
|
|
77
|
+
PREFIX dash: <http://datashapes.org/dash#>
|
|
78
|
+
|
|
79
|
+
CONSTRUCT {
|
|
80
|
+
?class sh:property [
|
|
81
|
+
a sh:PropertyShape ;
|
|
82
|
+
sh:path ?propRestriction ;
|
|
83
|
+
sh:minCount 1 ;
|
|
84
|
+
sh:maxCount 1 ;
|
|
85
|
+
sh:severity sh:Violation ;
|
|
86
|
+
sh:message "Cardinality 1"
|
|
87
|
+
] .
|
|
88
|
+
} WHERE {
|
|
89
|
+
?class a owl:Class ;
|
|
90
|
+
knora-api:isResourceClass true ;
|
|
91
|
+
knora-api:canBeInstantiated true ;
|
|
92
|
+
rdfs:subClassOf ?restriction .
|
|
93
|
+
?restriction a owl:Restriction ;
|
|
94
|
+
owl:onProperty ?propRestriction ;
|
|
95
|
+
owl:cardinality 1 .
|
|
96
|
+
|
|
97
|
+
?propRestriction knora-api:isEditable true .
|
|
98
|
+
FILTER NOT EXISTS { ?propRestriction knora-api:isLinkValueProperty true }
|
|
99
|
+
}
|
|
100
|
+
"""
|
|
101
|
+
if results_graph := onto_graph.query(query_s).graph:
|
|
102
|
+
return results_graph
|
|
103
|
+
return Graph()
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _construct_0_1_cardinality(onto_graph: Graph) -> Graph:
|
|
107
|
+
logger.debug("Constructing cardinality: 0-1")
|
|
108
|
+
query_s = """
|
|
109
|
+
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
110
|
+
PREFIX sh: <http://www.w3.org/ns/shacl#>
|
|
111
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
112
|
+
PREFIX api-shapes: <http://api.knora.org/ontology/knora-api/shapes/v2#>
|
|
113
|
+
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
|
|
114
|
+
PREFIX dash: <http://datashapes.org/dash#>
|
|
115
|
+
|
|
116
|
+
CONSTRUCT {
|
|
117
|
+
?class sh:property [
|
|
118
|
+
a sh:PropertyShape ;
|
|
119
|
+
sh:path ?propRestriction ;
|
|
120
|
+
sh:minCount 0 ;
|
|
121
|
+
sh:maxCount 1 ;
|
|
122
|
+
sh:severity sh:Violation ;
|
|
123
|
+
sh:message "Cardinality 0-1"
|
|
124
|
+
] .
|
|
125
|
+
} WHERE {
|
|
126
|
+
?class a owl:Class ;
|
|
127
|
+
knora-api:isResourceClass true ;
|
|
128
|
+
knora-api:canBeInstantiated true ;
|
|
129
|
+
rdfs:subClassOf ?restriction .
|
|
130
|
+
?restriction a owl:Restriction ;
|
|
131
|
+
owl:onProperty ?propRestriction ;
|
|
132
|
+
owl:maxCardinality 1 .
|
|
133
|
+
|
|
134
|
+
?propRestriction knora-api:isEditable true .
|
|
135
|
+
FILTER NOT EXISTS { ?propRestriction knora-api:isLinkValueProperty true }
|
|
136
|
+
}
|
|
137
|
+
"""
|
|
138
|
+
if results_graph := onto_graph.query(query_s).graph:
|
|
139
|
+
return results_graph
|
|
140
|
+
return Graph()
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _construct_1_n_cardinality(onto_graph: Graph) -> Graph:
|
|
144
|
+
logger.debug("Constructing cardinality: 1-n")
|
|
145
|
+
query_s = """
|
|
146
|
+
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
147
|
+
PREFIX sh: <http://www.w3.org/ns/shacl#>
|
|
148
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
149
|
+
PREFIX api-shapes: <http://api.knora.org/ontology/knora-api/shapes/v2#>
|
|
150
|
+
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
|
|
151
|
+
PREFIX dash: <http://datashapes.org/dash#>
|
|
152
|
+
|
|
153
|
+
CONSTRUCT {
|
|
154
|
+
?class sh:property [
|
|
155
|
+
a sh:PropertyShape ;
|
|
156
|
+
sh:path ?propRestriction ;
|
|
157
|
+
sh:minCount 1 ;
|
|
158
|
+
sh:severity sh:Violation ;
|
|
159
|
+
sh:message "Cardinality 1-n"
|
|
160
|
+
] .
|
|
161
|
+
} WHERE {
|
|
162
|
+
?class a owl:Class ;
|
|
163
|
+
knora-api:isResourceClass true ;
|
|
164
|
+
knora-api:canBeInstantiated true ;
|
|
165
|
+
rdfs:subClassOf ?restriction .
|
|
166
|
+
?restriction a owl:Restriction ;
|
|
167
|
+
owl:onProperty ?propRestriction ;
|
|
168
|
+
owl:minCardinality 1 .
|
|
169
|
+
|
|
170
|
+
?propRestriction knora-api:isEditable true .
|
|
171
|
+
FILTER NOT EXISTS { ?propRestriction knora-api:isLinkValueProperty true }
|
|
172
|
+
}
|
|
173
|
+
"""
|
|
174
|
+
if results_graph := onto_graph.query(query_s).graph:
|
|
175
|
+
return results_graph
|
|
176
|
+
return Graph()
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def _construct_0_n_cardinality(onto_graph: Graph) -> Graph:
|
|
180
|
+
logger.debug("Constructing cardinality: 0-n")
|
|
181
|
+
query_s = """
|
|
182
|
+
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
183
|
+
PREFIX sh: <http://www.w3.org/ns/shacl#>
|
|
184
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
185
|
+
PREFIX api-shapes: <http://api.knora.org/ontology/knora-api/shapes/v2#>
|
|
186
|
+
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
|
|
187
|
+
PREFIX dash: <http://datashapes.org/dash#>
|
|
188
|
+
|
|
189
|
+
CONSTRUCT {
|
|
190
|
+
?class sh:property [
|
|
191
|
+
a sh:PropertyShape ;
|
|
192
|
+
sh:path ?propRestriction
|
|
193
|
+
] .
|
|
194
|
+
} WHERE {
|
|
195
|
+
?class a owl:Class ;
|
|
196
|
+
knora-api:isResourceClass true ;
|
|
197
|
+
knora-api:canBeInstantiated true ;
|
|
198
|
+
rdfs:subClassOf ?restriction .
|
|
199
|
+
?restriction a owl:Restriction ;
|
|
200
|
+
owl:onProperty ?propRestriction ;
|
|
201
|
+
owl:minCardinality 0 .
|
|
202
|
+
|
|
203
|
+
?propRestriction knora-api:isEditable true .
|
|
204
|
+
FILTER NOT EXISTS { ?propRestriction knora-api:isLinkValueProperty true }
|
|
205
|
+
}
|
|
206
|
+
"""
|
|
207
|
+
if results_graph := onto_graph.query(query_s).graph:
|
|
208
|
+
return results_graph
|
|
209
|
+
return Graph()
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
from loguru import logger
|
|
2
|
+
from rdflib import Graph
|
|
3
|
+
|
|
4
|
+
from dsp_tools.commands.validate_data.models.api_responses import ProjectDataFromApi
|
|
5
|
+
from dsp_tools.commands.validate_data.models.validation import SHACLGraphs
|
|
6
|
+
from dsp_tools.commands.validate_data.sparql.cardinality_shacl import construct_cardinality_node_shapes
|
|
7
|
+
from dsp_tools.commands.validate_data.sparql.legal_info_shacl import construct_allowed_licenses_shape
|
|
8
|
+
from dsp_tools.commands.validate_data.sparql.value_shacl import construct_property_shapes
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def construct_shapes_graphs(
|
|
12
|
+
onto: Graph,
|
|
13
|
+
knora_api: Graph,
|
|
14
|
+
project_info_from_api: ProjectDataFromApi,
|
|
15
|
+
permission_ids: list[str],
|
|
16
|
+
) -> SHACLGraphs:
|
|
17
|
+
"""
|
|
18
|
+
Constructs a shapes graph from a project ontology
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
onto: ontology as graph
|
|
22
|
+
knora_api: the knora-api ontology
|
|
23
|
+
project_info_from_api: information from a project from the api, for example lists
|
|
24
|
+
permission_ids: ids of permissions that were defined in the XML
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
shapes graph
|
|
28
|
+
"""
|
|
29
|
+
logger.debug("Constructing SHACL shapes from ontology.")
|
|
30
|
+
knora_subset = _get_all_relevant_knora_subset(knora_api)
|
|
31
|
+
graph_to_query = knora_subset + onto
|
|
32
|
+
cardinality = construct_cardinality_node_shapes(graph_to_query)
|
|
33
|
+
content = construct_property_shapes(graph_to_query, project_info_from_api.all_lists)
|
|
34
|
+
content += construct_allowed_licenses_shape(project_info_from_api.enabled_licenses)
|
|
35
|
+
content += _get_defined_permissions_shape(permission_ids)
|
|
36
|
+
return SHACLGraphs(cardinality=cardinality, content=content)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _get_all_relevant_knora_subset(knora_api: Graph) -> Graph:
|
|
40
|
+
logger.debug("Getting relevant knora-api subset")
|
|
41
|
+
props = ["isLinkProperty", "isEditable", "isLinkValueProperty"]
|
|
42
|
+
g = Graph()
|
|
43
|
+
for p in props:
|
|
44
|
+
g += _get_one_relevant_knora_subset(knora_api, p)
|
|
45
|
+
return g
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _get_one_relevant_knora_subset(knora_api: Graph, knora_prop: str) -> Graph:
|
|
49
|
+
query_s = """
|
|
50
|
+
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
51
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
52
|
+
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
|
|
53
|
+
|
|
54
|
+
CONSTRUCT {
|
|
55
|
+
|
|
56
|
+
?focusProp a owl:ObjectProperty ;
|
|
57
|
+
knora-api:objectType ?type ;
|
|
58
|
+
knora-api:%(knora_prop)s ?object .
|
|
59
|
+
|
|
60
|
+
} WHERE {
|
|
61
|
+
|
|
62
|
+
?focusProp a owl:ObjectProperty ;
|
|
63
|
+
knora-api:objectType ?type ;
|
|
64
|
+
knora-api:%(knora_prop)s ?object .
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
""" % {"knora_prop": knora_prop} # noqa: UP031 (printf-string-formatting)
|
|
68
|
+
if results_graph := knora_api.query(query_s).graph:
|
|
69
|
+
return results_graph
|
|
70
|
+
return Graph()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _get_defined_permissions_shape(permission_ids: list[str]) -> Graph:
|
|
74
|
+
g = Graph()
|
|
75
|
+
permissions = " ".join([f'"{x}"' for x in permission_ids])
|
|
76
|
+
msg = f"You must reference one of the pre-defined permissions: {', '.join(permission_ids)}"
|
|
77
|
+
shape = f"""
|
|
78
|
+
@prefix sh: <http://www.w3.org/ns/shacl#> .
|
|
79
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
|
80
|
+
@prefix knora-api: <http://api.knora.org/ontology/knora-api/v2#> .
|
|
81
|
+
@prefix api-shapes: <http://api.knora.org/ontology/knora-api/shapes/v2#> .
|
|
82
|
+
|
|
83
|
+
api-shapes:hasPermissions_Shape
|
|
84
|
+
a sh:NodeShape ;
|
|
85
|
+
sh:targetClass knora-api:Value , knora-api:Resource ;
|
|
86
|
+
sh:path knora-api:hasPermissions ;
|
|
87
|
+
sh:in ( {permissions} ) ;
|
|
88
|
+
sh:message "{msg}" ;
|
|
89
|
+
sh:severity sh:Violation .
|
|
90
|
+
"""
|
|
91
|
+
g.parse(data=shape, format="turtle")
|
|
92
|
+
return g
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from loguru import logger
|
|
2
|
+
from rdflib import Graph
|
|
3
|
+
|
|
4
|
+
from dsp_tools.commands.validate_data.models.api_responses import EnabledLicenseIris
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def construct_allowed_licenses_shape(license_iris: EnabledLicenseIris) -> Graph:
|
|
8
|
+
"""Create a constraint detailing the allowed licences."""
|
|
9
|
+
formatted_iris = [f"<{x}>" for x in license_iris.enabled_licenses]
|
|
10
|
+
license_str = " ".join(formatted_iris)
|
|
11
|
+
if len(formatted_iris) == 0:
|
|
12
|
+
msg_str = '"You are only allowed to reference enabled licenses. No licenses are enabled for this project."'
|
|
13
|
+
else:
|
|
14
|
+
msg_str = (
|
|
15
|
+
'"Please only use enabled licenses in your data. Consult the project information for enabled licenses."'
|
|
16
|
+
)
|
|
17
|
+
logger.debug("Constructing allowed licenses shapes.")
|
|
18
|
+
ttl_str = """
|
|
19
|
+
@prefix sh: <http://www.w3.org/ns/shacl#> .
|
|
20
|
+
@prefix knora-api: <http://api.knora.org/ontology/knora-api/v2#> .
|
|
21
|
+
@prefix api-shapes: <http://api.knora.org/ontology/knora-api/shapes/v2#> .
|
|
22
|
+
|
|
23
|
+
api-shapes:FileValue_ClassShape
|
|
24
|
+
a sh:NodeShape ;
|
|
25
|
+
sh:targetClass knora-api:FileValue ;
|
|
26
|
+
sh:property [
|
|
27
|
+
a sh:PropertyShape ;
|
|
28
|
+
sh:path knora-api:hasLicense ;
|
|
29
|
+
sh:in ( %(license_str)s ) ;
|
|
30
|
+
sh:message %(msg)s ;
|
|
31
|
+
sh:severity sh:Violation
|
|
32
|
+
] .
|
|
33
|
+
""" % {"license_str": license_str, "msg": msg_str} # noqa: UP031 Use format specifiers instead of percent format
|
|
34
|
+
g = Graph()
|
|
35
|
+
g.parse(data=ttl_str, format="turtle")
|
|
36
|
+
return g
|