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.
Files changed (316) hide show
  1. dsp_tools/__init__.py +4 -0
  2. dsp_tools/cli/args.py +36 -0
  3. dsp_tools/cli/call_action.py +51 -231
  4. dsp_tools/cli/call_action_files_only.py +101 -0
  5. dsp_tools/cli/call_action_with_network.py +207 -0
  6. dsp_tools/cli/create_parsers.py +156 -58
  7. dsp_tools/cli/entry_point.py +56 -26
  8. dsp_tools/cli/utils.py +87 -0
  9. dsp_tools/clients/CLAUDE.md +420 -0
  10. dsp_tools/clients/authentication_client.py +14 -0
  11. dsp_tools/clients/authentication_client_live.py +66 -0
  12. dsp_tools/{utils → clients}/connection.py +2 -18
  13. dsp_tools/clients/connection_live.py +233 -0
  14. dsp_tools/clients/fuseki_metrics.py +60 -0
  15. dsp_tools/clients/group_user_clients.py +35 -0
  16. dsp_tools/clients/group_user_clients_live.py +181 -0
  17. dsp_tools/clients/legal_info_client.py +23 -0
  18. dsp_tools/clients/legal_info_client_live.py +132 -0
  19. dsp_tools/clients/list_client.py +49 -0
  20. dsp_tools/clients/list_client_live.py +166 -0
  21. dsp_tools/clients/metadata_client.py +24 -0
  22. dsp_tools/clients/metadata_client_live.py +47 -0
  23. dsp_tools/clients/ontology_clients.py +49 -0
  24. dsp_tools/clients/ontology_create_client_live.py +166 -0
  25. dsp_tools/clients/ontology_get_client_live.py +80 -0
  26. dsp_tools/clients/permissions_client.py +68 -0
  27. dsp_tools/clients/project_client.py +16 -0
  28. dsp_tools/clients/project_client_live.py +66 -0
  29. dsp_tools/commands/create/communicate_problems.py +24 -0
  30. dsp_tools/commands/create/create.py +134 -0
  31. dsp_tools/commands/create/create_on_server/cardinalities.py +111 -0
  32. dsp_tools/commands/create/create_on_server/classes.py +99 -0
  33. dsp_tools/commands/create/create_on_server/complete_ontologies.py +116 -0
  34. dsp_tools/commands/create/create_on_server/default_permissions.py +134 -0
  35. dsp_tools/commands/create/create_on_server/group_users.py +165 -0
  36. dsp_tools/commands/create/create_on_server/lists.py +163 -0
  37. dsp_tools/commands/create/create_on_server/mappers.py +12 -0
  38. dsp_tools/commands/create/create_on_server/onto_utils.py +74 -0
  39. dsp_tools/commands/create/create_on_server/ontology.py +52 -0
  40. dsp_tools/commands/create/create_on_server/project.py +68 -0
  41. dsp_tools/commands/create/create_on_server/properties.py +119 -0
  42. dsp_tools/commands/create/exceptions.py +29 -0
  43. dsp_tools/commands/create/lists_only.py +66 -0
  44. dsp_tools/commands/create/models/create_problems.py +87 -0
  45. dsp_tools/commands/create/models/parsed_ontology.py +88 -0
  46. dsp_tools/commands/create/models/parsed_project.py +81 -0
  47. dsp_tools/commands/create/models/rdf_ontology.py +12 -0
  48. dsp_tools/commands/create/models/server_project_info.py +100 -0
  49. dsp_tools/commands/create/parsing/parse_lists.py +45 -0
  50. dsp_tools/commands/create/parsing/parse_ontology.py +243 -0
  51. dsp_tools/commands/create/parsing/parse_project.py +149 -0
  52. dsp_tools/commands/create/parsing/parsing_utils.py +40 -0
  53. dsp_tools/commands/create/project_validate.py +595 -0
  54. dsp_tools/commands/create/serialisation/ontology.py +119 -0
  55. dsp_tools/commands/create/serialisation/project.py +44 -0
  56. dsp_tools/commands/excel2json/CLAUDE.md +101 -0
  57. dsp_tools/commands/excel2json/json_header.py +57 -23
  58. dsp_tools/commands/excel2json/{new_lists → lists}/compliance_checks.py +26 -26
  59. dsp_tools/commands/excel2json/{new_lists/make_new_lists.py → lists/make_lists.py} +19 -18
  60. dsp_tools/commands/excel2json/{new_lists → lists}/models/input_error.py +1 -12
  61. dsp_tools/commands/excel2json/{new_lists → lists}/models/serialise.py +9 -5
  62. dsp_tools/commands/excel2json/{new_lists → lists}/utils.py +4 -4
  63. dsp_tools/commands/excel2json/models/input_error.py +31 -11
  64. dsp_tools/commands/excel2json/models/json_header.py +53 -15
  65. dsp_tools/commands/excel2json/models/ontology.py +4 -3
  66. dsp_tools/commands/excel2json/{lists.py → old_lists.py} +26 -112
  67. dsp_tools/commands/excel2json/project.py +78 -34
  68. dsp_tools/commands/excel2json/properties.py +57 -36
  69. dsp_tools/commands/excel2json/resources.py +32 -12
  70. dsp_tools/commands/excel2json/utils.py +20 -1
  71. dsp_tools/commands/excel2xml/__init__.py +2 -2
  72. dsp_tools/commands/excel2xml/excel2xml_cli.py +7 -15
  73. dsp_tools/commands/excel2xml/excel2xml_lib.py +138 -493
  74. dsp_tools/commands/excel2xml/propertyelement.py +5 -5
  75. dsp_tools/commands/{project → get}/get.py +29 -13
  76. dsp_tools/commands/get/get_permissions.py +257 -0
  77. dsp_tools/commands/get/get_permissions_legacy.py +89 -0
  78. dsp_tools/commands/{project/models → get/legacy_models}/context.py +6 -6
  79. dsp_tools/commands/{project/models → get/legacy_models}/group.py +5 -10
  80. dsp_tools/commands/{project/models → get/legacy_models}/listnode.py +5 -35
  81. dsp_tools/commands/{project/models → get/legacy_models}/model.py +1 -1
  82. dsp_tools/commands/{project/models → get/legacy_models}/ontology.py +9 -14
  83. dsp_tools/commands/{project/models → get/legacy_models}/project.py +13 -6
  84. dsp_tools/commands/{project/models → get/legacy_models}/propertyclass.py +9 -16
  85. dsp_tools/commands/{project/models → get/legacy_models}/resourceclass.py +8 -46
  86. dsp_tools/commands/{project/models → get/legacy_models}/user.py +19 -60
  87. dsp_tools/commands/get/models/permissions_models.py +10 -0
  88. dsp_tools/commands/id2iri.py +20 -10
  89. dsp_tools/commands/ingest_xmlupload/bulk_ingest_client.py +81 -56
  90. dsp_tools/commands/ingest_xmlupload/create_resources/apply_ingest_id.py +4 -10
  91. dsp_tools/commands/ingest_xmlupload/create_resources/upload_xml.py +97 -37
  92. dsp_tools/commands/ingest_xmlupload/create_resources/user_information.py +2 -2
  93. dsp_tools/commands/ingest_xmlupload/ingest_files/ingest_files.py +9 -10
  94. dsp_tools/commands/ingest_xmlupload/upload_files/filechecker.py +3 -3
  95. dsp_tools/commands/ingest_xmlupload/upload_files/input_error.py +2 -10
  96. dsp_tools/commands/ingest_xmlupload/upload_files/upload_failures.py +12 -2
  97. dsp_tools/commands/ingest_xmlupload/upload_files/upload_files.py +8 -9
  98. dsp_tools/commands/resume_xmlupload/resume_xmlupload.py +18 -18
  99. dsp_tools/commands/start_stack.py +126 -77
  100. dsp_tools/commands/update_legal/CLAUDE.md +344 -0
  101. dsp_tools/commands/update_legal/__init__.py +0 -0
  102. dsp_tools/commands/update_legal/core.py +182 -0
  103. dsp_tools/commands/update_legal/csv_operations.py +135 -0
  104. dsp_tools/commands/update_legal/models.py +87 -0
  105. dsp_tools/commands/update_legal/xml_operations.py +247 -0
  106. dsp_tools/commands/validate_data/CLAUDE.md +159 -0
  107. dsp_tools/commands/validate_data/__init__.py +0 -0
  108. dsp_tools/commands/validate_data/constants.py +59 -0
  109. dsp_tools/commands/validate_data/mappers.py +143 -0
  110. dsp_tools/commands/validate_data/models/__init__.py +0 -0
  111. dsp_tools/commands/validate_data/models/api_responses.py +45 -0
  112. dsp_tools/commands/validate_data/models/input_problems.py +119 -0
  113. dsp_tools/commands/validate_data/models/rdf_like_data.py +117 -0
  114. dsp_tools/commands/validate_data/models/validation.py +106 -0
  115. dsp_tools/commands/validate_data/prepare_data/__init__.py +0 -0
  116. dsp_tools/commands/validate_data/prepare_data/get_rdf_like_data.py +296 -0
  117. dsp_tools/commands/validate_data/prepare_data/make_data_graph.py +91 -0
  118. dsp_tools/commands/validate_data/prepare_data/prepare_data.py +184 -0
  119. dsp_tools/commands/validate_data/process_validation_report/__init__.py +0 -0
  120. dsp_tools/commands/validate_data/process_validation_report/get_user_validation_message.py +358 -0
  121. dsp_tools/commands/validate_data/process_validation_report/query_validation_result.py +507 -0
  122. dsp_tools/commands/validate_data/process_validation_report/reformat_validation_results.py +150 -0
  123. dsp_tools/commands/validate_data/shacl_cli_validator.py +70 -0
  124. dsp_tools/commands/validate_data/sparql/__init__.py +0 -0
  125. dsp_tools/commands/{xml_validate/sparql/resource_shacl.py → validate_data/sparql/cardinality_shacl.py} +45 -47
  126. dsp_tools/commands/validate_data/sparql/construct_shacl.py +92 -0
  127. dsp_tools/commands/validate_data/sparql/legal_info_shacl.py +36 -0
  128. dsp_tools/commands/validate_data/sparql/value_shacl.py +357 -0
  129. dsp_tools/commands/validate_data/utils.py +59 -0
  130. dsp_tools/commands/validate_data/validate_data.py +283 -0
  131. dsp_tools/commands/validate_data/validation/__init__.py +0 -0
  132. dsp_tools/commands/validate_data/validation/check_duplicate_files.py +55 -0
  133. dsp_tools/commands/validate_data/validation/check_for_unknown_classes.py +67 -0
  134. dsp_tools/commands/validate_data/validation/get_validation_report.py +94 -0
  135. dsp_tools/commands/validate_data/validation/validate_ontology.py +107 -0
  136. dsp_tools/commands/xmlupload/CLAUDE.md +292 -0
  137. dsp_tools/commands/xmlupload/make_rdf_graph/__init__.py +0 -0
  138. dsp_tools/commands/xmlupload/make_rdf_graph/constants.py +63 -0
  139. dsp_tools/commands/xmlupload/make_rdf_graph/jsonld_utils.py +44 -0
  140. dsp_tools/commands/xmlupload/make_rdf_graph/make_file_value.py +77 -0
  141. dsp_tools/commands/xmlupload/make_rdf_graph/make_resource_and_values.py +114 -0
  142. dsp_tools/commands/xmlupload/make_rdf_graph/make_values.py +262 -0
  143. dsp_tools/commands/xmlupload/models/bitstream_info.py +18 -0
  144. dsp_tools/commands/xmlupload/models/formatted_text_value.py +0 -25
  145. dsp_tools/commands/xmlupload/models/ingest.py +56 -70
  146. dsp_tools/commands/xmlupload/models/input_problems.py +6 -14
  147. dsp_tools/commands/xmlupload/models/lookup_models.py +21 -0
  148. dsp_tools/commands/xmlupload/models/permission.py +0 -39
  149. dsp_tools/commands/xmlupload/models/{deserialise/xmlpermission.py → permissions_parsed.py} +2 -2
  150. dsp_tools/commands/xmlupload/models/processed/__init__.py +0 -0
  151. dsp_tools/commands/xmlupload/models/processed/file_values.py +29 -0
  152. dsp_tools/commands/xmlupload/models/processed/res.py +27 -0
  153. dsp_tools/commands/xmlupload/models/processed/values.py +101 -0
  154. dsp_tools/commands/xmlupload/models/rdf_models.py +26 -0
  155. dsp_tools/commands/xmlupload/models/upload_clients.py +3 -3
  156. dsp_tools/commands/xmlupload/models/upload_state.py +2 -4
  157. dsp_tools/commands/xmlupload/prepare_xml_input/__init__.py +0 -0
  158. dsp_tools/commands/xmlupload/{ark2iri.py → prepare_xml_input/ark2iri.py} +1 -1
  159. dsp_tools/commands/xmlupload/prepare_xml_input/get_processed_resources.py +252 -0
  160. dsp_tools/commands/xmlupload/{iiif_uri_validator.py → prepare_xml_input/iiif_uri_validator.py} +2 -14
  161. dsp_tools/commands/xmlupload/{list_client.py → prepare_xml_input/list_client.py} +15 -10
  162. dsp_tools/commands/xmlupload/prepare_xml_input/prepare_xml_input.py +67 -0
  163. dsp_tools/commands/xmlupload/prepare_xml_input/read_validate_xml_file.py +58 -0
  164. dsp_tools/commands/xmlupload/prepare_xml_input/transform_input_values.py +118 -0
  165. dsp_tools/commands/xmlupload/resource_create_client.py +7 -468
  166. dsp_tools/commands/xmlupload/richtext_id2iri.py +37 -0
  167. dsp_tools/commands/xmlupload/stash/{construct_and_analyze_graph.py → analyse_circular_reference_graph.py} +64 -157
  168. dsp_tools/commands/xmlupload/stash/create_info_for_graph.py +53 -0
  169. dsp_tools/commands/xmlupload/stash/graph_models.py +13 -8
  170. dsp_tools/commands/xmlupload/stash/stash_circular_references.py +48 -115
  171. dsp_tools/commands/xmlupload/stash/stash_models.py +4 -9
  172. dsp_tools/commands/xmlupload/stash/upload_stashed_resptr_props.py +34 -40
  173. dsp_tools/commands/xmlupload/stash/upload_stashed_xml_texts.py +98 -108
  174. dsp_tools/commands/xmlupload/upload_config.py +8 -0
  175. dsp_tools/commands/xmlupload/write_diagnostic_info.py +14 -9
  176. dsp_tools/commands/xmlupload/xmlupload.py +214 -192
  177. dsp_tools/config/__init__.py +0 -0
  178. dsp_tools/config/logger_config.py +69 -0
  179. dsp_tools/{utils → config}/warnings_config.py +4 -1
  180. dsp_tools/error/__init__.py +0 -0
  181. dsp_tools/error/custom_warnings.py +39 -0
  182. dsp_tools/error/exceptions.py +204 -0
  183. dsp_tools/error/problems.py +10 -0
  184. dsp_tools/error/xmllib_errors.py +20 -0
  185. dsp_tools/error/xmllib_warnings.py +54 -0
  186. dsp_tools/error/xmllib_warnings_util.py +159 -0
  187. dsp_tools/error/xsd_validation_error_msg.py +19 -0
  188. dsp_tools/legacy_models/__init__.py +0 -0
  189. dsp_tools/{models → legacy_models}/datetimestamp.py +7 -7
  190. dsp_tools/{models → legacy_models}/langstring.py +1 -1
  191. dsp_tools/{models → legacy_models}/projectContext.py +4 -4
  192. dsp_tools/resources/schema/data.xsd +108 -83
  193. dsp_tools/resources/schema/lists-only.json +4 -23
  194. dsp_tools/resources/schema/project.json +80 -35
  195. dsp_tools/resources/schema/properties-only.json +1 -4
  196. dsp_tools/resources/start-stack/docker-compose.override-host.j2 +11 -0
  197. dsp_tools/resources/start-stack/docker-compose.yml +34 -30
  198. dsp_tools/resources/start-stack/dsp-app-config.json +45 -0
  199. dsp_tools/resources/start-stack/dsp-app-config.override-host.j2 +26 -0
  200. dsp_tools/resources/validate_data/api-shapes-resource-cardinalities.ttl +191 -0
  201. dsp_tools/resources/validate_data/api-shapes.ttl +804 -0
  202. dsp_tools/resources/validate_data/shacl-cli-image.yml +4 -0
  203. dsp_tools/resources/validate_data/validate-ontology.ttl +99 -0
  204. dsp_tools/utils/ansi_colors.py +32 -0
  205. dsp_tools/utils/data_formats/__init__.py +0 -0
  206. dsp_tools/utils/{date_util.py → data_formats/date_util.py} +13 -1
  207. dsp_tools/utils/data_formats/iri_util.py +30 -0
  208. dsp_tools/utils/{shared.py → data_formats/shared.py} +1 -35
  209. dsp_tools/utils/{uri_util.py → data_formats/uri_util.py} +12 -2
  210. dsp_tools/utils/fuseki_bloating.py +63 -0
  211. dsp_tools/utils/json_parsing.py +22 -0
  212. dsp_tools/utils/rdf_constants.py +42 -0
  213. dsp_tools/utils/rdflib_utils.py +10 -0
  214. dsp_tools/utils/replace_id_with_iri.py +66 -0
  215. dsp_tools/utils/request_utils.py +238 -0
  216. dsp_tools/utils/xml_parsing/__init__.py +0 -0
  217. dsp_tools/utils/xml_parsing/get_lookups.py +32 -0
  218. dsp_tools/utils/xml_parsing/get_parsed_resources.py +325 -0
  219. dsp_tools/utils/xml_parsing/models/__init__.py +0 -0
  220. dsp_tools/utils/xml_parsing/models/parsed_resource.py +76 -0
  221. dsp_tools/utils/xml_parsing/parse_clean_validate_xml.py +137 -0
  222. dsp_tools/xmllib/CLAUDE.md +302 -0
  223. dsp_tools/xmllib/__init__.py +49 -0
  224. dsp_tools/xmllib/general_functions.py +877 -0
  225. dsp_tools/xmllib/internal/__init__.py +0 -0
  226. dsp_tools/xmllib/internal/checkers.py +162 -0
  227. dsp_tools/xmllib/internal/circumvent_circular_imports.py +36 -0
  228. dsp_tools/xmllib/internal/constants.py +46 -0
  229. dsp_tools/xmllib/internal/input_converters.py +155 -0
  230. dsp_tools/xmllib/internal/serialise_file_value.py +57 -0
  231. dsp_tools/xmllib/internal/serialise_resource.py +177 -0
  232. dsp_tools/xmllib/internal/serialise_values.py +152 -0
  233. dsp_tools/xmllib/internal/type_aliases.py +11 -0
  234. dsp_tools/xmllib/models/config_options.py +28 -0
  235. dsp_tools/xmllib/models/date_formats.py +48 -0
  236. dsp_tools/xmllib/models/dsp_base_resources.py +1380 -400
  237. dsp_tools/xmllib/models/internal/__init__.py +0 -0
  238. dsp_tools/xmllib/models/internal/file_values.py +172 -0
  239. dsp_tools/xmllib/models/internal/geometry.py +162 -0
  240. dsp_tools/xmllib/models/{migration_metadata.py → internal/migration_metadata.py} +14 -10
  241. dsp_tools/xmllib/models/internal/serialise_permissions.py +66 -0
  242. dsp_tools/xmllib/models/internal/values.py +342 -0
  243. dsp_tools/xmllib/models/licenses/__init__.py +0 -0
  244. dsp_tools/xmllib/models/licenses/other.py +59 -0
  245. dsp_tools/xmllib/models/licenses/recommended.py +107 -0
  246. dsp_tools/xmllib/models/permissions.py +41 -0
  247. dsp_tools/xmllib/models/res.py +1782 -0
  248. dsp_tools/xmllib/models/root.py +313 -26
  249. dsp_tools/xmllib/value_checkers.py +310 -47
  250. dsp_tools/xmllib/value_converters.py +765 -8
  251. dsp_tools-18.3.0.post13.dist-info/METADATA +90 -0
  252. dsp_tools-18.3.0.post13.dist-info/RECORD +286 -0
  253. dsp_tools-18.3.0.post13.dist-info/WHEEL +4 -0
  254. {dsp_tools-9.1.0.post11.dist-info → dsp_tools-18.3.0.post13.dist-info}/entry_points.txt +1 -0
  255. dsp_tools/commands/project/create/project_create.py +0 -1107
  256. dsp_tools/commands/project/create/project_create_lists.py +0 -204
  257. dsp_tools/commands/project/create/project_validate.py +0 -453
  258. dsp_tools/commands/project/models/project_definition.py +0 -12
  259. dsp_tools/commands/rosetta.py +0 -124
  260. dsp_tools/commands/template.py +0 -30
  261. dsp_tools/commands/xml_validate/api_connection.py +0 -122
  262. dsp_tools/commands/xml_validate/deserialise_input.py +0 -135
  263. dsp_tools/commands/xml_validate/make_data_rdf.py +0 -193
  264. dsp_tools/commands/xml_validate/models/data_deserialised.py +0 -108
  265. dsp_tools/commands/xml_validate/models/data_rdf.py +0 -214
  266. dsp_tools/commands/xml_validate/models/input_problems.py +0 -191
  267. dsp_tools/commands/xml_validate/models/validation.py +0 -29
  268. dsp_tools/commands/xml_validate/reformat_validaton_result.py +0 -89
  269. dsp_tools/commands/xml_validate/sparql/construct_shapes.py +0 -16
  270. dsp_tools/commands/xml_validate/xml_validate.py +0 -151
  271. dsp_tools/commands/xmlupload/check_consistency_with_ontology.py +0 -253
  272. dsp_tools/commands/xmlupload/models/deserialise/deserialise_value.py +0 -236
  273. dsp_tools/commands/xmlupload/models/deserialise/xmlresource.py +0 -171
  274. dsp_tools/commands/xmlupload/models/namespace_context.py +0 -39
  275. dsp_tools/commands/xmlupload/models/ontology_lookup_models.py +0 -161
  276. dsp_tools/commands/xmlupload/models/ontology_problem_models.py +0 -178
  277. dsp_tools/commands/xmlupload/models/serialise/jsonld_serialiser.py +0 -40
  278. dsp_tools/commands/xmlupload/models/serialise/serialise_value.py +0 -51
  279. dsp_tools/commands/xmlupload/ontology_client.py +0 -92
  280. dsp_tools/commands/xmlupload/project_client.py +0 -91
  281. dsp_tools/commands/xmlupload/read_validate_xml_file.py +0 -99
  282. dsp_tools/models/custom_warnings.py +0 -31
  283. dsp_tools/models/exceptions.py +0 -90
  284. dsp_tools/resources/0100-template-repo/template.json +0 -45
  285. dsp_tools/resources/0100-template-repo/template.xml +0 -27
  286. dsp_tools/resources/start-stack/docker-compose-validation.yml +0 -5
  287. dsp_tools/resources/start-stack/start-stack-config.yml +0 -4
  288. dsp_tools/resources/xml_validate/api-shapes.ttl +0 -411
  289. dsp_tools/resources/xml_validate/replace_namespace.xslt +0 -61
  290. dsp_tools/utils/connection_live.py +0 -383
  291. dsp_tools/utils/iri_util.py +0 -14
  292. dsp_tools/utils/logger_config.py +0 -41
  293. dsp_tools/utils/set_encoder.py +0 -20
  294. dsp_tools/utils/xml_utils.py +0 -145
  295. dsp_tools/utils/xml_validation.py +0 -197
  296. dsp_tools/utils/xml_validation_models.py +0 -68
  297. dsp_tools/xmllib/models/file_values.py +0 -78
  298. dsp_tools/xmllib/models/resource.py +0 -415
  299. dsp_tools/xmllib/models/values.py +0 -428
  300. dsp_tools-9.1.0.post11.dist-info/METADATA +0 -130
  301. dsp_tools-9.1.0.post11.dist-info/RECORD +0 -167
  302. dsp_tools-9.1.0.post11.dist-info/WHEEL +0 -4
  303. dsp_tools-9.1.0.post11.dist-info/licenses/LICENSE +0 -674
  304. /dsp_tools/{commands/excel2json/new_lists → clients}/__init__.py +0 -0
  305. /dsp_tools/commands/{excel2json/new_lists/models → create}/__init__.py +0 -0
  306. /dsp_tools/commands/{project → create/create_on_server}/__init__.py +0 -0
  307. /dsp_tools/commands/{project/create → create/models}/__init__.py +0 -0
  308. /dsp_tools/commands/{project/models → create/parsing}/__init__.py +0 -0
  309. /dsp_tools/commands/{xml_validate → create/serialisation}/__init__.py +0 -0
  310. /dsp_tools/commands/{xml_validate/models → excel2json/lists}/__init__.py +0 -0
  311. /dsp_tools/commands/{xml_validate/sparql → excel2json/lists/models}/__init__.py +0 -0
  312. /dsp_tools/commands/excel2json/{new_lists → lists}/models/deserialise.py +0 -0
  313. /dsp_tools/commands/{xmlupload/models/deserialise → get}/__init__.py +0 -0
  314. /dsp_tools/commands/{xmlupload/models/serialise → get/legacy_models}/__init__.py +0 -0
  315. /dsp_tools/commands/{project/models → get/legacy_models}/helpers.py +0 -0
  316. /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 construct_resource_class_node_shape(onto: Graph) -> Graph:
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
- ?shapesIRI a sh:NodeShape ;
32
- sh:targetClass ?class ;
33
- sh:ignoredProperties ( rdf:type rdfs:label knora-api:hasComment knora-api:isPartOf knora-api:seqnum ) ;
34
- sh:closed true .
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