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,137 @@
1
+ from __future__ import annotations
2
+
3
+ import importlib.resources
4
+ from copy import deepcopy
5
+ from pathlib import Path
6
+
7
+ import pandas as pd
8
+ import regex
9
+ from loguru import logger
10
+ from lxml import etree
11
+
12
+ from dsp_tools.error.exceptions import InputError
13
+ from dsp_tools.error.exceptions import UserFilepathNotFoundError
14
+ from dsp_tools.error.xsd_validation_error_msg import XSDValidationMessage
15
+ from dsp_tools.error.xsd_validation_error_msg import get_xsd_validation_message_str
16
+ from dsp_tools.utils.ansi_colors import BACKGROUND_BOLD_RED
17
+ from dsp_tools.utils.ansi_colors import BOLD_RED
18
+ from dsp_tools.utils.ansi_colors import RESET_TO_DEFAULT
19
+
20
+ separator = "\n "
21
+ list_separator = "\n - "
22
+
23
+
24
+ def parse_and_clean_xml_file(input_file: Path) -> etree._Element:
25
+ root = parse_xml_file(input_file)
26
+ root = _remove_comments_from_element_tree(root)
27
+ if not validate_root_emit_user_message(root, Path(input_file).parent):
28
+ raise InputError("The XML file contains validation errors.") # a detailed report has already been printed
29
+ print("The XML file is syntactically correct.")
30
+ return transform_into_localnames(root)
31
+
32
+
33
+ def parse_and_validate_xml_file(input_file: Path | str) -> bool:
34
+ root = parse_xml_file(input_file)
35
+ data_xml = _remove_comments_from_element_tree(root)
36
+ return validate_root_emit_user_message(data_xml, Path(input_file).parent)
37
+
38
+
39
+ def parse_xml_file(input_file: str | Path) -> etree._Element:
40
+ parser = etree.XMLParser(remove_comments=True, remove_pis=True)
41
+ if not Path(input_file).exists():
42
+ raise UserFilepathNotFoundError(input_file)
43
+ try:
44
+ return etree.parse(source=input_file, parser=parser).getroot()
45
+ except etree.XMLSyntaxError as err:
46
+ logger.error(f"The XML file contains the following syntax error: {err.msg}")
47
+ raise InputError(f"The XML file contains the following syntax error: {err.msg}") from None
48
+
49
+
50
+ def transform_into_localnames(root: etree._Element) -> etree._Element:
51
+ """Removes the namespace of the tags."""
52
+ tree = deepcopy(root)
53
+ for elem in tree.iter():
54
+ elem.tag = etree.QName(elem).localname
55
+ return tree
56
+
57
+
58
+ def _remove_comments_from_element_tree(input_tree: etree._Element) -> etree._Element:
59
+ """Removes comments and processing instructions."""
60
+ root = deepcopy(input_tree)
61
+ for c in root.xpath("//comment()"):
62
+ c.getparent().remove(c)
63
+ for c in root.xpath("//processing-instruction()"):
64
+ c.getparent().remove(c)
65
+ return root
66
+
67
+
68
+ def _validate_xml_tree_against_schema(data_xml: etree._Element) -> etree.XMLSchema | None:
69
+ schema_res = importlib.resources.files("dsp_tools").joinpath("resources/schema/data.xsd")
70
+ with schema_res.open(encoding="utf-8") as schema_file:
71
+ xmlschema = etree.XMLSchema(etree.parse(schema_file))
72
+ if not xmlschema.validate(data_xml):
73
+ return xmlschema
74
+ return None
75
+
76
+
77
+ def validate_root_emit_user_message(root: etree._Element, save_path: Path) -> bool:
78
+ validation_errors = _validate_root_get_validation_messages(root)
79
+ if validation_errors:
80
+ _emit_validation_errors(validation_errors, save_path)
81
+ return False
82
+ return True
83
+
84
+
85
+ def _validate_root_get_validation_messages(data_xml: etree._Element) -> list[XSDValidationMessage] | None:
86
+ if errors := _validate_xml_tree_against_schema(data_xml):
87
+ return _reformat_validation_errors(errors.error_log)
88
+ return None
89
+
90
+
91
+ def _emit_validation_errors(validation_errors: list[XSDValidationMessage], save_path: Path) -> None:
92
+ header_msg = f"During the XSD Schema validation the following {len(validation_errors)} error(s) were found: "
93
+ print(BACKGROUND_BOLD_RED, header_msg, RESET_TO_DEFAULT)
94
+ logger.error(header_msg)
95
+ if len(validation_errors) > 50:
96
+ save_path = save_path / "xsd_validation_errors.csv"
97
+ message_dicts = [vars(x) for x in validation_errors]
98
+ df = pd.DataFrame.from_records(message_dicts)
99
+ df.to_csv(save_path, index=False)
100
+ msg = f"Due to the large number of errors they are saved in the file '{save_path}'."
101
+ print(BOLD_RED + msg, RESET_TO_DEFAULT)
102
+ logger.error(msg)
103
+ else:
104
+ for one_msg in validation_errors:
105
+ msg_str = get_xsd_validation_message_str(one_msg)
106
+ print(BOLD_RED, msg_str, RESET_TO_DEFAULT)
107
+ logger.error(msg_str)
108
+
109
+
110
+ def _reformat_validation_errors(log: etree._ListErrorLog) -> list[XSDValidationMessage]:
111
+ res = [_reformat_error_message_str(err.message, err.line) for err in log]
112
+ return [x for x in res if x]
113
+
114
+
115
+ def _reformat_error_message_str(msg: str, line_number: int) -> XSDValidationMessage | None:
116
+ element, attrib = None, None
117
+ msg = msg.replace("{https://dasch.swiss/schema}", "")
118
+ first, message = msg.split(":", maxsplit=1)
119
+ if ele_found := regex.search(r"Element '(.*?)'", first):
120
+ element = ele_found.group(1)
121
+ if attrib_found := regex.search(r"attribute '(.*?)'", first):
122
+ attrib = attrib_found.group(1)
123
+ if "No precomputed value available, the value was either invalid or something strange happened" in message:
124
+ return None
125
+ if " is not a valid value of the atomic type 'xs:ID'." in message:
126
+ if found := regex.search(r"'.*?'", message):
127
+ id_ = found.group(0)
128
+ else:
129
+ id_ = ""
130
+ message = (
131
+ f"The provided resource id {id_} is either not a valid xsd:ID or not unique in the file."
132
+ "The function make_xsd_compatible_id() assists you in creating IDs."
133
+ )
134
+ else:
135
+ message = regex.sub(r"\[facet .+\] ", "", message)
136
+ message = regex.sub(r"pattern ('.+')", "pattern for this value", message).strip()
137
+ return XSDValidationMessage(line_number=line_number, element=element, attribute=attrib, message=message)
@@ -0,0 +1,302 @@
1
+ # CLAUDE.md - xmllib Module
2
+
3
+ This file provides guidance to Claude Code when working with the `xmllib` module in dsp-tools.
4
+
5
+ ## Module Overview
6
+
7
+ The `xmllib` module is the public API library for programmatic creation of DSP XML files.
8
+ It provides a type-safe, validated approach to generating XML data that conforms to DSP (DaSCH Service Platform) requirements.
9
+
10
+ ## Architecture
11
+
12
+ ### Core Components
13
+
14
+ #### Public API Layer (`__init__.py`)
15
+
16
+ - **Primary Interface**: All public functions and classes are exported here
17
+ - **Helper Functions**: Utilities for XML generation, validation, and formatting
18
+ - **Value Processing**: Checkers and converters for different data types
19
+
20
+ #### Models Layer (`models/`)
21
+
22
+ - **XMLRoot**: Main container for XML documents (`models/root.py`)
23
+ - **Resource**: Primary resource class for DSP resources (`models/res.py`)
24
+ - **DSP Base Resources**: Specialized resource types (`models/dsp_base_resources.py`)
25
+ - **Configuration**: Enums and options (`models/config_options.py`)
26
+ - **Licenses**: License definitions (`models/licenses/`)
27
+ - **Internal Models**: Value types and file models (`models/internal/`)
28
+
29
+ #### Utilities Layer
30
+
31
+ - **general_functions.py**: Public utility functions for XML creation
32
+ - **value_checkers.py**: Validation functions for data types
33
+ - **value_converters.py**: Data conversion utilities
34
+
35
+ #### Internal Layer (`internal/`)
36
+
37
+ - **checkers.py**: Type checking and input validation functions
38
+ - **input_converters.py**: Data conversion utilities for internal use
39
+ - **Serialization**: XML output generation (`serialise_resource.py`, `serialise_values.py`, `serialise_file_value.py`)
40
+ - **constants.py**: Constants used in several other files
41
+ - **type_aliases.py**: Type definitions and aliases
42
+ - **circumvent_circular_imports.py**: Place for functions that would produce a circular import error in other places
43
+
44
+ ### Data Flow
45
+
46
+ ```text
47
+ Raw Data → Validation → Resource Creation → XML Serialization
48
+ ↓ ↓ ↓ ↓
49
+ Input Converters → Checkers → Models/Values → XML Output
50
+ (internal/) (internal/) (models/) (internal/)
51
+ ```
52
+
53
+ ## Key Classes and Usage Patterns
54
+
55
+ ### XMLRoot - Document Container
56
+
57
+ ```python
58
+ root = XMLRoot.create_new(shortcode="0000", default_ontology="onto")
59
+ root.add_resource(resource)
60
+ root.serialise_to_file("output.xml")
61
+ ```
62
+
63
+ ### Resource - Core Data Model
64
+
65
+ ```python
66
+ resource = Resource.create_new(
67
+ res_id="resource_1",
68
+ restype=":Person",
69
+ label="John Doe"
70
+ )
71
+ resource.add_simpletext(prop_name=":hasName", value="John Doe")
72
+ resource.add_date(prop_name=":hasBirthdate", value="GREGORIAN:CE:1990-01-01")
73
+ resource.add_integer(prop_name=":hasAge", value=33)
74
+ resource.add_link(prop_name=":hasPartner", value="resource_2")
75
+ ```
76
+
77
+ ### Specialized Resources
78
+
79
+ ```python
80
+ # Region of Interest
81
+ region = RegionResource.create_new(
82
+ res_id="region_1",
83
+ label="ROI 1",
84
+ region_of="image_1",
85
+ ).add_rectangle(
86
+ (0.5, 0.2),
87
+ (0.1, 0.3),
88
+ )
89
+
90
+ # Video Segment
91
+ segment = VideoSegmentResource.create_new(
92
+ res_id="segment_1",
93
+ label="The second minute of the video",
94
+ segment_of="video_1",
95
+ segment_start="60",
96
+ segment_end="120"
97
+ )
98
+ ```
99
+
100
+ ## Value Types and Validation
101
+
102
+ ### Supported Value Types
103
+
104
+ - **SimpleText**: Plain text values
105
+ - **Richtext**: Formatted text with standoff markup
106
+ - **Integer**: Numeric integers
107
+ - **Decimal**: Floating point numbers
108
+ - **Boolean**: True/false values
109
+ - **Date**: Calendar dates with era and precision. Always as data range with start and end.
110
+ - **Time**: Timestamps
111
+ - **Color**: Hex color values
112
+ - **URI**: Web addresses and identifiers
113
+ - **Geoname**: Geographic location references, as geoname.org identifiers
114
+ - **List**: Controlled vocabulary values
115
+ - **Link**: References to other resources
116
+ - **File**: Multimedia file attachments
117
+
118
+ ### Validation Functions
119
+
120
+ ```python
121
+ # Check data types
122
+ date_value = reformat_date("1.1.1990", ".", None, DateFormat.DD_MM_YYYY)
123
+ assert is_date(date_value)
124
+
125
+ if is_bool_like("yes"):
126
+ bool_value = convert_to_bool_string("yes")
127
+
128
+ if is_color("#FF0000"):
129
+ # Valid hex color
130
+ pass
131
+ ```
132
+
133
+ ## Configuration Options
134
+
135
+ ### Permissions
136
+
137
+ - `PROJECT_SPECIFIC_PERMISSIONS`: Use project defaults
138
+ - `OPEN`: Publicly accessible
139
+ - `RESTRICTED`: Only visible for project members
140
+ - `RESTRICTED_VIEW`: Only applicable for images: Publicly accessible,
141
+ but users who are not project members see the image in lower resolution or with a watermark
142
+
143
+ ### Date Formatting
144
+
145
+ - `DateFormat.YYYY_MM_DD`: ISO format (2023-12-31)
146
+ - `DateFormat.DD_MM_YYYY`: European format (31.12.2023)
147
+ - `DateFormat.MM_DD_YYYY`: US format (12/31/2023)
148
+
149
+ ### Calendar Systems
150
+
151
+ - `Calendar.GREGORIAN`: Modern standard calendar
152
+ - `Calendar.JULIAN`: Julian calender, only used for historical dates
153
+ - `Calendar.ISLAMIC`: Islamic calendar
154
+
155
+ ### Text Processing
156
+
157
+ - `NewlineReplacement.PARAGRAPH`: Convert linebreaks to `<p>` tags
158
+ - `NewlineReplacement.LINEBREAK`: Convert linebreaks to `<br>` tags
159
+ - `NewlineReplacement.NONE`: Preserve linebreaks as-is
160
+
161
+ ## Rich Text and Standoff Markup
162
+
163
+ ### Creating Links
164
+
165
+ ```python
166
+ # Link to another resource
167
+ link_text = create_standoff_link_to_resource("target_resource_id", "link text")
168
+
169
+ # Link to external URI
170
+ uri_link = create_standoff_link_to_uri("https://example.com", "external link")
171
+
172
+ # Add to richtext
173
+ resource.add_richtext(prop_name=":hasDescription", value=f"See {link_text} for details")
174
+ ```
175
+
176
+ ### Footnotes
177
+
178
+ ```python
179
+ # Create footnote
180
+ footnote = create_footnote_string("This is a footnote")
181
+ footnote_element = create_footnote_element("Footnote text")
182
+ resource.add_richtext(prop_name=":hasDescription", value=f"Rich text with a footnote: {footnote}")
183
+ ```
184
+
185
+ ## Error Handling
186
+
187
+ ### Warning System
188
+
189
+ - **Input Warnings**: Non-fatal data issues with input data
190
+ - **Type Mismatches**: Automatic conversion with notification
191
+ - **Validation Failures**: Clear error messages with resource context
192
+
193
+ ### Error Types
194
+
195
+ ```python
196
+ # Warning for non-fatal issues
197
+ emit_xmllib_input_warning("Non-standard boolean value converted")
198
+
199
+ # Type mismatch warning
200
+ if not is_color(val):
201
+ emit_xmllib_input_type_mismatch_warning(expected_type="color", value=val, res_id=resource_id, prop_name=prop_name)
202
+
203
+ # Input validation errors
204
+ raise_input_error(MessageInfo(f"Invalid date format: {date}", resource_id="res_1", prop_name=":hasDate"))
205
+ ```
206
+
207
+ ## Testing Approach
208
+
209
+ ### Unit Tests (`test/unittests/xmllib`)
210
+
211
+ - Individual function validation
212
+ - Type checking verification
213
+ - Data conversion accuracy
214
+
215
+ ### Integration Tests (`test/integration/xmllib`)
216
+
217
+ - Multi-resource XML generation
218
+ - Cross-module compatibility
219
+ - File I/O operations
220
+
221
+ ## Common Patterns
222
+
223
+ ### Resource Creation Pipeline
224
+
225
+ 1. **Validate Input**: Use checker functions
226
+ 2. **Convert Data**: Apply converters if needed
227
+ 3. **Create Resource**: Instantiate with validated data
228
+ 4. **Add Values**: Use typed `add_xyz()` methods
229
+ 5. **Serialize**: Generate XML output
230
+
231
+ ### Batch Processing
232
+
233
+ ```python
234
+ # Process multiple resources
235
+ for data_row in dataset:
236
+ resource = Resource.create_new(
237
+ res_id=make_xsd_compatible_id(data_row['id']),
238
+ restype=data_row['type'],
239
+ label=clean_whitespaces_from_string(data_row['label'])
240
+ )
241
+
242
+ # Add values with validation
243
+ for prop, value in data_row.items():
244
+ if is_nonempty_value(value):
245
+ resource.add_simpletext(prop_name=prop, value=str(value))
246
+
247
+ root.add_resource(resource)
248
+ ```
249
+
250
+ ### List Value Processing
251
+
252
+ ```python
253
+ # Work with controlled vocabularies
254
+ lookup = ListLookup(project_lists)
255
+ string_with_list_labels = "Label 1; Label 2"
256
+ nodes = get_list_nodes_from_string_via_list_name(
257
+ string_with_list_labels="Label 1; Label 2",
258
+ label_separator=";",
259
+ list_name="list1",
260
+ list_lookup=list_lookup,
261
+ )
262
+ assert nodes == ["node1", "node2"]
263
+ resource.add_list_multiple(prop_name=":hasColor", list_name="list1", values=list_nodes)
264
+ ```
265
+
266
+ ## Important Guidelines
267
+
268
+ ### Type Safety
269
+
270
+ - Always use type hints in new code
271
+ - Leverage dataclass models for structured data
272
+ - Use validation functions before creating values
273
+
274
+ ### Maintainability
275
+
276
+ - Follow existing patterns for new value types
277
+ - Add comprehensive docstrings for public functions
278
+ - Include validation logic with clear error messages
279
+
280
+ ## Dependencies
281
+
282
+ ### External
283
+
284
+ - `lxml`: XML processing and validation
285
+ - `pandas`: Data manipulation (NA handling)
286
+ - `regex`: Unicode-aware pattern matching
287
+ - `loguru`: Structured logging
288
+
289
+ ### Internal
290
+
291
+ - `dsp_tools.error`: Warning and error system
292
+ - `dsp_tools.utils`: Data format utilities
293
+ - Type definitions and constants
294
+
295
+ ## Migration Notes
296
+
297
+ When updating xmllib:
298
+
299
+ - Maintain backward compatibility in public API
300
+ - Add deprecation warnings before removing features
301
+ - Update type hints for new Python versions
302
+ - Ensure XML schema compliance is preserved
@@ -0,0 +1,49 @@
1
+ from dsp_tools.error.xmllib_warnings_util import initialise_warning_file
2
+
3
+ from .general_functions import ListLookup as ListLookup
4
+ from .general_functions import clean_whitespaces_from_string as clean_whitespaces_from_string
5
+ from .general_functions import create_footnote_element as create_footnote_element
6
+ from .general_functions import create_footnote_string as create_footnote_string
7
+ from .general_functions import create_list_from_input as create_list_from_input
8
+ from .general_functions import create_list_from_string as create_list_from_string
9
+ from .general_functions import create_non_empty_list_from_string as create_non_empty_list_from_string
10
+ from .general_functions import create_standoff_link_to_resource as create_standoff_link_to_resource
11
+ from .general_functions import create_standoff_link_to_uri as create_standoff_link_to_uri
12
+ from .general_functions import escape_reserved_xml_characters as escape_reserved_xml_characters
13
+ from .general_functions import find_license_in_string as find_license_in_string
14
+ from .general_functions import get_list_nodes_from_string_via_list_name as get_list_nodes_from_string_via_list_name
15
+ from .general_functions import get_list_nodes_from_string_via_property as get_list_nodes_from_string_via_property
16
+ from .general_functions import make_xsd_compatible_id as make_xsd_compatible_id
17
+ from .general_functions import make_xsd_compatible_id_with_uuid as make_xsd_compatible_id_with_uuid
18
+ from .models.config_options import NewlineReplacement as NewlineReplacement
19
+ from .models.date_formats import Calendar as Calendar
20
+ from .models.date_formats import DateFormat as DateFormat
21
+ from .models.date_formats import Era as Era
22
+ from .models.dsp_base_resources import AudioSegmentResource as AudioSegmentResource
23
+ from .models.dsp_base_resources import LinkResource as LinkResource
24
+ from .models.dsp_base_resources import RegionResource as RegionResource
25
+ from .models.dsp_base_resources import VideoSegmentResource as VideoSegmentResource
26
+ from .models.licenses.other import LicenseOther as LicenseOther
27
+ from .models.licenses.recommended import LicenseRecommended as LicenseRecommended
28
+ from .models.permissions import Permissions as Permissions
29
+ from .models.res import Resource as Resource
30
+ from .models.root import XMLRoot as XMLRoot
31
+ from .value_checkers import check_richtext_syntax as check_richtext_syntax
32
+ from .value_checkers import is_bool_like as is_bool_like
33
+ from .value_checkers import is_color as is_color
34
+ from .value_checkers import is_date as is_date
35
+ from .value_checkers import is_decimal as is_decimal
36
+ from .value_checkers import is_dsp_ark as is_dsp_ark
37
+ from .value_checkers import is_dsp_iri as is_dsp_iri
38
+ from .value_checkers import is_geoname as is_geoname
39
+ from .value_checkers import is_integer as is_integer
40
+ from .value_checkers import is_nonempty_value as is_nonempty_value
41
+ from .value_checkers import is_timestamp as is_timestamp
42
+ from .value_converters import convert_to_bool_string as convert_to_bool_string
43
+ from .value_converters import find_dates_in_string as find_dates_in_string
44
+ from .value_converters import reformat_date as reformat_date
45
+ from .value_converters import replace_newlines_with_br_tags as replace_newlines_with_br_tags
46
+ from .value_converters import replace_newlines_with_paragraph_tags as replace_newlines_with_paragraph_tags
47
+ from .value_converters import replace_newlines_with_tags as replace_newlines_with_tags
48
+
49
+ initialise_warning_file()