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,39 @@
1
+ from abc import ABC
2
+ from abc import abstractmethod
3
+
4
+ from dsp_tools.utils.ansi_colors import BOLD_RED
5
+ from dsp_tools.utils.ansi_colors import RESET_TO_DEFAULT
6
+
7
+
8
+ class DspToolsWarning(Warning, ABC):
9
+ """Abstract base class for warnings that implement a custom showwarnings() function"""
10
+
11
+ @classmethod
12
+ @abstractmethod
13
+ def showwarning(cls, message: str) -> None:
14
+ """Functionality that should be executed when a warning of this class is emitted"""
15
+
16
+
17
+ class DspToolsUserWarning(DspToolsWarning):
18
+ """Class for general user-facing warnings"""
19
+
20
+ @classmethod
21
+ def showwarning(cls, message: str) -> None:
22
+ """Print the warning, without context"""
23
+ print(BOLD_RED + f"WARNING: {message}" + RESET_TO_DEFAULT)
24
+
25
+
26
+ class DspToolsFutureWarning(DspToolsWarning, FutureWarning):
27
+ """Class for user-facing deprecation warnings"""
28
+
29
+ @classmethod
30
+ def showwarning(cls, message: str) -> None:
31
+ """Print the warning, without context"""
32
+ print(BOLD_RED + f"DEPRECATION WARNING: {message}" + RESET_TO_DEFAULT)
33
+
34
+
35
+ class DspToolsUnexpectedStatusCodeWarning(DspToolsWarning):
36
+ @classmethod
37
+ def showwarning(cls, message: str) -> None:
38
+ """Print the warning, without context"""
39
+ print(BOLD_RED + f"ERROR: {message}" + RESET_TO_DEFAULT)
@@ -0,0 +1,204 @@
1
+ from dataclasses import dataclass
2
+ from pathlib import Path
3
+
4
+ from dsp_tools.config.logger_config import LOGGER_SAVEPATH
5
+ from dsp_tools.utils.ansi_colors import BOLD_RED
6
+ from dsp_tools.utils.ansi_colors import RESET_TO_DEFAULT
7
+
8
+
9
+ @dataclass
10
+ class BaseError(Exception):
11
+ """
12
+ A basic error class for DSP-TOOLS.
13
+
14
+ Attributes:
15
+ message: A message that describes the error
16
+ """
17
+
18
+ message: str = ""
19
+
20
+ def __str__(self) -> str:
21
+ return self.message
22
+
23
+
24
+ class InternalError(BaseError):
25
+ """
26
+ Class for errors that are raised if the user cannot solve the problem themselves.
27
+ """
28
+
29
+ def __init__(self, custom_msg: str | None = None, keep_default_msg: bool = True) -> None:
30
+ default_msg = (
31
+ f"\n\n{BOLD_RED}An internal error occurred.{RESET_TO_DEFAULT}\n"
32
+ "Please contact the dsp-tools development team (at support@dasch.swiss) with the following information:\n"
33
+ " - Which command was used.\n"
34
+ " - If applicable, any files that were used in conjunction with the command.\n"
35
+ " - A text file with the terminal output copied into.\n"
36
+ f" - The log file at {LOGGER_SAVEPATH}.\n"
37
+ )
38
+ match keep_default_msg, custom_msg:
39
+ case False, str():
40
+ super().__init__(custom_msg)
41
+ case True, str():
42
+ default_msg = f"\n\n{custom_msg}\n--------------------------{default_msg}"
43
+ super().__init__(default_msg)
44
+ case _:
45
+ super().__init__(default_msg)
46
+
47
+
48
+ class DockerNotReachableError(BaseError):
49
+ """This error is raised when docker is not running."""
50
+
51
+ def __init__(self) -> None:
52
+ msg = "Docker is not running properly. Please start Docker and try again."
53
+ super().__init__(msg)
54
+
55
+
56
+ class DspApiNotReachableError(BaseError):
57
+ """This error is raised when the DSP-API could not be reached on localhost."""
58
+
59
+
60
+ class DspToolsRequestException(BaseError):
61
+ """Class for errors that are raised if any request exceptions happens."""
62
+
63
+
64
+ class InputError(BaseError):
65
+ """This error is raised when the user input is invalid. The message should be as user-friendly as possible."""
66
+
67
+
68
+ class UserError(BaseError):
69
+ """
70
+ This is a base class for all the errors that are raised when the user input is invalid.
71
+ The message should be as user-friendly as possible.
72
+ """
73
+
74
+
75
+ class InvalidGuiAttributeError(BaseError):
76
+ """This error is raised when a invalid gui-attribute is used."""
77
+
78
+
79
+ class FatalNonOkApiResponseCode(BaseError):
80
+ """This error is raised when the API gives an unexpected response, that we cannot anticipate and handle cleanly."""
81
+
82
+ def __init__(self, request_url: str, status_code: int, response_text: str) -> None:
83
+ resp_txt = response_text[:200] if len(response_text) > 200 else response_text
84
+ msg = (
85
+ f"We currently do not support the following API response code for this request.\n"
86
+ f"Status code: {status_code}\n"
87
+ f"Request URL: {request_url}\n"
88
+ f"Original Response: {resp_txt}\n"
89
+ f"Please contact support@dasch.swiss with the log file at {LOGGER_SAVEPATH}."
90
+ )
91
+ super().__init__(msg)
92
+
93
+
94
+ class UserFilepathNotFoundError(InputError):
95
+ """This error is raised if a filepath from the user does not exist."""
96
+
97
+ def __init__(self, filepath: str | Path) -> None:
98
+ msg = f"The provided filepath does not exist: {filepath}"
99
+ super().__init__(msg)
100
+
101
+
102
+ class UserDirectoryNotFoundError(InputError):
103
+ """This error is raised if a directory from the user does not exist."""
104
+
105
+ def __init__(self, directory: str | Path) -> None:
106
+ msg = f"The provided directory does not exist: {directory}"
107
+ super().__init__(msg)
108
+
109
+
110
+ class JSONFileParsingError(InputError):
111
+ """This error should be raised if the user provided input file cannot be parsed."""
112
+
113
+
114
+ class PermanentConnectionError(BaseError):
115
+ """This error is raised when all attempts to reconnect to DSP have failed."""
116
+
117
+
118
+ class InvalidInputError(BaseError):
119
+ """This error is raised if the API responds with a permanent error because of invalid input data"""
120
+
121
+
122
+ class ShaclValidationCliError(BaseError):
123
+ """This error is raised when the validate data docker command has problems"""
124
+
125
+
126
+ class ShaclValidationError(BaseError):
127
+ """This error is raised when an unexpected error occurs during the validation"""
128
+
129
+
130
+ class InvalidIngestFileNameError(InvalidInputError):
131
+ """This error is raised if INGEST rejects a file due to its name."""
132
+
133
+
134
+ class PermanentTimeOutError(BaseError):
135
+ """This error is raised when python throws a timeout due to no response from the DSP-API."""
136
+
137
+
138
+ class BadCredentialsError(PermanentConnectionError):
139
+ """This error is raised when DSP-API doesn't accept the prodived credentials."""
140
+
141
+
142
+ class XmlUploadError(BaseError):
143
+ """Represents an error raised in the context of the xmlupload."""
144
+
145
+
146
+ class XmlInputConversionError(BaseError):
147
+ """Represents an error raised in the context of the xmlupload."""
148
+
149
+
150
+ class Id2IriReplacementError(BaseError):
151
+ """Represents an error raised if an internal ID could not be found in the Id2Iri mapping."""
152
+
153
+
154
+ class DuplicateIdsInXmlAndId2IriMapping(InputError):
155
+ """
156
+ Represents an error raised if a resource ID that is in the Id2Iri mapping
157
+ is also used as a resource id in the new data.
158
+ """
159
+
160
+
161
+ class XmlUploadInterruptedError(XmlUploadError):
162
+ """Represents an error raised when the xmlupload was interrupted."""
163
+
164
+
165
+ class XmlUploadPermissionsNotFoundError(BaseError):
166
+ """Class for errors that are raised when a permission does not exist."""
167
+
168
+
169
+ class XmlUploadAuthorshipsNotFoundError(BaseError):
170
+ """Class for errors that are raised when an authorship id does not exist."""
171
+
172
+
173
+ class XmlUploadListNodeNotFoundError(BaseError):
174
+ """Class for errors that are raised when a list node does not exist."""
175
+
176
+
177
+ class UnknownDOAPException(BaseError):
178
+ """Class for errors that are raised if a DOAP cannot be parsed"""
179
+
180
+
181
+ class ProjectOntologyNotFound(BaseError):
182
+ """Class for errors that are raised if a project is expected to have 1 or more ontologies, but none were found."""
183
+
184
+ def __init__(self, shortcode: str) -> None:
185
+ msg = f"The project with the shortcode '{shortcode}' does not have any ontologies."
186
+ super().__init__(msg)
187
+
188
+
189
+ class ProjectNotFoundError(InputError):
190
+ """Class if a project is expected to exist but could not be found."""
191
+
192
+
193
+ class InvalidLicenseError(InputError):
194
+ """This error is raised when a license string cannot be parsed."""
195
+
196
+ license_str: str
197
+
198
+ def __init__(self, license_str: str) -> None:
199
+ msg = (
200
+ f"The provided license string is invalid and cannot be parsed: '{license_str}'"
201
+ "You must provide a license that can be parsed by xmllib.find_license_in_string(). "
202
+ "See https://docs.dasch.swiss/latest/DSP-TOOLS/xmllib-docs/general-functions/#xmllib.general_functions.find_license_in_string"
203
+ )
204
+ super().__init__(msg)
@@ -0,0 +1,10 @@
1
+ from typing import Protocol
2
+
3
+
4
+ class Problem(Protocol):
5
+ """Information about input errors."""
6
+
7
+ def execute_error_protocol(self) -> str:
8
+ """
9
+ This function initiates all the steps for successful problem communication with the user.
10
+ """
@@ -0,0 +1,20 @@
1
+ from dsp_tools.error.exceptions import BaseError
2
+
3
+
4
+ class XmllibInputError(BaseError):
5
+ """
6
+ This error is raised if a user provided invalid input.
7
+ It should never be raised plain, but with the dedicated util function.
8
+ """
9
+
10
+
11
+ class XmllibFileNotFoundError(BaseError):
12
+ """
13
+ This error is raised if a user provided a filepath that does not exist.
14
+ """
15
+
16
+
17
+ class XmllibInternalError(BaseError):
18
+ """
19
+ This error is raised if an internal error, i.e. an error on which the user has no influence, is found in the xmllib.
20
+ """
@@ -0,0 +1,54 @@
1
+ from abc import ABC
2
+ from abc import abstractmethod
3
+ from dataclasses import dataclass
4
+ from enum import StrEnum
5
+
6
+ from dsp_tools.utils.ansi_colors import BOLD_RED
7
+ from dsp_tools.utils.ansi_colors import RESET_TO_DEFAULT
8
+ from dsp_tools.utils.ansi_colors import YELLOW
9
+
10
+
11
+ class UserMessageSeverity(StrEnum):
12
+ INFO = "INFO"
13
+ WARNING = "WARNING"
14
+ ERROR = "ERROR"
15
+
16
+
17
+ @dataclass
18
+ class MessageInfo:
19
+ """
20
+ message: message about what went wrong
21
+ resource_id: ID of the affected resource
22
+ prop_name: property name of the affected property (if applicable)
23
+ field: information about which field of the resource is affected (if not the property), e.g. "resource id", "label"
24
+ """
25
+
26
+ message: str
27
+ resource_id: str | None = None
28
+ prop_name: str | None = None
29
+ field: str | None = None
30
+
31
+
32
+ class XmllibUserInfoBase(Warning, ABC):
33
+ """Base class for warnings that implement a custom showwarnings() function"""
34
+
35
+ @classmethod
36
+ @abstractmethod
37
+ def showwarning(cls, message: str) -> None:
38
+ """Functionality that should be executed when a warning of this class is emitted"""
39
+
40
+
41
+ class XmllibInputInfo(XmllibUserInfoBase):
42
+ """If the xmllib input may be problematic"""
43
+
44
+ @classmethod
45
+ def showwarning(cls, message: str) -> None:
46
+ print(YELLOW + f"INFO | {message}" + RESET_TO_DEFAULT)
47
+
48
+
49
+ class XmllibInputWarning(XmllibUserInfoBase):
50
+ """If the xmllib input is problematic"""
51
+
52
+ @classmethod
53
+ def showwarning(cls, message: str) -> None:
54
+ print(BOLD_RED + f"WARNING | {message}" + RESET_TO_DEFAULT)
@@ -0,0 +1,159 @@
1
+ import csv
2
+ import inspect
3
+ import os
4
+ import warnings
5
+ from typing import Any
6
+ from typing import Never
7
+
8
+ import regex
9
+ from dotenv import find_dotenv
10
+ from dotenv import load_dotenv
11
+
12
+ from dsp_tools.error.xmllib_errors import XmllibFileNotFoundError
13
+ from dsp_tools.error.xmllib_errors import XmllibInputError
14
+ from dsp_tools.error.xmllib_warnings import MessageInfo
15
+ from dsp_tools.error.xmllib_warnings import UserMessageSeverity
16
+ from dsp_tools.error.xmllib_warnings import XmllibInputInfo
17
+ from dsp_tools.error.xmllib_warnings import XmllibInputWarning
18
+ from dsp_tools.utils.ansi_colors import BOLD_YELLOW
19
+ from dsp_tools.utils.ansi_colors import RESET_TO_DEFAULT
20
+
21
+ load_dotenv(dotenv_path=find_dotenv(usecwd=True))
22
+
23
+
24
+ def initialise_warning_file() -> None:
25
+ if file_path := os.getenv("XMLLIB_WARNINGS_CSV_SAVEPATH"):
26
+ try:
27
+ new_row = ["File", "Severity", "Message", "Resource ID", "Property", "Field"]
28
+ with open(file_path, "w", newline="") as file:
29
+ print(
30
+ BOLD_YELLOW,
31
+ f"Warnings generated by the xmllib "
32
+ f"will be saved to '{file_path}' and will not be printed in the terminal.",
33
+ RESET_TO_DEFAULT,
34
+ )
35
+ writer = csv.writer(file)
36
+ writer.writerow(new_row)
37
+ except FileNotFoundError:
38
+ raise XmllibFileNotFoundError(
39
+ f"The filepath '{file_path}' you entered in your .env file does not exist. "
40
+ f"Please ensure that the folder you named exists."
41
+ ) from None
42
+
43
+
44
+ def write_message_to_csv(
45
+ file_path: str, msg: MessageInfo, function_trace: str | None, severity: UserMessageSeverity
46
+ ) -> None:
47
+ new_row = [
48
+ function_trace if function_trace else "",
49
+ str(severity),
50
+ msg.message if msg.message else "",
51
+ msg.resource_id if msg.resource_id else "",
52
+ msg.prop_name if msg.prop_name else "",
53
+ msg.field if msg.field else "",
54
+ ]
55
+ with open(file_path, "a", newline="") as file:
56
+ writer = csv.writer(file)
57
+ writer.writerow(new_row)
58
+
59
+
60
+ def get_user_message_string(msg: MessageInfo, function_trace: str | None) -> str:
61
+ str_list = [f"File '{function_trace}'"] if function_trace else []
62
+ if msg.resource_id:
63
+ str_list.append(f"Resource ID '{msg.resource_id}'")
64
+ if msg.prop_name:
65
+ str_list.append(f"Property '{msg.prop_name}'")
66
+ if msg.field:
67
+ str_list.append(f"Field '{msg.field}'")
68
+ str_list.append(msg.message)
69
+ return " | ".join(str_list)
70
+
71
+
72
+ def _get_calling_code_context() -> str | None:
73
+ """
74
+ Find file name and line number of the file that was written by the user.
75
+ """
76
+ all_stack_frames = inspect.stack()
77
+ frame_files = [x.filename for x in all_stack_frames]
78
+ calling_func_index = _get_stack_frame_number(frame_files)
79
+ if calling_func_index == 0:
80
+ return None
81
+ user_frame_info = all_stack_frames.pop(calling_func_index)
82
+ file_name = user_frame_info.filename.rsplit("/", 1)[1]
83
+ return f"{file_name}:{user_frame_info.lineno}"
84
+
85
+
86
+ def _get_stack_frame_number(file_names: list[str]) -> int:
87
+ """
88
+ Get index number of first python file of the stack trace which is not any more in the dsp-tools code.
89
+ This is the index of the first user python file.
90
+ """
91
+ calling_func_index = -1
92
+ for file in file_names:
93
+ if _filter_stack_frames(file):
94
+ calling_func_index += 1
95
+ else:
96
+ calling_func_index += 1
97
+ break
98
+ return calling_func_index
99
+
100
+
101
+ def _filter_stack_frames(file_path: str) -> bool:
102
+ dsp_tools_path = r"\/dsp[-_]tools\/(xmllib|error)\/"
103
+ if regex.search(dsp_tools_path, file_path):
104
+ return True
105
+ elif regex.search(r"^<[a-zA-Z]+>$", file_path):
106
+ # This is for functions like str(), which appear in the stack trace as filename "<string>"
107
+ return True
108
+ return False
109
+
110
+
111
+ def raise_xmllib_input_error(msg: MessageInfo) -> Never:
112
+ """These are to be used if the error is caused by user input."""
113
+ function_trace = _get_calling_code_context()
114
+ if file_path := os.getenv("XMLLIB_WARNINGS_CSV_SAVEPATH"):
115
+ write_message_to_csv(file_path, msg, function_trace, UserMessageSeverity.ERROR)
116
+ msg_str = get_user_message_string(msg, function_trace)
117
+ raise XmllibInputError(msg_str)
118
+
119
+
120
+ def emit_xmllib_input_warning(msg: MessageInfo) -> None:
121
+ """These are to be used if the error is caused by user input."""
122
+ if str(os.getenv("XMLLIB_IGNORE_USER_WARNING")).lower() == "true":
123
+ return
124
+ function_trace = _get_calling_code_context()
125
+ if file_path := os.getenv("XMLLIB_WARNINGS_CSV_SAVEPATH"):
126
+ write_message_to_csv(file_path, msg, function_trace, UserMessageSeverity.WARNING)
127
+ else:
128
+ msg_str = get_user_message_string(msg, function_trace)
129
+ warnings.warn(XmllibInputWarning(msg_str))
130
+
131
+
132
+ def emit_xmllib_input_info(msg: MessageInfo) -> None:
133
+ """These are to be used if the error is caused by user input."""
134
+ if str(os.getenv("XMLLIB_IGNORE_USER_INFO")).lower() == "true":
135
+ return
136
+ function_trace = _get_calling_code_context()
137
+ if file_path := os.getenv("XMLLIB_WARNINGS_CSV_SAVEPATH"):
138
+ write_message_to_csv(file_path, msg, function_trace, UserMessageSeverity.INFO)
139
+ else:
140
+ msg_str = get_user_message_string(msg, function_trace)
141
+ warnings.warn(XmllibInputInfo(msg_str))
142
+
143
+
144
+ def emit_xmllib_input_type_mismatch_warning(
145
+ *,
146
+ expected_type: str,
147
+ value: Any,
148
+ res_id: str | None,
149
+ value_field: str | None = None,
150
+ prop_name: str | None = None,
151
+ ) -> None:
152
+ """These are to be used if the error is caused by user input."""
153
+ msg_info = MessageInfo(
154
+ message=f"The input should be a valid {expected_type}, your input '{value}' does not match the type.",
155
+ resource_id=res_id,
156
+ prop_name=prop_name,
157
+ field=value_field,
158
+ )
159
+ emit_xmllib_input_warning(msg_info)
@@ -0,0 +1,19 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class XSDValidationMessage:
6
+ line_number: int
7
+ element: str | None
8
+ attribute: str | None
9
+ message: str
10
+
11
+
12
+ def get_xsd_validation_message_str(msg: XSDValidationMessage) -> str:
13
+ msg_list = [f"Line Number {msg.line_number}"]
14
+ if msg.element:
15
+ msg_list.append(f"Element '{msg.element}'")
16
+ if msg.attribute:
17
+ msg_list.append(f"Attribute '{msg.attribute}'")
18
+ msg_list.append(msg.message)
19
+ return " | ".join(msg_list)
File without changes
@@ -5,7 +5,7 @@ from typing import Union
5
5
 
