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
|
@@ -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
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
from loguru import logger
|
|
1
2
|
from rdflib import Graph
|
|
2
3
|
|
|
3
4
|
|
|
4
|
-
def
|
|
5
|
+
def construct_cardinality_node_shapes(onto: Graph) -> Graph:
|
|
5
6
|
"""
|
|
6
7
|
Returns the sh:NodeShapes for the resource classes in the ontology.
|
|
7
8
|
|
|
@@ -11,6 +12,7 @@ def construct_resource_class_node_shape(onto: Graph) -> Graph:
|
|
|
11
12
|
Returns:
|
|
12
13
|
Graph with the resource class node shapes
|
|
13
14
|
"""
|
|
15
|
+
logger.debug("Constructing cardinality shapes for the ontology.")
|
|
14
16
|
g = Graph()
|
|
15
17
|
g += _construct_resource_nodeshape(onto)
|
|
16
18
|
g += _construct_all_cardinalities(onto)
|
|
@@ -18,6 +20,7 @@ def construct_resource_class_node_shape(onto: Graph) -> Graph:
|
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
def _construct_resource_nodeshape(onto_graph: Graph) -> Graph:
|
|
23
|
+
logger.debug("Constructing resource NodeShape")
|
|
21
24
|
query_s = """
|
|
22
25
|
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
23
26
|
PREFIX sh: <http://www.w3.org/ns/shacl#>
|
|
@@ -25,21 +28,28 @@ def _construct_resource_nodeshape(onto_graph: Graph) -> Graph:
|
|
|
25
28
|
PREFIX api-shapes: <http://api.knora.org/ontology/knora-api/shapes/v2#>
|
|
26
29
|
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
|
|
27
30
|
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
31
|
+
PREFIX dash: <http://datashapes.org/dash#>
|
|
28
32
|
|
|
29
33
|
CONSTRUCT {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
sh:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
+
] .
|
|
36
49
|
} WHERE {
|
|
37
|
-
|
|
38
50
|
?class a owl:Class ;
|
|
39
51
|
knora-api:isResourceClass true ;
|
|
40
52
|
knora-api:canBeInstantiated true .
|
|
41
|
-
|
|
42
|
-
BIND(IRI(CONCAT(str(?class), "_Shape")) AS ?shapesIRI)
|
|
43
53
|
}
|
|
44
54
|
"""
|
|
45
55
|
if results_graph := onto_graph.query(query_s).graph:
|
|
@@ -57,38 +67,35 @@ def _construct_all_cardinalities(onto_graph: Graph) -> Graph:
|
|
|
57
67
|
|
|
58
68
|
|
|
59
69
|
def _construct_1_cardinality(onto_graph: Graph) -> Graph:
|
|
70
|
+
logger.debug("Constructing cardinality: 1")
|
|
60
71
|
query_s = """
|
|
61
72
|
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
62
73
|
PREFIX sh: <http://www.w3.org/ns/shacl#>
|
|
63
74
|
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
64
|
-
PREFIX salsah-gui: <http://api.knora.org/ontology/salsah-gui/v2#>
|
|
65
75
|
PREFIX api-shapes: <http://api.knora.org/ontology/knora-api/shapes/v2#>
|
|
66
76
|
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
|
|
67
|
-
|
|
77
|
+
PREFIX dash: <http://datashapes.org/dash#>
|
|
78
|
+
|
|
68
79
|
CONSTRUCT {
|
|
69
|
-
|
|
70
|
-
?shapesIRI sh:property [
|
|
80
|
+
?class sh:property [
|
|
71
81
|
a sh:PropertyShape ;
|
|
72
82
|
sh:path ?propRestriction ;
|
|
73
83
|
sh:minCount 1 ;
|
|
74
84
|
sh:maxCount 1 ;
|
|
75
85
|
sh:severity sh:Violation ;
|
|
76
|
-
sh:message "1"
|
|
86
|
+
sh:message "Cardinality 1"
|
|
77
87
|
] .
|
|
78
|
-
|
|
79
88
|
} WHERE {
|
|
80
|
-
|
|
81
89
|
?class a owl:Class ;
|
|
82
90
|
knora-api:isResourceClass true ;
|
|
83
91
|
knora-api:canBeInstantiated true ;
|
|
84
92
|
rdfs:subClassOf ?restriction .
|
|
85
93
|
?restriction a owl:Restriction ;
|
|
86
94
|
owl:onProperty ?propRestriction ;
|
|
87
|
-
salsah-gui:guiOrder ?order ;
|
|
88
95
|
owl:cardinality 1 .
|
|
96
|
+
|
|
97
|
+
?propRestriction knora-api:isEditable true .
|
|
89
98
|
FILTER NOT EXISTS { ?propRestriction knora-api:isLinkValueProperty true }
|
|
90
|
-
|
|
91
|
-
BIND(IRI(CONCAT(str(?class), "_Shape")) AS ?shapesIRI)
|
|
92
99
|
}
|
|
93
100
|
"""
|
|
94
101
|
if results_graph := onto_graph.query(query_s).graph:
|
|
@@ -97,38 +104,35 @@ def _construct_1_cardinality(onto_graph: Graph) -> Graph:
|
|
|
97
104
|
|
|
98
105
|
|
|
99
106
|
def _construct_0_1_cardinality(onto_graph: Graph) -> Graph:
|
|
107
|
+
logger.debug("Constructing cardinality: 0-1")
|
|
100
108
|
query_s = """
|
|
101
109
|
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
102
110
|
PREFIX sh: <http://www.w3.org/ns/shacl#>
|
|
103
111
|
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
104
|
-
PREFIX salsah-gui: <http://api.knora.org/ontology/salsah-gui/v2#>
|
|
105
112
|
PREFIX api-shapes: <http://api.knora.org/ontology/knora-api/shapes/v2#>
|
|
106
113
|
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
|
|
114
|
+
PREFIX dash: <http://datashapes.org/dash#>
|
|
107
115
|
|
|
108
116
|
CONSTRUCT {
|
|
109
|
-
|
|
110
|
-
?shapesIRI sh:property [
|
|
117
|
+
?class sh:property [
|
|
111
118
|
a sh:PropertyShape ;
|
|
112
119
|
sh:path ?propRestriction ;
|
|
113
120
|
sh:minCount 0 ;
|
|
114
121
|
sh:maxCount 1 ;
|
|
115
122
|
sh:severity sh:Violation ;
|
|
116
|
-
sh:message "0-1"
|
|
123
|
+
sh:message "Cardinality 0-1"
|
|
117
124
|
] .
|
|
118
|
-
|
|
119
125
|
} WHERE {
|
|
120
|
-
|
|
121
126
|
?class a owl:Class ;
|
|
122
127
|
knora-api:isResourceClass true ;
|
|
123
128
|
knora-api:canBeInstantiated true ;
|
|
124
129
|
rdfs:subClassOf ?restriction .
|
|
125
130
|
?restriction a owl:Restriction ;
|
|
126
131
|
owl:onProperty ?propRestriction ;
|
|
127
|
-
salsah-gui:guiOrder ?order ;
|
|
128
132
|
owl:maxCardinality 1 .
|
|
133
|
+
|
|
134
|
+
?propRestriction knora-api:isEditable true .
|
|
129
135
|
FILTER NOT EXISTS { ?propRestriction knora-api:isLinkValueProperty true }
|
|
130
|
-
|
|
131
|
-
BIND(IRI(CONCAT(str(?class), "_Shape")) AS ?shapesIRI)
|
|
132
136
|
}
|
|
133
137
|
"""
|
|
134
138
|
if results_graph := onto_graph.query(query_s).graph:
|
|
@@ -137,37 +141,34 @@ def _construct_0_1_cardinality(onto_graph: Graph) -> Graph:
|
|
|
137
141
|
|
|
138
142
|
|
|
139
143
|
def _construct_1_n_cardinality(onto_graph: Graph) -> Graph:
|
|
144
|
+
logger.debug("Constructing cardinality: 1-n")
|
|
140
145
|
query_s = """
|
|
141
146
|
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
142
147
|
PREFIX sh: <http://www.w3.org/ns/shacl#>
|
|
143
148
|
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
144
|
-
PREFIX salsah-gui: <http://api.knora.org/ontology/salsah-gui/v2#>
|
|
145
149
|
PREFIX api-shapes: <http://api.knora.org/ontology/knora-api/shapes/v2#>
|
|
146
150
|
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
|
|
151
|
+
PREFIX dash: <http://datashapes.org/dash#>
|
|
147
152
|
|
|
148
153
|
CONSTRUCT {
|
|
149
|
-
|
|
150
|
-
?shapesIRI sh:property [
|
|
154
|
+
?class sh:property [
|
|
151
155
|
a sh:PropertyShape ;
|
|
152
156
|
sh:path ?propRestriction ;
|
|
153
157
|
sh:minCount 1 ;
|
|
154
158
|
sh:severity sh:Violation ;
|
|
155
|
-
sh:message "1-n"
|
|
159
|
+
sh:message "Cardinality 1-n"
|
|
156
160
|
] .
|
|
157
|
-
|
|
158
161
|
} WHERE {
|
|
159
|
-
|
|
160
162
|
?class a owl:Class ;
|
|
161
163
|
knora-api:isResourceClass true ;
|
|
162
164
|
knora-api:canBeInstantiated true ;
|
|
163
165
|
rdfs:subClassOf ?restriction .
|
|
164
166
|
?restriction a owl:Restriction ;
|
|
165
167
|
owl:onProperty ?propRestriction ;
|
|
166
|
-
salsah-gui:guiOrder ?order ;
|
|
167
168
|
owl:minCardinality 1 .
|
|
169
|
+
|
|
170
|
+
?propRestriction knora-api:isEditable true .
|
|
168
171
|
FILTER NOT EXISTS { ?propRestriction knora-api:isLinkValueProperty true }
|
|
169
|
-
|
|
170
|
-
BIND(IRI(CONCAT(str(?class), "_Shape")) AS ?shapesIRI)
|
|
171
172
|
}
|
|
172
173
|
"""
|
|
173
174
|
if results_graph := onto_graph.query(query_s).graph:
|
|
@@ -176,34 +177,31 @@ def _construct_1_n_cardinality(onto_graph: Graph) -> Graph:
|
|
|
176
177
|
|
|
177
178
|
|
|
178
179
|
def _construct_0_n_cardinality(onto_graph: Graph) -> Graph:
|
|
180
|
+
logger.debug("Constructing cardinality: 0-n")
|
|
179
181
|
query_s = """
|
|
180
182
|
PREFIX owl: <http://www.w3.org/2002/07/owl#>
|
|
181
183
|
PREFIX sh: <http://www.w3.org/ns/shacl#>
|
|
182
184
|
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
|
183
|
-
PREFIX salsah-gui: <http://api.knora.org/ontology/salsah-gui/v2#>
|
|
184
185
|
PREFIX api-shapes: <http://api.knora.org/ontology/knora-api/shapes/v2#>
|
|
185
186
|
PREFIX knora-api: <http://api.knora.org/ontology/knora-api/v2#>
|
|
187
|
+
PREFIX dash: <http://datashapes.org/dash#>
|
|
186
188
|
|
|
187
189
|
CONSTRUCT {
|
|
188
|
-
|
|
189
|
-
?shapesIRI sh:property [
|
|
190
|
+
?class sh:property [
|
|
190
191
|
a sh:PropertyShape ;
|
|
191
|
-
sh:path ?propRestriction
|
|
192
|
+
sh:path ?propRestriction
|
|
192
193
|
] .
|
|
193
|
-
|
|
194
194
|
} WHERE {
|
|
195
|
-
|
|
196
195
|
?class a owl:Class ;
|
|
197
196
|
knora-api:isResourceClass true ;
|
|
198
197
|
knora-api:canBeInstantiated true ;
|
|
199
198
|
rdfs:subClassOf ?restriction .
|
|
200
199
|
?restriction a owl:Restriction ;
|
|
201
200
|
owl:onProperty ?propRestriction ;
|
|
202
|
-
salsah-gui:guiOrder ?order ;
|
|
203
201
|
owl:minCardinality 0 .
|
|
202
|
+
|
|
203
|
+
?propRestriction knora-api:isEditable true .
|
|
204
204
|
FILTER NOT EXISTS { ?propRestriction knora-api:isLinkValueProperty true }
|
|
205
|
-
|
|
206
|
-
BIND(IRI(CONCAT(str(?class), "_Shape")) AS ?shapesIRI)
|
|
207
205
|
}
|
|
208
206
|
"""
|
|
209
207
|
if results_graph := onto_graph.query(query_s).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
|