dsp-tools 0.9.13__py3-none-any.whl → 18.3.0.post13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. dsp_tools/__init__.py +5 -0
  2. dsp_tools/cli/args.py +47 -0
  3. dsp_tools/cli/call_action.py +85 -0
  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 +479 -0
  7. dsp_tools/cli/entry_point.py +322 -0
  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/clients/connection.py +35 -0
  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 +321 -0
  58. dsp_tools/commands/excel2json/lists/__init__.py +0 -0
  59. dsp_tools/commands/excel2json/lists/compliance_checks.py +292 -0
  60. dsp_tools/commands/excel2json/lists/make_lists.py +247 -0
  61. dsp_tools/commands/excel2json/lists/models/__init__.py +0 -0
  62. dsp_tools/commands/excel2json/lists/models/deserialise.py +30 -0
  63. dsp_tools/commands/excel2json/lists/models/input_error.py +216 -0
  64. dsp_tools/commands/excel2json/lists/models/serialise.py +57 -0
  65. dsp_tools/commands/excel2json/lists/utils.py +81 -0
  66. dsp_tools/commands/excel2json/models/__init__.py +0 -0
  67. dsp_tools/commands/excel2json/models/input_error.py +416 -0
  68. dsp_tools/commands/excel2json/models/json_header.py +175 -0
  69. dsp_tools/commands/excel2json/models/list_node_name.py +16 -0
  70. dsp_tools/commands/excel2json/models/ontology.py +76 -0
  71. dsp_tools/commands/excel2json/old_lists.py +328 -0
  72. dsp_tools/commands/excel2json/project.py +280 -0
  73. dsp_tools/commands/excel2json/properties.py +370 -0
  74. dsp_tools/commands/excel2json/resources.py +336 -0
  75. dsp_tools/commands/excel2json/utils.py +352 -0
  76. dsp_tools/commands/excel2xml/__init__.py +7 -0
  77. dsp_tools/commands/excel2xml/excel2xml_cli.py +523 -0
  78. dsp_tools/commands/excel2xml/excel2xml_lib.py +1953 -0
  79. dsp_tools/commands/excel2xml/propertyelement.py +47 -0
  80. dsp_tools/commands/get/__init__.py +0 -0
  81. dsp_tools/commands/get/get.py +166 -0
  82. dsp_tools/commands/get/get_permissions.py +257 -0
  83. dsp_tools/commands/get/get_permissions_legacy.py +89 -0
  84. dsp_tools/commands/get/legacy_models/__init__.py +0 -0
  85. dsp_tools/commands/get/legacy_models/context.py +318 -0
  86. dsp_tools/commands/get/legacy_models/group.py +241 -0
  87. dsp_tools/commands/get/legacy_models/helpers.py +47 -0
  88. dsp_tools/commands/get/legacy_models/listnode.py +390 -0
  89. dsp_tools/commands/get/legacy_models/model.py +12 -0
  90. dsp_tools/commands/get/legacy_models/ontology.py +324 -0
  91. dsp_tools/commands/get/legacy_models/project.py +366 -0
  92. dsp_tools/commands/get/legacy_models/propertyclass.py +417 -0
  93. dsp_tools/commands/get/legacy_models/resourceclass.py +676 -0
  94. dsp_tools/commands/get/legacy_models/user.py +438 -0
  95. dsp_tools/commands/get/models/__init__.py +0 -0
  96. dsp_tools/commands/get/models/permissions_models.py +10 -0
  97. dsp_tools/commands/id2iri.py +258 -0
  98. dsp_tools/commands/ingest_xmlupload/__init__.py +0 -0
  99. dsp_tools/commands/ingest_xmlupload/bulk_ingest_client.py +178 -0
  100. dsp_tools/commands/ingest_xmlupload/create_resources/__init__.py +0 -0
  101. dsp_tools/commands/ingest_xmlupload/create_resources/apply_ingest_id.py +69 -0
  102. dsp_tools/commands/ingest_xmlupload/create_resources/upload_xml.py +166 -0
  103. dsp_tools/commands/ingest_xmlupload/create_resources/user_information.py +121 -0
  104. dsp_tools/commands/ingest_xmlupload/ingest_files/__init__.py +0 -0
  105. dsp_tools/commands/ingest_xmlupload/ingest_files/ingest_files.py +64 -0
  106. dsp_tools/commands/ingest_xmlupload/upload_files/__init__.py +0 -0
  107. dsp_tools/commands/ingest_xmlupload/upload_files/filechecker.py +20 -0
  108. dsp_tools/commands/ingest_xmlupload/upload_files/input_error.py +57 -0
  109. dsp_tools/commands/ingest_xmlupload/upload_files/upload_failures.py +66 -0
  110. dsp_tools/commands/ingest_xmlupload/upload_files/upload_files.py +67 -0
  111. dsp_tools/commands/resume_xmlupload/__init__.py +0 -0
  112. dsp_tools/commands/resume_xmlupload/resume_xmlupload.py +96 -0
  113. dsp_tools/commands/start_stack.py +428 -0
  114. dsp_tools/commands/update_legal/CLAUDE.md +344 -0
  115. dsp_tools/commands/update_legal/__init__.py +0 -0
  116. dsp_tools/commands/update_legal/core.py +182 -0
  117. dsp_tools/commands/update_legal/csv_operations.py +135 -0
  118. dsp_tools/commands/update_legal/models.py +87 -0
  119. dsp_tools/commands/update_legal/xml_operations.py +247 -0
  120. dsp_tools/commands/validate_data/CLAUDE.md +159 -0
  121. dsp_tools/commands/validate_data/__init__.py +0 -0
  122. dsp_tools/commands/validate_data/constants.py +59 -0
  123. dsp_tools/commands/validate_data/mappers.py +143 -0
  124. dsp_tools/commands/validate_data/models/__init__.py +0 -0
  125. dsp_tools/commands/validate_data/models/api_responses.py +45 -0
  126. dsp_tools/commands/validate_data/models/input_problems.py +119 -0
  127. dsp_tools/commands/validate_data/models/rdf_like_data.py +117 -0
  128. dsp_tools/commands/validate_data/models/validation.py +106 -0
  129. dsp_tools/commands/validate_data/prepare_data/__init__.py +0 -0
  130. dsp_tools/commands/validate_data/prepare_data/get_rdf_like_data.py +296 -0
  131. dsp_tools/commands/validate_data/prepare_data/make_data_graph.py +91 -0
  132. dsp_tools/commands/validate_data/prepare_data/prepare_data.py +184 -0
  133. dsp_tools/commands/validate_data/process_validation_report/__init__.py +0 -0
  134. dsp_tools/commands/validate_data/process_validation_report/get_user_validation_message.py +358 -0
  135. dsp_tools/commands/validate_data/process_validation_report/query_validation_result.py +507 -0
  136. dsp_tools/commands/validate_data/process_validation_report/reformat_validation_results.py +150 -0
  137. dsp_tools/commands/validate_data/shacl_cli_validator.py +70 -0
  138. dsp_tools/commands/validate_data/sparql/__init__.py +0 -0
  139. dsp_tools/commands/validate_data/sparql/cardinality_shacl.py +209 -0
  140. dsp_tools/commands/validate_data/sparql/construct_shacl.py +92 -0
  141. dsp_tools/commands/validate_data/sparql/legal_info_shacl.py +36 -0
  142. dsp_tools/commands/validate_data/sparql/value_shacl.py +357 -0
  143. dsp_tools/commands/validate_data/utils.py +59 -0
  144. dsp_tools/commands/validate_data/validate_data.py +283 -0
  145. dsp_tools/commands/validate_data/validation/__init__.py +0 -0
  146. dsp_tools/commands/validate_data/validation/check_duplicate_files.py +55 -0
  147. dsp_tools/commands/validate_data/validation/check_for_unknown_classes.py +67 -0
  148. dsp_tools/commands/validate_data/validation/get_validation_report.py +94 -0
  149. dsp_tools/commands/validate_data/validation/validate_ontology.py +107 -0
  150. dsp_tools/commands/xmlupload/CLAUDE.md +292 -0
  151. dsp_tools/commands/xmlupload/__init__.py +0 -0
  152. dsp_tools/commands/xmlupload/iri_resolver.py +21 -0
  153. dsp_tools/commands/xmlupload/make_rdf_graph/__init__.py +0 -0
  154. dsp_tools/commands/xmlupload/make_rdf_graph/constants.py +63 -0
  155. dsp_tools/commands/xmlupload/make_rdf_graph/jsonld_utils.py +44 -0
  156. dsp_tools/commands/xmlupload/make_rdf_graph/make_file_value.py +77 -0
  157. dsp_tools/commands/xmlupload/make_rdf_graph/make_resource_and_values.py +114 -0
  158. dsp_tools/commands/xmlupload/make_rdf_graph/make_values.py +262 -0
  159. dsp_tools/commands/xmlupload/models/__init__.py +0 -0
  160. dsp_tools/commands/xmlupload/models/bitstream_info.py +18 -0
  161. dsp_tools/commands/xmlupload/models/formatted_text_value.py +10 -0
  162. dsp_tools/commands/xmlupload/models/ingest.py +143 -0
  163. dsp_tools/commands/xmlupload/models/input_problems.py +58 -0
  164. dsp_tools/commands/xmlupload/models/lookup_models.py +21 -0
  165. dsp_tools/commands/xmlupload/models/permission.py +45 -0
  166. dsp_tools/commands/xmlupload/models/permissions_parsed.py +93 -0
  167. dsp_tools/commands/xmlupload/models/processed/__init__.py +0 -0
  168. dsp_tools/commands/xmlupload/models/processed/file_values.py +29 -0
  169. dsp_tools/commands/xmlupload/models/processed/res.py +27 -0
  170. dsp_tools/commands/xmlupload/models/processed/values.py +101 -0
  171. dsp_tools/commands/xmlupload/models/rdf_models.py +26 -0
  172. dsp_tools/commands/xmlupload/models/upload_clients.py +14 -0
  173. dsp_tools/commands/xmlupload/models/upload_state.py +20 -0
  174. dsp_tools/commands/xmlupload/prepare_xml_input/__init__.py +0 -0
  175. dsp_tools/commands/xmlupload/prepare_xml_input/ark2iri.py +55 -0
  176. dsp_tools/commands/xmlupload/prepare_xml_input/get_processed_resources.py +252 -0
  177. dsp_tools/commands/xmlupload/prepare_xml_input/iiif_uri_validator.py +50 -0
  178. dsp_tools/commands/xmlupload/prepare_xml_input/list_client.py +120 -0
  179. dsp_tools/commands/xmlupload/prepare_xml_input/prepare_xml_input.py +67 -0
  180. dsp_tools/commands/xmlupload/prepare_xml_input/read_validate_xml_file.py +58 -0
  181. dsp_tools/commands/xmlupload/prepare_xml_input/transform_input_values.py +118 -0
  182. dsp_tools/commands/xmlupload/resource_create_client.py +25 -0
  183. dsp_tools/commands/xmlupload/richtext_id2iri.py +37 -0
  184. dsp_tools/commands/xmlupload/stash/__init__.py +0 -0
  185. dsp_tools/commands/xmlupload/stash/analyse_circular_reference_graph.py +236 -0
  186. dsp_tools/commands/xmlupload/stash/create_info_for_graph.py +53 -0
  187. dsp_tools/commands/xmlupload/stash/graph_models.py +87 -0
  188. dsp_tools/commands/xmlupload/stash/stash_circular_references.py +68 -0
  189. dsp_tools/commands/xmlupload/stash/stash_models.py +109 -0
  190. dsp_tools/commands/xmlupload/stash/upload_stashed_resptr_props.py +106 -0
  191. dsp_tools/commands/xmlupload/stash/upload_stashed_xml_texts.py +196 -0
  192. dsp_tools/commands/xmlupload/upload_config.py +76 -0
  193. dsp_tools/commands/xmlupload/write_diagnostic_info.py +27 -0
  194. dsp_tools/commands/xmlupload/xmlupload.py +516 -0
  195. dsp_tools/config/__init__.py +0 -0
  196. dsp_tools/config/logger_config.py +69 -0
  197. dsp_tools/config/warnings_config.py +32 -0
  198. dsp_tools/error/__init__.py +0 -0
  199. dsp_tools/error/custom_warnings.py +39 -0
  200. dsp_tools/error/exceptions.py +204 -0
  201. dsp_tools/error/problems.py +10 -0
  202. dsp_tools/error/xmllib_errors.py +20 -0
  203. dsp_tools/error/xmllib_warnings.py +54 -0
  204. dsp_tools/error/xmllib_warnings_util.py +159 -0
  205. dsp_tools/error/xsd_validation_error_msg.py +19 -0
  206. dsp_tools/legacy_models/__init__.py +0 -0
  207. dsp_tools/legacy_models/datetimestamp.py +81 -0
  208. dsp_tools/legacy_models/langstring.py +253 -0
  209. dsp_tools/legacy_models/projectContext.py +49 -0
  210. dsp_tools/py.typed +0 -0
  211. dsp_tools/resources/schema/data.xsd +648 -0
  212. dsp_tools/resources/schema/lists-only.json +72 -0
  213. dsp_tools/resources/schema/project.json +1258 -0
  214. dsp_tools/resources/schema/properties-only.json +874 -0
  215. dsp_tools/resources/schema/resources-only.json +140 -0
  216. dsp_tools/resources/start-stack/docker-compose.override-host.j2 +11 -0
  217. dsp_tools/resources/start-stack/docker-compose.override.yml +11 -0
  218. dsp_tools/resources/start-stack/docker-compose.yml +88 -0
  219. dsp_tools/resources/start-stack/dsp-app-config.json +45 -0
  220. dsp_tools/resources/start-stack/dsp-app-config.override-host.j2 +26 -0
  221. dsp_tools/resources/validate_data/api-shapes-resource-cardinalities.ttl +191 -0
  222. dsp_tools/resources/validate_data/api-shapes.ttl +804 -0
  223. dsp_tools/resources/validate_data/shacl-cli-image.yml +4 -0
  224. dsp_tools/resources/validate_data/validate-ontology.ttl +99 -0
  225. dsp_tools/utils/__init__.py +0 -0
  226. dsp_tools/utils/ansi_colors.py +32 -0
  227. dsp_tools/utils/data_formats/__init__.py +0 -0
  228. dsp_tools/utils/data_formats/date_util.py +166 -0
  229. dsp_tools/utils/data_formats/iri_util.py +30 -0
  230. dsp_tools/utils/data_formats/shared.py +81 -0
  231. dsp_tools/utils/data_formats/uri_util.py +76 -0
  232. dsp_tools/utils/fuseki_bloating.py +63 -0
  233. dsp_tools/utils/json_parsing.py +22 -0
  234. dsp_tools/utils/rdf_constants.py +42 -0
  235. dsp_tools/utils/rdflib_utils.py +10 -0
  236. dsp_tools/utils/replace_id_with_iri.py +66 -0
  237. dsp_tools/utils/request_utils.py +238 -0
  238. dsp_tools/utils/xml_parsing/__init__.py +0 -0
  239. dsp_tools/utils/xml_parsing/get_lookups.py +32 -0
  240. dsp_tools/utils/xml_parsing/get_parsed_resources.py +325 -0
  241. dsp_tools/utils/xml_parsing/models/__init__.py +0 -0
  242. dsp_tools/utils/xml_parsing/models/parsed_resource.py +76 -0
  243. dsp_tools/utils/xml_parsing/parse_clean_validate_xml.py +137 -0
  244. dsp_tools/xmllib/CLAUDE.md +302 -0
  245. dsp_tools/xmllib/__init__.py +49 -0
  246. dsp_tools/xmllib/general_functions.py +877 -0
  247. dsp_tools/xmllib/internal/__init__.py +0 -0
  248. dsp_tools/xmllib/internal/checkers.py +162 -0
  249. dsp_tools/xmllib/internal/circumvent_circular_imports.py +36 -0
  250. dsp_tools/xmllib/internal/constants.py +46 -0
  251. dsp_tools/xmllib/internal/input_converters.py +155 -0
  252. dsp_tools/xmllib/internal/serialise_file_value.py +57 -0
  253. dsp_tools/xmllib/internal/serialise_resource.py +177 -0
  254. dsp_tools/xmllib/internal/serialise_values.py +152 -0
  255. dsp_tools/xmllib/internal/type_aliases.py +11 -0
  256. dsp_tools/xmllib/models/__init__.py +0 -0
  257. dsp_tools/xmllib/models/config_options.py +28 -0
  258. dsp_tools/xmllib/models/date_formats.py +48 -0
  259. dsp_tools/xmllib/models/dsp_base_resources.py +1542 -0
  260. dsp_tools/xmllib/models/internal/__init__.py +0 -0
  261. dsp_tools/xmllib/models/internal/file_values.py +172 -0
  262. dsp_tools/xmllib/models/internal/geometry.py +162 -0
  263. dsp_tools/xmllib/models/internal/migration_metadata.py +55 -0
  264. dsp_tools/xmllib/models/internal/serialise_permissions.py +66 -0
  265. dsp_tools/xmllib/models/internal/values.py +342 -0
  266. dsp_tools/xmllib/models/licenses/__init__.py +0 -0
  267. dsp_tools/xmllib/models/licenses/other.py +59 -0
  268. dsp_tools/xmllib/models/licenses/recommended.py +107 -0
  269. dsp_tools/xmllib/models/permissions.py +41 -0
  270. dsp_tools/xmllib/models/res.py +1782 -0
  271. dsp_tools/xmllib/models/root.py +348 -0
  272. dsp_tools/xmllib/value_checkers.py +434 -0
  273. dsp_tools/xmllib/value_converters.py +777 -0
  274. dsp_tools-18.3.0.post13.dist-info/METADATA +90 -0
  275. dsp_tools-18.3.0.post13.dist-info/RECORD +286 -0
  276. dsp_tools-18.3.0.post13.dist-info/WHEEL +4 -0
  277. dsp_tools-18.3.0.post13.dist-info/entry_points.txt +3 -0
  278. dsp_tools-0.9.13.dist-info/LICENSE +0 -674
  279. dsp_tools-0.9.13.dist-info/METADATA +0 -144
  280. dsp_tools-0.9.13.dist-info/RECORD +0 -71
  281. dsp_tools-0.9.13.dist-info/WHEEL +0 -5
  282. dsp_tools-0.9.13.dist-info/entry_points.txt +0 -3
  283. dsp_tools-0.9.13.dist-info/top_level.txt +0 -1
  284. dsplib/models/connection.py +0 -272
  285. dsplib/models/group.py +0 -296
  286. dsplib/models/helpers.py +0 -505
  287. dsplib/models/langstring.py +0 -277
  288. dsplib/models/listnode.py +0 -578
  289. dsplib/models/model.py +0 -20
  290. dsplib/models/ontology.py +0 -448
  291. dsplib/models/permission.py +0 -112
  292. dsplib/models/project.py +0 -547
  293. dsplib/models/propertyclass.py +0 -505
  294. dsplib/models/resource.py +0 -366
  295. dsplib/models/resourceclass.py +0 -810
  296. dsplib/models/sipi.py +0 -30
  297. dsplib/models/user.py +0 -731
  298. dsplib/models/value.py +0 -1000
  299. dsplib/utils/knora-data-schema.xsd +0 -454
  300. dsplib/utils/knora-schema-lists.json +0 -83
  301. dsplib/utils/knora-schema.json +0 -434
  302. dsplib/utils/onto_commons.py +0 -24
  303. dsplib/utils/onto_create_lists.py +0 -73
  304. dsplib/utils/onto_create_ontology.py +0 -442
  305. dsplib/utils/onto_get.py +0 -58
  306. dsplib/utils/onto_validate.py +0 -33
  307. dsplib/utils/xml_upload.py +0 -539
  308. dsplib/widgets/doublepassword.py +0 -80
  309. knora/MLS-import-libraries.py +0 -84
  310. knora/dsp_tools.py +0 -96
  311. knora/dsplib/models/connection.py +0 -272
  312. knora/dsplib/models/group.py +0 -296
  313. knora/dsplib/models/helpers.py +0 -506
  314. knora/dsplib/models/langstring.py +0 -277
  315. knora/dsplib/models/listnode.py +0 -578
  316. knora/dsplib/models/model.py +0 -20
  317. knora/dsplib/models/ontology.py +0 -448
  318. knora/dsplib/models/permission.py +0 -112
  319. knora/dsplib/models/project.py +0 -583
  320. knora/dsplib/models/propertyclass.py +0 -505
  321. knora/dsplib/models/resource.py +0 -416
  322. knora/dsplib/models/resourceclass.py +0 -811
  323. knora/dsplib/models/sipi.py +0 -35
  324. knora/dsplib/models/user.py +0 -731
  325. knora/dsplib/models/value.py +0 -1000
  326. knora/dsplib/utils/knora-data-schema.xsd +0 -464
  327. knora/dsplib/utils/knora-schema-lists.json +0 -83
  328. knora/dsplib/utils/knora-schema.json +0 -444
  329. knora/dsplib/utils/onto_commons.py +0 -24
  330. knora/dsplib/utils/onto_create_lists.py +0 -73
  331. knora/dsplib/utils/onto_create_ontology.py +0 -451
  332. knora/dsplib/utils/onto_get.py +0 -58
  333. knora/dsplib/utils/onto_validate.py +0 -33
  334. knora/dsplib/utils/xml_upload.py +0 -540
  335. knora/dsplib/widgets/doublepassword.py +0 -80
  336. knora/knora.py +0 -2108
  337. knora/test.py +0 -99
  338. knora/testit.py +0 -76
  339. knora/xml2knora.py +0 -633
  340. {dsplib → dsp_tools/cli}/__init__.py +0 -0
  341. {dsplib/models → dsp_tools/clients}/__init__.py +0 -0
  342. {dsplib/utils → dsp_tools/commands}/__init__.py +0 -0
  343. {dsplib/widgets → dsp_tools/commands/create}/__init__.py +0 -0
  344. {knora → dsp_tools/commands/create/create_on_server}/__init__.py +0 -0
  345. {knora/dsplib → dsp_tools/commands/create/models}/__init__.py +0 -0
  346. {knora/dsplib/models → dsp_tools/commands/create/parsing}/__init__.py +0 -0
  347. {knora/dsplib/utils → dsp_tools/commands/create/serialisation}/__init__.py +0 -0
  348. {knora/dsplib/widgets → dsp_tools/commands/excel2json}/__init__.py +0 -0