6
6
  import regex
7
7
 
8
- from dsp_tools.models.exceptions import BaseError
8
+ from dsp_tools.error.exceptions import BaseError
9
9
 
10
10
 
11
11
  class DateTimeStamp:
@@ -44,27 +44,27 @@ class DateTimeStamp:
44
44
  else:
45
45
  raise BaseError(f"Invalid xsd:dateTimeStamp: '{val}'")
46
46
 
47
- def __eq__(self, other: Union[str, "DateTimeStamp"]) -> bool:
47
+ def __eq__(self, other: Union[str, DateTimeStamp]) -> bool:
48
48
  if isinstance(other, str):
49
49
  other = DateTimeStamp(other)
50
50
  return self._dateTimeStamp == other._dateTimeStamp
51
51
 
52
- def __lt__(self, other: "DateTimeStamp") -> bool:
52
+ def __lt__(self, other: DateTimeStamp) -> bool:
53
53
  if isinstance(other, str):
54
54
  other = DateTimeStamp(other)
55
55
  return self._dateTimeStamp < other._dateTimeStamp
56
56
 
57
- def __le__(self, other: "DateTimeStamp") -> bool:
57
+ def __le__(self, other: DateTimeStamp) -> bool:
58
58
  if isinstance(other, str):
59
59
  other = DateTimeStamp(other)
