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,243 @@
1
+ from typing import Any
2
+ from typing import cast
3
+
4
+ from dsp_tools.commands.create.models.create_problems import CollectedProblems
5
+ from dsp_tools.commands.create.models.create_problems import CreateProblem
6
+ from dsp_tools.commands.create.models.create_problems import InputProblem
7
+ from dsp_tools.commands.create.models.create_problems import InputProblemType
8
+ from dsp_tools.commands.create.models.parsed_ontology import Cardinality
9
+ from dsp_tools.commands.create.models.parsed_ontology import GuiElement
10
+ from dsp_tools.commands.create.models.parsed_ontology import KnoraObjectType
11
+ from dsp_tools.commands.create.models.parsed_ontology import ParsedClass
12
+ from dsp_tools.commands.create.models.parsed_ontology import ParsedClassCardinalities
13
+ from dsp_tools.commands.create.models.parsed_ontology import ParsedOntology
14
+ from dsp_tools.commands.create.models.parsed_ontology import ParsedProperty
15
+ from dsp_tools.commands.create.models.parsed_ontology import ParsedPropertyCardinality
16
+ from dsp_tools.commands.create.parsing.parsing_utils import resolve_to_absolute_iri
17
+
18
+ CARDINALITY_MAPPER = {
19
+ "0-1": Cardinality.C_0_1,
20
+ "1": Cardinality.C_1,
21
+ "0-n": Cardinality.C_0_N,
22
+ "1-n": Cardinality.C_1_N,
23
+ }
24
+
25
+ OBJECT_TYPE_MAPPER = {
26
+ "BooleanValue": KnoraObjectType.BOOLEAN,
27
+ "ColorValue": KnoraObjectType.COLOR,
28
+ "DateValue": KnoraObjectType.DATE,
29
+ "DecimalValue": KnoraObjectType.DECIMAL,
30
+ "GeonameValue": KnoraObjectType.GEONAME,
31
+ "IntValue": KnoraObjectType.INT,
32
+ "ListValue": KnoraObjectType.LIST,
33
+ "TextValue": KnoraObjectType.TEXT,
34
+ "TimeValue": KnoraObjectType.TIME,
35
+ "UriValue": KnoraObjectType.URI,
36
+ }
37
+
38
+ GUI_ELEMENT_MAPPER = {
39
+ "Checkbox": GuiElement.CHECKBOX,
40
+ "Colorpicker": GuiElement.COLORPICKER,
41
+ "Date": GuiElement.DATE,
42
+ "Spinbox": GuiElement.SPINBOX,
43
+ "Geonames": GuiElement.GEONAMES,
44
+ "List": GuiElement.LIST,
45
+ "SimpleText": GuiElement.SIMPLETEXT,
46
+ "Textarea": GuiElement.TEXTAREA,
47
+ "Richtext": GuiElement.RICHTEXT,
48
+ "Searchbox": GuiElement.SEARCHBOX,
49
+ "TimeStamp": GuiElement.TIME_STAMP,
50
+ }
51
+
52
+
53
+ def parse_ontology(ontology_json: dict[str, Any], prefixes: dict[str, str]) -> ParsedOntology | CollectedProblems:
54
+ onto_name = ontology_json["name"]
55
+ current_onto = prefixes[onto_name]
56
+ fails = []
57
+ props, prop_fails = _parse_properties(ontology_json["properties"], current_onto, prefixes)
58
+ fails.extend(prop_fails)
59
+ classes, cls_fails = _parse_classes(ontology_json["resources"], current_onto, prefixes)
60
+ fails.extend(cls_fails)
61
+ cards, card_fails = _parse_cardinalities(ontology_json["resources"], current_onto, prefixes)
62
+ fails.extend(card_fails)
63
+ if fails:
64
+ return CollectedProblems(
65
+ f"During the parsing of the ontology '{onto_name}' the following errors occurred", fails
66
+ )
67
+ return ParsedOntology(
68
+ name=onto_name,
69
+ label=ontology_json["label"],
70
+ comment=ontology_json.get("comment"),
71
+ classes=classes,
72
+ properties=props,
73
+ cardinalities=cards,
74
+ )
75
+
76
+
77
+ def _parse_properties(
78
+ properties_list: list[dict[str, Any]],
79
+ current_onto_prefix: str,
80
+ prefixes: dict[str, str],
81
+ ) -> tuple[list[ParsedProperty], list[CreateProblem]]:
82
+ problems: list[CreateProblem] = []
83
+ parsed = []
84
+ for prop in properties_list:
85
+ result = _parse_one_property(prop, current_onto_prefix, prefixes)
86
+ if isinstance(result, ParsedProperty):
87
+ parsed.append(result)
88
+ else:
89
+ problems.extend(result)
90
+ return parsed, problems
91
+
92
+
93
+ def _parse_one_property(
94
+ prop: dict[str, Any], current_onto_prefix: str, prefixes: dict[str, str]
95
+ ) -> ParsedProperty | list[CreateProblem]:
96
+ problems: list[CreateProblem] = []
97
+ prop_name = f"{current_onto_prefix}{prop['name']}"
98
+ labels = prop["labels"]
99
+ comments = prop.get("comments")
100
+ object_str = prop["object"]
101
+ gui_element = GUI_ELEMENT_MAPPER[prop["gui_element"]]
102
+ subject = prop.get("subject")
103
+
104
+ supers = []
105
+ for super_prop in prop["super"]:
106
+ if not (resolved := resolve_to_absolute_iri(super_prop, current_onto_prefix, prefixes)):
107
+ problems.append(
108
+ InputProblem(
109
+ f'At property "{prop["name"]}" / Super: "{super_prop}"',
110
+ InputProblemType.PREFIX_COULD_NOT_BE_RESOLVED,
111
+ )
112
+ )
113
+ else:
114
+ supers.append(resolved)
115
+
116
+ if gui_element == GuiElement.SEARCHBOX:
117
+ if not (obj_iri := resolve_to_absolute_iri(object_str, current_onto_prefix, prefixes)):
118
+ problems.append(
119
+ InputProblem(
120
+ f'At property "{prop["name"]}" / Object: "{object_str}"',
121
+ InputProblemType.PREFIX_COULD_NOT_BE_RESOLVED,
122
+ )
123
+ )
124
+ object_value = ""
125
+ else:
126
+ object_value = obj_iri
127
+ else:
128
+ object_value = OBJECT_TYPE_MAPPER[object_str]
129
+
130
+ if subject:
131
+ if not (resolved_subject := resolve_to_absolute_iri(prop["subject"], current_onto_prefix, prefixes)):
132
+ problems.append(
133
+ InputProblem(
134
+ f'At property "{prop["name"]}" / Subject: "{subject}"',
135
+ InputProblemType.PREFIX_COULD_NOT_BE_RESOLVED,
136
+ )
137
+ )
138
+ subject = resolved_subject
139
+
140
+ list_name = None
141
+ if object_value == KnoraObjectType.LIST:
142
+ list_name = prop["gui_attributes"]["hlist"]
143
+
144
+ if problems:
145
+ return problems
146
+ return ParsedProperty(
147
+ name=prop_name,
148
+ labels=labels,
149
+ comments=comments,
150
+ supers=supers,
151
+ object=object_value,
152
+ subject=subject,
153
+ gui_element=gui_element,
154
+ node_name=list_name,
155
+ onto_iri=current_onto_prefix.rstrip("#"),
156
+ )
157
+
158
+
159
+ def _parse_classes(
160
+ classes_list: list[dict[str, Any]], current_onto_prefix: str, prefixes: dict[str, str]
161
+ ) -> tuple[list[ParsedClass], list[CreateProblem]]:
162
+ parsed = []
163
+ problems = []
164
+ for cls in classes_list:
165
+ result = _parse_one_class(cls, current_onto_prefix, prefixes)
166
+ if isinstance(result, ParsedClass):
167
+ parsed.append(result)
168
+ else:
169
+ problems.extend(result)
170
+ return parsed, problems
171
+
172
+
173
+ def _parse_one_class(
174
+ cls: dict[str, Any], current_onto_prefix: str, prefixes: dict[str, str]
175
+ ) -> ParsedClass | list[CreateProblem]:
176
+ problems: list[CreateProblem] = []
177
+ supers = [cls["super"]] if isinstance(cls["super"], str) else cls["super"]
178
+ resolved_supers = []
179
+ for s in supers:
180
+ if not (resolved_super := resolve_to_absolute_iri(s, current_onto_prefix, prefixes)):
181
+ problems.append(
182
+ InputProblem(
183
+ f'At class "{cls["name"]}" / Super: "{s}"',
184
+ InputProblemType.PREFIX_COULD_NOT_BE_RESOLVED,
185
+ )
186
+ )
187
+ else:
188
+ resolved_supers.append(resolved_super)
189
+ if problems:
190
+ return problems
191
+ return ParsedClass(
192
+ name=f"{current_onto_prefix}{cls['name']}",
193
+ labels=cls["labels"],
194
+ comments=cls.get("comments"),
195
+ supers=resolved_supers,
196
+ onto_iri=current_onto_prefix.rstrip("#"),
197
+ )
198
+
199
+
200
+ def _parse_cardinalities(
201
+ classes_list: list[dict[str, Any]], current_onto_prefix: str, prefixes: dict[str, str]
202
+ ) -> tuple[list[ParsedClassCardinalities], list[CreateProblem]]:
203
+ parsed = []
204
+ failures = []
205
+ for c in classes_list:
206
+ if c.get("cardinalities"):
207
+ result = _parse_one_class_cardinality(c, current_onto_prefix, prefixes)
208
+ if isinstance(result, ParsedClassCardinalities):
209
+ parsed.append(result)
210
+ else:
211
+ failures.extend(result)
212
+ return parsed, failures
213
+
214
+
215
+ def _parse_one_class_cardinality(
216
+ cls_json: dict[str, Any], current_onto_prefix: str, prefixes: dict[str, str]
217
+ ) -> ParsedClassCardinalities | list[CreateProblem]:
218
+ failures = []
219
+ parsed = []
220
+ for c in cls_json["cardinalities"]:
221
+ result = _parse_one_cardinality(c, current_onto_prefix, prefixes)
222
+ if isinstance(result, ParsedPropertyCardinality):
223
+ parsed.append(result)
224
+ else:
225
+ failures.append(result)
226
+ if failures:
227
+ return failures
228
+ cls_iri = f"{current_onto_prefix}{cls_json['name']}"
229
+ return ParsedClassCardinalities(cls_iri, parsed)
230
+
231
+
232
+ def _parse_one_cardinality(
233
+ card_json: dict[str, str | int], current_onto_prefix: str, prefixes: dict[str, str]
234
+ ) -> ParsedPropertyCardinality | CreateProblem:
235
+ prp_name = cast(str, card_json["propname"])
236
+ if not (resolved := resolve_to_absolute_iri(prp_name, current_onto_prefix, prefixes)):
237
+ return CreateProblem(prp_name, InputProblemType.PREFIX_COULD_NOT_BE_RESOLVED)
238
+ gui = cast(int | None, card_json.get("gui_order"))
239
+ return ParsedPropertyCardinality(
240
+ propname=resolved,
241
+ cardinality=CARDINALITY_MAPPER[cast(str, card_json["cardinality"])],
242
+ gui_order=gui,
243
+ )
@@ -0,0 +1,149 @@
1
+ import os
2
+ from typing import Any
3
+
4
+ from dotenv import find_dotenv
5
+ from dotenv import load_dotenv
6
+
7
+ from dsp_tools.commands.create.models.create_problems import CollectedProblems
8
+ from dsp_tools.commands.create.models.create_problems import CreateProblem
9
+ from dsp_tools.commands.create.models.create_problems import InputProblem
10
+ from dsp_tools.commands.create.models.create_problems import InputProblemType
11
+ from dsp_tools.commands.create.models.parsed_ontology import ParsedOntology
12
+ from dsp_tools.commands.create.models.parsed_project import ParsedGroup
13
+ from dsp_tools.commands.create.models.parsed_project import ParsedGroupDescription
14
+ from dsp_tools.commands.create.models.parsed_project import ParsedList
15
+ from dsp_tools.commands.create.models.parsed_project import ParsedPermissions
16
+ from dsp_tools.commands.create.models.parsed_project import ParsedProject
17
+ from dsp_tools.commands.create.models.parsed_project import ParsedProjectMetadata
18
+ from dsp_tools.commands.create.models.parsed_project import ParsedUser
19
+ from dsp_tools.commands.create.models.parsed_project import ParsedUserMemberShipInfo
20
+ from dsp_tools.commands.create.parsing.parse_lists import parse_list_section
21
+ from dsp_tools.commands.create.parsing.parse_ontology import parse_ontology
22
+ from dsp_tools.commands.create.parsing.parsing_utils import create_prefix_lookup
23
+
24
+ # Load .env file only if it exists in the current working directory
25
+ # This allows CI to set environment variables directly without interference
26
+ dotenv_file = find_dotenv(usecwd=True)
27
+ if dotenv_file:
28
+ load_dotenv(dotenv_path=dotenv_file, override=False)
29
+
30
+
31
+ def parse_project(complete_json: dict[str, Any], api_url: str) -> ParsedProject | list[CollectedProblems]:
32
+ prefix_lookup = create_prefix_lookup(complete_json, api_url)
33
+ project_json = complete_json["project"]
34
+ ontologies, failures = _parse_all_ontologies(project_json, prefix_lookup)
35
+ parsed_lists, list_problems = _parse_lists(project_json)
36
+ if list_problems:
37
+ failures.append(list_problems)
38
+ users, memberships, user_problems = _parse_users(project_json)
39
+ if user_problems:
40
+ failures.append(user_problems)
41
+ if failures:
42
+ return failures
43
+ return ParsedProject(
44
+ prefixes=prefix_lookup,
45
+ project_metadata=_parse_metadata(project_json),
46
+ permissions=_parse_permissions(project_json),
47
+ groups=_parse_groups(project_json),
48
+ users=users,
49
+ user_memberships=memberships,
50
+ lists=parsed_lists,
51
+ ontologies=ontologies,
52
+ )
53
+
54
+
55
+ def _parse_metadata(project_json: dict[str, Any]) -> ParsedProjectMetadata:
56
+ return ParsedProjectMetadata(
57
+ shortcode=project_json["shortcode"],
58
+ shortname=project_json["shortname"],
59
+ longname=project_json["longname"],
60
+ descriptions=project_json["descriptions"],
61
+ keywords=project_json["keywords"],
62
+ enabled_licenses=project_json.get("enabled_licenses", []),
63
+ )
64
+
65
+
66
+ def _parse_permissions(project_json: dict[str, Any]) -> ParsedPermissions:
67
+ return ParsedPermissions(
68
+ default_permissions=project_json["default_permissions"],
69
+ default_permissions_overrule=project_json.get("default_permissions_overrule"),
70
+ )
71
+
72
+
73
+ def _parse_groups(project_json: dict[str, Any]) -> list[ParsedGroup]:
74
+ if not (found := project_json.get("groups")):
75
+ return []
76
+ return [_parse_one_group(x) for x in found]
77
+
78
+
79
+ def _parse_one_group(group_dict: dict[str, Any]) -> ParsedGroup:
80
+ descriptions = [ParsedGroupDescription(lang=lang, text=text) for lang, text in group_dict["descriptions"].items()]
81
+ return ParsedGroup(name=group_dict["name"], descriptions=descriptions)
82
+
83
+
84
+ def _parse_users(
85
+ project_json: dict[str, Any],
86
+ ) -> tuple[list[ParsedUser], list[ParsedUserMemberShipInfo], CollectedProblems | None]:
87
+ if not (found := project_json.get("users")):
88
+ return [], [], None
89
+ users, memberships = [], []
90
+ input_problems: list[CreateProblem] = []
91
+ for u in found:
92
+ result = _parse_one_user(u)
93
+ if isinstance(result, InputProblem):
94
+ input_problems.append(result)
95
+ else:
96
+ usr, mbmr = result
97
+ users.append(usr)
98
+ memberships.append(mbmr)
99
+ if input_problems:
100
+ problem_collection = CollectedProblems(
101
+ "When parsing the user section the following problems occurred:", input_problems
102
+ )
103
+ else:
104
+ problem_collection = None
105
+ return users, memberships, problem_collection
106
+
107
+
108
+ def _parse_one_user(user_dict: dict[str, Any]) -> tuple[ParsedUser, ParsedUserMemberShipInfo] | InputProblem:
109
+ projects = user_dict.get("projects", [])
110
+ is_admin = ":admin" in projects
111
+ groups = [g.removeprefix(":") for g in user_dict.get("groups", [])]
112
+ pw = user_dict["password"]
113
+ if not pw:
114
+ pw = os.getenv("DSP_USER_PASSWORD")
115
+ if not pw:
116
+ return InputProblem(user_dict["username"], InputProblemType.USER_PASSWORD_NOT_SET)
117
+ usr = ParsedUser(
118
+ username=user_dict["username"],
119
+ email=user_dict["email"],
120
+ given_name=user_dict["givenName"],
121
+ family_name=user_dict["familyName"],
122
+ password=pw,
123
+ lang=user_dict.get("lang", "en"),
124
+ )
125
+ memberships = ParsedUserMemberShipInfo(user_dict["username"], is_admin, groups)
126
+ return usr, memberships
127
+
128
+
129
+ def _parse_lists(project_json: dict[str, Any]) -> tuple[list[ParsedList], CollectedProblems | None]:
130
+ if not (found := project_json.get("lists")):
131
+ return [], None
132
+ result = parse_list_section(found)
133
+ if isinstance(result, CollectedProblems):
134
+ return [], result
135
+ return result, None
136
+
137
+
138
+ def _parse_all_ontologies(
139
+ project_json: dict[str, Any], prefix_lookup: dict[str, str]
140
+ ) -> tuple[list[ParsedOntology], list[CollectedProblems]]:
141
+ ontos = []
142
+ failures = []
143
+ for o in project_json["ontologies"]:
144
+ result = parse_ontology(o, prefix_lookup)
145
+ if isinstance(result, ParsedOntology):
146
+ ontos.append(result)
147
+ else:
148
+ failures.append(result)
149
+ return ontos, failures
@@ -0,0 +1,40 @@
1
+ from typing import Any
2
+
3
+ import regex
4
+
5
+ from dsp_tools.utils.data_formats.iri_util import make_dsp_ontology_prefix
6
+ from dsp_tools.utils.data_formats.uri_util import is_uri
7
+ from dsp_tools.utils.rdf_constants import DSP_NAME_TO_PREFIX
8
+ from dsp_tools.utils.rdf_constants import KNORA_API_PREFIX
9
+
10
+
11
+ def resolve_to_absolute_iri(prefixed: str, current_onto: str, prefix_lookup: dict[str, str]) -> str | None:
12
+ if is_uri(prefixed):
13
+ return prefixed
14
+ if prefixed.startswith(":"):
15
+ return f"{current_onto}{prefixed.lstrip(':')}"
16
+ segments = prefixed.split(":", maxsplit=1)
17
+ if len(segments) == 1:
18
+ return f"{KNORA_API_PREFIX}{segments[0]}"
19
+ if not (found := prefix_lookup.get(segments[0])):
20
+ return None
21
+ return f"{found}{segments[1]}"
22
+
23
+
24
+ def create_prefix_lookup(project_json: dict[str, Any], api_url: str) -> dict[str, str]:
25
+ defined_prefixes = project_json.get("prefixes", {})
26
+ defined_prefixes = defined_prefixes | DSP_NAME_TO_PREFIX
27
+ defined_prefixes = _correct_external_prefix(defined_prefixes)
28
+ shortcode = project_json["project"]["shortcode"]
29
+ for onto in project_json["project"]["ontologies"]:
30
+ onto_name = onto["name"]
31
+ defined_prefixes[onto_name] = make_dsp_ontology_prefix(api_url, shortcode, onto_name)
32
+ return defined_prefixes
33
+
34
+
35
+ def _correct_external_prefix(prefixes: dict[str, str]) -> dict[str, str]:
36
+ for prfx, namespace in prefixes.items():
37
+ if regex.search(r"(#|\/)$", namespace):
38
+ continue
39
+ prefixes[prfx] = f"{namespace}/"
40
+ return prefixes