@@ -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
@@ -0,0 +1,81 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+ from typing import Union
5
+
6
+ import regex
7
+
8
+ from dsp_tools.error.exceptions import BaseError
9
+
10
+
11
+ class DateTimeStamp:
12
+ """
13
+ Class to hold and process an xsd:dateTimeStamp
14
+ """
15
+
16
+ _dateTimeStamp: str
17
+ _validation_regex = (
18
+ r"^-?([1-9][0-9]{3,}|0[0-9]{3})"
19
+ r"-(0[1-9]|1[0-2])"
20
+ r"-(0[1-9]|[12][0-9]|3[01])"
21
+ r"T(([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]+)?|(24:00:00(\.0+)?))"
22
+ r"(Z|(\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))$"
23
+ )
24
+
25
+ def __init__(self, val: Any):
26
+ """
27
+ The constructor works for different inputs: a string, an instance of "DateTimeStamp",
28
+ or a JSON-LD construct of the form { "@type": "xsd:dateTimeStamp", "@value": "date-str" }
29
+
30
+ Args:
31
+ val: xsd:dateTimeStamp as string, instance of "DateTimeStamp" or json-ld construct
32
+
33
+ Raises:
34
+ BaseError: if the JSON-LD construct is not correct
35
+ """
36
+ if isinstance(val, str):
37
+ if not regex.search(self._validation_regex, val):
38
+ raise BaseError(f"Invalid xsd:dateTimeStamp: '{val}'")
39
+ self._dateTimeStamp = val
40
+ elif isinstance(val, DateTimeStamp):
41
+ self._dateTimeStamp = str(val)
42
+ elif val.get("@type") == "xsd:dateTimeStamp" and regex.search(self._validation_regex, str(val.get("@value"))):
43
+ self._dateTimeStamp = val["@value"]
44
+ else:
45
+ raise BaseError(f"Invalid xsd:dateTimeStamp: '{val}'")
46
+
47
+ def __eq__(self, other: Union[str, DateTimeStamp]) -> bool:
48
+ if isinstance(other, str):
49
+ other = DateTimeStamp(other)
50
+ return self._dateTimeStamp == other._dateTimeStamp
51
+
52
+ def __lt__(self, other: DateTimeStamp) -> bool:
53
+ if isinstance(other, str):
54
+ other = DateTimeStamp(other)
55
+ return self._dateTimeStamp < other._dateTimeStamp
56
+
57
+ def __le__(self, other: DateTimeStamp) -> bool:
58
+ if isinstance(other, str):
59
+ other = DateTimeStamp(other)
60
+ return self._dateTimeStamp <= other._dateTimeStamp
61
+
62
+ def __gt__(self, other: DateTimeStamp) -> bool:
63
+ if isinstance(other, str):
64
+ other = DateTimeStamp(other)
65
+ return self._dateTimeStamp > other._dateTimeStamp
66
+
67
+ def __ge__(self, other: DateTimeStamp) -> bool:
68
+ if isinstance(other, str):
69
+ other = DateTimeStamp(other)
70
+ return self._dateTimeStamp >= other._dateTimeStamp
71
+
72
+ def __ne__(self, other: DateTimeStamp) -> bool:
73
+ if isinstance(other, str):
74
+ other = DateTimeStamp(other)
75
+ return self._dateTimeStamp != other._dateTimeStamp
76
+
77
+ def __str__(self: DateTimeStamp) -> str:
78
+ return self._dateTimeStamp
79
+
80
+ def toJsonObj(self) -> dict[str, str]:
81
+ return {"@type": "xsd:dateTimeStamp", "@value": self._dateTimeStamp}