60
60
  return self._dateTimeStamp <= other._dateTimeStamp
61
61
 
62
- def __gt__(self, other: "DateTimeStamp") -> bool:
62
+ def __gt__(self, other: DateTimeStamp) -> bool:
63
63
  if isinstance(other, str):
64
64
  other = DateTimeStamp(other)
65
65
  return self._dateTimeStamp > other._dateTimeStamp
66
66
 
67
- def __ge__(self, other: "DateTimeStamp") -> bool:
67
+ def __ge__(self, other: DateTimeStamp) -> bool:
68
68
  if isinstance(other, str):
69
69
  other = DateTimeStamp(other)
70
70
  return self._dateTimeStamp >= other._dateTimeStamp
@@ -74,7 +74,7 @@ class DateTimeStamp:
74
74
  other = DateTimeStamp(other)
75
75
  return self._dateTimeStamp != other._dateTimeStamp
76
76
 
77
- def __str__(self: "DateTimeStamp") -> str:
77
+ def __str__(self: DateTimeStamp) -> str:
78
78
  return self._dateTimeStamp
79
79
 
80
80
  def toJsonObj(self) -> dict[str, str]:
@@ -4,7 +4,7 @@ from typing import Any
4
4
  from typing import Optional
5
5
  from typing import Union
6
6
 
7
- from dsp_tools.models.exceptions import BaseError
7
+ from dsp_tools.error.exceptions import BaseError
8
8
 
9
9
 
10
10
  @unique
@@ -1,9 +1,9 @@
1
1
  from typing import Optional
2
2
 
3
- from dsp_tools.commands.project.models.group import Group
4
- from dsp_tools.commands.project.models.project import Project
5
- from dsp_tools.models.exceptions import BaseError
6
- from dsp_tools.utils.connection import Connection
3
+ from dsp_tools.clients.connection import Connection
4
+ from dsp_tools.commands.get.legacy_models.group import Group
5
+ from dsp_tools.commands.get.legacy_models.project import Project
6
+ from dsp_tools.error.exceptions import BaseError
7
7
 
8
8
 
9
9
  class ProjectContext: