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,324 @@
1
+ """
2
+ This model implements the handling of ontologies. It is to note that ResourceClasses, PropertyClasses
3
+ as well as the assignment of PropertyCLasses to the ResourceClasses (with a given cardinality)
4
+ is handled in "cooperation" with the propertyclass.py (PropertyClass) and resourceclass.py (ResourceClass
5
+ and HasProperty) modules.
6
+
7
+ CREATE:
8
+ * Instantiate a new object of the Ontology class with all required parameters
9
+ * Call the ``create``-method on the instance to create the ontology withing the backend
10
+
11
+ READ:
12
+ * Instantiate a new object with ``iri``(IRI of ontology) given
13
+ * Call the ``read``-method on the instance. Reading the ontology also reads all
14
+ associated PropertyClasses and ResourceClasses as well as the assignments.
15
+ * Access the information that has been provided to the instance
16
+
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import copy
22
+ from typing import Any
23
+ from typing import Optional
24
+ from typing import Union
25
+ from urllib.parse import quote_plus
26
+
27
+ import regex
28
+
29
+ from dsp_tools.clients.connection import Connection
30
+ from dsp_tools.commands.get.legacy_models.context import Context
31
+ from dsp_tools.commands.get.legacy_models.helpers import WithId
32
+ from dsp_tools.commands.get.legacy_models.model import Model
33
+ from dsp_tools.commands.get.legacy_models.project import Project
34
+ from dsp_tools.commands.get.legacy_models.propertyclass import PropertyClass
35
+ from dsp_tools.commands.get.legacy_models.resourceclass import ResourceClass
36
+ from dsp_tools.error.exceptions import BaseError
37
+ from dsp_tools.legacy_models.datetimestamp import DateTimeStamp
38
+
39
+
40
+ class Ontology(Model):
41
+ ROUTE: str = "/v2/ontologies"
42
+ METADATA: str = "/metadata/"
43
+ ALL_LANGUAGES: str = "?allLanguages=true"
44
+
45
+ _iri: str
46
+ _project: str
47
+ _name: str
48
+ _label: str
49
+ _comment: str
50
+ _lastModificationDate: DateTimeStamp
51
+ _resource_classes: list[ResourceClass]
52
+ _property_classes: list[PropertyClass]
53
+ _context: Context
54
+ _skiplist: list[str]
55
+
56
+ def __init__(
57
+ self,
58
+ con: Connection,
59
+ iri: Optional[str] = None,
60
+ project: Optional[Union[str, Project]] = None,
61
+ name: Optional[str] = None,
62
+ label: Optional[str] = None,
63
+ comment: Optional[str] = None,
64
+ lastModificationDate: Optional[Union[str, DateTimeStamp]] = None,
65
+ resource_classes: Optional[list[ResourceClass]] = None,
66
+ property_classes: Optional[list[PropertyClass]] = None,
67
+ context: Context = None,
68
+ ):
69
+ super().__init__(con)
70
+ self._iri = iri
71
+ if isinstance(project, Project):
72
+ self._project = project.iri
73
+ else:
74
+ self._project = project
75
+ self._name = name
76
+ self._label = label
77
+ self._comment = comment
78
+ if lastModificationDate is None:
79
+ self._lastModificationDate = None
80
+ elif isinstance(lastModificationDate, DateTimeStamp):
81
+ self._lastModificationDate = lastModificationDate
82
+ else:
83
+ self._lastModificationDate = DateTimeStamp(lastModificationDate)
84
+ self._resource_classes = resource_classes or []
85
+ self._property_classes = property_classes or []
86
+ self._context = context if context is not None else Context()
87
+ self._skiplist = []
88
+
89
+ @property
90
+ def iri(self) -> str:
91
+ return self._iri
92
+
93
+ @property
94
+ def project(self) -> str:
95
+ return self._project
96
+
97
+ @property
98
+ def name(self) -> str:
99
+ return self._name
100
+
101
+ @property
102
+ def label(self) -> str:
103
+ return self._label
104
+
105
+ @label.setter
106
+ def label(self, value: str) -> None:
107
+ self._label = str(value)
108
+ self._changed.add("label")
109
+
110
+ @property
111
+ def comment(self) -> str:
112
+ return self._comment
113
+
114
+ @comment.setter
115
+ def comment(self, value: str) -> None:
116
+ self._comment = str(value)
117
+ self._changed.add("comment")
118
+
119
+ @property
120
+ def lastModificationDate(self) -> DateTimeStamp:
121
+ return self._lastModificationDate
122
+
123
+ @lastModificationDate.setter
124
+ def lastModificationDate(self, value: Union[str, DateTimeStamp]) -> None:
125
+ self._lastModificationDate = DateTimeStamp(value)
126
+
127
+ @property
128
+ def resource_classes(self) -> list[ResourceClass]:
129
+ return self._resource_classes
130
+
131
+ @resource_classes.setter
132
+ def resource_classes(self, value: list[ResourceClass]) -> None:
133
+ self._resource_classes = value
134
+
135
+ @property
136
+ def property_classes(self) -> list[PropertyClass]:
137
+ return self._property_classes
138
+
139
+ @property_classes.setter
140
+ def property_classes(self, value: list[PropertyClass]) -> None:
141
+ self._property_classes = value
142
+
143
+ @property
144
+ def context(self) -> Context:
145
+ return self._context
146
+
147
+ @classmethod
148
+ def fromJsonObj(cls, con: Connection, json_obj: Any) -> Ontology:
149
+ #
150
+ # First let's get the ID (IRI) of the ontology
151
+ #
152
+ iri = json_obj.get("@id")
153
+ if iri is None:
154
+ raise BaseError("Ontology iri is missing")
155
+
156
+ #
157
+ # evaluate the JSON-LD context to get the proper prefixes
158
+ #
159
+ context = Context(json_obj.get("@context"))
160
+ onto_name = iri.split("/")[-2]
161
+ context.add_context(onto_name, iri + "#")
162
+ rdfs = context.prefix_from_iri("http://www.w3.org/2000/01/rdf-schema#")
163
+ knora_api = context.prefix_from_iri("http://api.knora.org/ontology/knora-api/v2#")
164
+ this_onto = context.prefix_from_iri(iri + "#")
165
+
166
+ label = json_obj.get(rdfs + ":label")
167
+ if label is None:
168
+ raise BaseError("Ontology label is missing")
169
+ comment = json_obj.get(rdfs + ":comment")
170
+ if json_obj.get(knora_api + ":attachedToProject") is None:
171
+ raise BaseError("Ontology not attached to a project")
172
+ if json_obj[knora_api + ":attachedToProject"].get("@id") is None:
173
+ raise BaseError("Ontology not attached to a project")
174
+ project = json_obj[knora_api + ":attachedToProject"]["@id"]
175
+ tmp = json_obj.get(knora_api + ":lastModificationDate")
176
+ if tmp is not None:
177
+ last_modification_date = DateTimeStamp(json_obj.get(knora_api + ":lastModificationDate"))
178
+ else:
179
+ last_modification_date = None
180
+ resource_classes = None
181
+ property_classes = None
182
+ if json_obj.get("@graph") is not None:
183
+ resclasses_obj = list(
184
+ filter(lambda a: a.get(knora_api + ":isResourceClass") is not None, json_obj.get("@graph"))
185
+ )
186
+ resource_classes = list(
187
+ map(lambda a: ResourceClass.fromJsonObj(con=con, context=context, json_obj=a), resclasses_obj)
188
+ )
189
+
190
+ properties_obj = list(
191
+ filter(lambda a: a.get(knora_api + ":isResourceProperty") is not None, json_obj.get("@graph"))
192
+ )
193
+ property_classes = [
194
+ PropertyClass.fromJsonObj(con=con, context=context, json_obj=a)
195
+ for a in properties_obj
196
+ if WithId(a.get(knora_api + ":objectType")).to_string() != "knora-api:LinkValue"
197
+ ]
198
+ return cls(
199
+ con=con,
200
+ iri=iri,
201
+ label=label,
202
+ project=project,
203
+ name=this_onto,
204
+ comment=comment,
205
+ lastModificationDate=last_modification_date,
206
+ resource_classes=resource_classes,
207
+ property_classes=property_classes,
208
+ context=context,
209
+ )
210
+
211
+ @classmethod
212
+ def __oneOntologiesFromJsonObj(cls, con: Connection, json_obj: Any, context: Context) -> Ontology:
213
+ rdfs = context.prefix_from_iri("http://www.w3.org/2000/01/rdf-schema#")
214
+ owl = context.prefix_from_iri("http://www.w3.org/2002/07/owl#")
215
+ knora_api = context.prefix_from_iri("http://api.knora.org/ontology/knora-api/v2#")
216
+ if json_obj.get("@type") != owl + ":Ontology":
217
+ return None
218
+ iri = json_obj.get("@id")
219
+ if iri is None:
220
+ raise BaseError("Ontology iri is missing")
221
+ if json_obj.get(knora_api + ":attachedToProject") is None:
222
+ raise BaseError("Ontology not attached to a project (1)")
223
+ if json_obj[knora_api + ":attachedToProject"].get("@id") is None:
224
+ raise BaseError("Ontology not attached to a project (2)")
225
+ project = json_obj[knora_api + ":attachedToProject"]["@id"]
226
+ tmp = json_obj.get(knora_api + ":lastModificationDate")
227
+ if tmp is not None:
228
+ last_modification_date = DateTimeStamp(json_obj.get(knora_api + ":lastModificationDate"))
229
+ else:
230
+ last_modification_date = None
231
+ label = json_obj.get(rdfs + ":label")
232
+ if label is None:
233
+ raise BaseError("Ontology label is missing")
234
+ comment = json_obj.get(rdfs + ":comment")
235
+ this_onto = iri.split("/")[-2]
236
+ context2 = copy.deepcopy(context)
237
+ context2.add_context(this_onto, iri)
238
+ return cls(
239
+ con=con,
240
+ iri=iri,
241
+ label=label,
242
+ project=project,
243
+ name=this_onto,
244
+ comment=comment,
245
+ lastModificationDate=last_modification_date,
246
+ context=context2,
247
+ )
248
+
249
+ @classmethod
250
+ def allOntologiesFromJsonObj(cls, con: Connection, json_obj: Any) -> list[Ontology]:
251
+ context = Context(json_obj.get("@context"))
252
+ ontos: list[Ontology] = []
253
+ if json_obj.get("@graph") is not None:
254
+ for o in json_obj["@graph"]:
255
+ ontos.append(Ontology.__oneOntologiesFromJsonObj(con, o, context))
256
+ else:
257
+ onto = Ontology.__oneOntologiesFromJsonObj(con, json_obj, context)
258
+ if onto is not None:
259
+ ontos.append(onto)
260
+ return ontos
261
+
262
+ def create(self) -> Ontology:
263
+ jsonobj = self._toJsonObj_create()
264
+ result = self._con.post(Ontology.ROUTE, jsonobj)
265
+ return Ontology.fromJsonObj(self._con, result)
266
+
267
+ def _toJsonObj_create(self):
268
+ rdfs = self._context.prefix_from_iri("http://www.w3.org/2000/01/rdf-schema#")
269
+ knora_api = self._context.prefix_from_iri("http://api.knora.org/ontology/knora-api/v2#")
270
+ if self._name is None:
271
+ raise BaseError("There must be a valid name given!")
272
+ if self._label is None:
273
+ raise BaseError("There must be a valid label given!")
274
+ if self._project is None:
275
+ raise BaseError("There must be a valid project given!")
276
+ tmp = {
277
+ knora_api + ":ontologyName": self._name,
278
+ knora_api + ":attachedToProject": {"@id": self._project},
279
+ rdfs + ":label": self._label,
280
+ "@context": self._context.toJsonObj(),
281
+ }
282
+ if self._comment is not None:
283
+ tmp[rdfs + ":comment"] = self._comment
284
+ return tmp
285
+
286
+ def read(self) -> Ontology:
287
+ result = self._con.get(Ontology.ROUTE + "/allentities/" + quote_plus(self._iri) + Ontology.ALL_LANGUAGES)
288
+ return Ontology.fromJsonObj(self._con, result)
289
+
290
+ @staticmethod
291
+ def getProjectOntologies(con: Connection, project_id: str) -> list[Ontology]:
292
+ if project_id is None:
293
+ raise BaseError("Project ID must be defined!")
294
+ result = con.get(Ontology.ROUTE + Ontology.METADATA + quote_plus(project_id) + Ontology.ALL_LANGUAGES)
295
+ return Ontology.allOntologiesFromJsonObj(con, result)
296
+
297
+ @staticmethod
298
+ def getOntologyFromServer(con: Connection, shortcode: str, name: str) -> Ontology:
299
+ if regex.search(r"[0-9A-F]{4}", shortcode):
300
+ result = con.get("/ontology/" + shortcode + "/" + name + "/v2" + Ontology.ALL_LANGUAGES)
301
+ else:
302
+ result = con.get("/ontology/" + name + "/v2" + Ontology.ALL_LANGUAGES)
303
+ return Ontology.fromJsonObj(con, result)
304
+
305
+ def createDefinitionFileObj(self) -> dict[str, Any]:
306
+ ontology = {
307
+ "name": self.name,
308
+ "label": self.label,
309
+ "comment": self.comment,
310
+ "properties": [],
311
+ "resources": [],
312
+ }
313
+ if not self.comment:
314
+ ontology.pop("comment")
315
+ for prop in self.property_classes:
316
+ if "knora-api:hasLinkToValue" in prop.superproperties:
317
+ self._skiplist.append(self.name + ":" + prop.name)
318
+ continue
319
+ ontology["properties"].append(prop.createDefinitionFileObj(self.context, self.name))
320
+
321
+ for res in self.resource_classes:
322
+ ontology["resources"].append(res.createDefinitionFileObj(self.context, self.name, self._skiplist))
323
+
324
+ return ontology
@@ -0,0 +1,366 @@
1
+ """
2
+ This module implements the handling (CRUD) of DSP projects.
3
+
4
+ CREATE:
5
+ * Instantiate a new object of the class Project with all required parameters
6
+ * Call the ``create``-method on the instance
7
+
8
+ READ:
9
+ * Instantiate a new object with ``iri`` given
10
+ * Call the ``read``-method on the instance
11
+ * Access the information that has been provided to the instance
12
+
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import Any
18
+ from typing import Optional
19
+ from typing import Union
20
+ from urllib.parse import quote_plus
21
+
22
+ from dsp_tools.clients.connection import Connection
23
+ from dsp_tools.commands.get.legacy_models.model import Model
24
+ from dsp_tools.error.exceptions import BaseError
25
+ from dsp_tools.legacy_models.langstring import LangString
26
+
27
+
28
+ class Project(Model):
29
+ """
30
+ This class represents a project in DSP.
31
+
32
+ Attributes
33
+ ----------
34
+
35
+ con : Connection
36
+ A Connection instance to a DSP server
37
+
38
+ iri : str
39
+ IRI of the project [readonly, cannot be modified after creation of instance]
40
+
41
+ shortcode : str
42
+ DSP project shortcode [readonly, cannot be modified after creation of instance]
43
+
44
+ shortname : str
45
+ DSP project shortname [read/write]
46
+
47
+ longname : str
48
+ DSP project longname [read/write]
49
+
50
+ description : LangString
51
+ DSP project description in a given language (Languages.EN, Languages.DE, Languages.FR, Languages.IT).
52
+
53
+ keywords : set[str]
54
+ Set of keywords describing the project.
55
+
56
+ ontologies : set[str]
57
+ Set if IRI's of the ontologies attached to the project [readonly]
58
+
59
+ selfjoin : bool
60
+ Boolean if the project allows selfjoin
61
+
62
+
63
+ Methods
64
+ -------
65
+
66
+ create : DSP project information object
67
+ Creates a new project and returns the information from the project as it is in DSP
68
+
69
+ read : DSP project information object
70
+ Read project data from an existing project
71
+
72
+ getAllprojects [static]: List of all projects
73
+ Returns a list of all projects available
74
+
75
+ print : None
76
+ Prints the project information to stdout
77
+
78
+ """
79
+
80
+ ROUTE: str = "/admin/projects"
81
+ IRI: str = ROUTE + "/iri/"
82
+
83
+ _iri: str
84
+ _shortcode: str
85
+ _shortname: str
86
+ _longname: str
87
+ _description: LangString
88
+ _keywords: set[str]
89
+ _ontologies: set[str]
90
+ _enabled_licenses: set[str]
91
+ _selfjoin: bool
92
+ _status: bool
93
+ _logo: Optional[str]
94
+
95
+ def __init__(
96
+ self,
97
+ con: Connection,
98
+ iri: Optional[str] = None,
99
+ shortcode: Optional[str] = None,
100
+ shortname: Optional[str] = None,
101
+ longname: Optional[str] = None,
102
+ description: LangString = None,
103
+ keywords: Optional[set[str]] = None,
104
+ ontologies: Optional[set[str]] = None,
105
+ enabled_licenses: Optional[set[str]] = None,
106
+ selfjoin: Optional[bool] = None,
107
+ status: Optional[bool] = None,
108
+ logo: Optional[str] = None,
109
+ ):
110
+ """
111
+ Constructor for Project
112
+
113
+ :param con: Connection instance
114
+ :param iri: IRI of the project [required for CREATE, READ]
115
+ :param shortcode: Shortcode of the project. Four-digit hexadecimal number. [required for CREATE]
116
+ :param shortname: Shortname of the project [required for CREATE]
117
+ :param longname: Longname of the project [required for CREATE]
118
+ :param description: LangString instance containing the description [required for CREATE]
119
+ :param keywords: Set of keywords [required for CREATE]
120
+ :param ontologies: Set of ontologies that belong to this project [optional]
121
+ :param enabled_licenses: Set of enabled licenses [optional]
122
+ :param selfjoin: Allow selfjoin [required for CREATE]
123
+ :param status: Status of project (active if True) [required for CREATE]
124
+ :param logo: Path to logo image file [optional] NOT YET USED
125
+ """
126
+ super().__init__(con)
127
+ self._iri = iri
128
+ self._shortcode = shortcode
129
+ self._shortname = shortname
130
+ self._longname = longname
131
+ self._description = LangString(description)
132
+ self._keywords = keywords
133
+ if not isinstance(ontologies, set) and ontologies is not None:
134
+ raise BaseError("Ontologies must be a set of strings or None!")
135
+ self._ontologies = ontologies
136
+ self._enabled_licenses = enabled_licenses or set()
137
+ self._selfjoin = selfjoin
138
+ self._status = status
139
+ self._logo = logo
140
+
141
+ def __str__(self) -> str:
142
+ tmpstr = self._iri + "\n " + self._shortcode + "\n " + self._shortname
143
+ return tmpstr
144
+
145
+ #
146
+ # Here follows a list of getters/setters
147
+ #
148
+ @property
149
+ def iri(self) -> Optional[str]:
150
+ return self._iri
151
+
152
+ @property
153
+ def shortcode(self) -> Optional[str]:
154
+ return self._shortcode
155
+
156
+ @property
157
+ def shortname(self) -> Optional[str]:
158
+ return self._shortname
159
+
160
+ @shortname.setter
161
+ def shortname(self, value: str) -> None:
162
+ if self._shortname != str(value):
163
+ self._shortname = str(value)
164
+ self._changed.add("shortname")
165
+
166
+ @property
167
+ def longname(self) -> Optional[str]:
168
+ return self._longname
169
+
170
+ @longname.setter
171
+ def longname(self, value: str) -> None:
172
+ if self._longname != str(value):
173
+ self._longname = str(value)
174
+ self._changed.add("longname")
175
+
176
+ @property
177
+ def description(self) -> LangString:
178
+ return self._description or LangString({})
179
+
180
+ @description.setter
181
+ def description(self, value: Optional[LangString]) -> None:
182
+ self._description = LangString(value)
183
+ self._changed.add("description")
184
+
185
+ @property
186
+ def keywords(self) -> set[str]:
187
+ return self._keywords
188
+
189
+ @keywords.setter
190
+ def keywords(self, value: Union[list[str], set[str]]) -> None:
191
+ if isinstance(value, set):
192
+ self._keywords = value
193
+ self._changed.add("keywords")
194
+ elif isinstance(value, list):
195
+ self._keywords = set(value)
196
+ self._changed.add("keywords")
197
+ else:
198
+ raise BaseError("Must be a set of strings!")
199
+
200
+ @property
201
+ def ontologies(self) -> set[str]:
202
+ return self._ontologies
203
+
204
+ @property
205
+ def selfjoin(self) -> Optional[bool]:
206
+ return self._selfjoin
207
+
208
+ @selfjoin.setter
209
+ def selfjoin(self, value: bool) -> None:
210
+ if self._selfjoin != value:
211
+ self._changed.add("selfjoin")
212
+ self._selfjoin = value
213
+
214
+ @property
215
+ def status(self) -> bool:
216
+ return self._status
217
+
218
+ @status.setter
219
+ def status(self, value: bool) -> None:
220
+ if self._status != value:
221
+ self._status = value
222
+ self._changed.add("status")
223
+
224
+ @property
225
+ def logo(self) -> str:
226
+ return self._logo
227
+
228
+ @logo.setter
229
+ def logo(self, value: str) -> None:
230
+ if self._logo != value:
231
+ self._logo = value
232
+ self._changed.add("logo")
233
+
234
+ @classmethod
235
+ def fromJsonObj(cls, con: Connection, json_obj: Any) -> Project:
236
+ """
237
+ Internal method! Should not be used directly!
238
+
239
+ This method is used to create a Project instance from the JSON data returned by DSP
240
+
241
+ :param con: Connection instance
242
+ :param json_obj: JSON data returned by DSP as python3 object
243
+ :return: Project instance
244
+ """
245
+ iri = json_obj.get("id")
246
+ if iri is None:
247
+ raise BaseError("Project iri is missing")
248
+ shortcode = json_obj.get("shortcode")
249
+ if shortcode is None:
250
+ raise BaseError("Shortcode is missing")
251
+ shortname = json_obj.get("shortname")
252
+ if shortname is None:
253
+ raise BaseError("Shortname is missing")
254
+ longname = json_obj.get("longname")
255
+ if longname is None:
256
+ raise BaseError("Longname is missing")
257
+ description = LangString.fromJsonObj(json_obj.get("description"))
258
+ keywords = set(json_obj.get("keywords"))
259
+ if keywords is None:
260
+ raise BaseError("Keywords are missing")
261
+ ontologies = set(json_obj.get("ontologies"))
262
+ if ontologies is None:
263
+ raise BaseError("ontologies are missing")
264
+ enabled_licenses = json_obj.get("enabledLicenses", set())
265
+ selfjoin = json_obj.get("selfjoin")
266
+ if selfjoin is None:
267
+ raise BaseError("Selfjoin is missing")
268
+ status = json_obj.get("status")
269
+ if status is None:
270
+ raise BaseError("Status is missing")
271
+ logo = json_obj.get("logo")
272
+ return cls(
273
+ con=con,
274
+ iri=iri,
275
+ shortcode=shortcode,
276
+ shortname=shortname,
277
+ longname=longname,
278
+ description=description,
279
+ keywords=keywords,
280
+ ontologies=ontologies,
281
+ enabled_licenses=enabled_licenses,
282
+ selfjoin=selfjoin,
283
+ status=status,
284
+ logo=logo,
285
+ )
286
+
287
+ def createDefinitionFileObj(self) -> dict[str, Any]:
288
+ return {
289
+ "shortcode": self._shortcode,
290
+ "shortname": self._shortname,
291
+ "longname": self._longname,
292
+ "descriptions": self._description.createDefinitionFileObj(),
293
+ "keywords": list(self._keywords),
294
+ "enabled_licenses": list(self._enabled_licenses),
295
+ }
296
+
297
+ def create(self) -> Project:
298
+ """
299
+ Create a new project in DSP
300
+
301
+ :return: JSON-object from DSP
302
+ """
303
+ jsonobj = self._toJsonObj_create()
304
+ result = self._con.post(Project.ROUTE, jsonobj)
305
+ return Project.fromJsonObj(self._con, result["project"])
306
+
307
+ def _toJsonObj_create(self) -> dict[str, str]:
308
+ tmp = {}
309
+ if self._shortcode is None:
310
+ raise BaseError("There must be a valid project shortcode!")
311
+ tmp["shortcode"] = self._shortcode
312
+ if self._shortname is None:
313
+ raise BaseError("There must be a valid project shortname!")
314
+ tmp["shortname"] = self._shortname
315
+ if self._longname is None:
316
+ raise BaseError("There must be a valid project longname!")
317
+ tmp["longname"] = self._longname
318
+ if self._description.isEmpty():
319
+ raise BaseError("There must be a valid project description!")
320
+ tmp["description"] = self._description.toJsonObj()
321
+ if self._keywords is not None and len(self._keywords) > 0:
322
+ tmp["keywords"] = self._keywords
323
+ if self._enabled_licenses:
324
+ tmp["enabledLicenses"] = list(self._enabled_licenses)
325
+ if self._selfjoin is None:
326
+ raise BaseError("selfjoin must be defined (True or False!")
327
+ tmp["selfjoin"] = self._selfjoin
328
+ if self._status is None:
329
+ raise BaseError("status must be defined (True or False!")
330
+ tmp["status"] = self._status
331
+ return tmp
332
+
333
+ def read(self) -> Project:
334
+ """
335
+ Read a project from DSP
336
+
337
+ :return: JSON-object from DSP
338
+ """
339
+ result = None
340
+ if self._iri is not None:
341
+ result = self._con.get(Project.IRI + quote_plus(self._iri))
342
+ elif self._shortcode is not None:
343
+ result = self._con.get(Project.ROUTE + "/shortcode/" + quote_plus(self._shortcode))
344
+ elif self._shortname is not None:
345
+ result = self._con.get(Project.ROUTE + "/shortname/" + quote_plus(self._shortname))
346
+ if result is not None:
347
+ return Project.fromJsonObj(self._con, result["project"])
348
+ else:
349
+ raise BaseError(
350
+ f"ERROR: Could not read project '{self.shortname}' ({self.shortcode}) with IRI {self._iri} "
351
+ f"from DSP server."
352
+ )
353
+
354
+ @staticmethod
355
+ def getAllProjects(con: Connection) -> list[Project]:
356
+ """
357
+ Get all existing projects in DSP
358
+
359
+ :param con: Connection instance
360
+ :return:
361
+ """
362
+ try:
363
+ result = con.get(Project.ROUTE)
364
+ return [Project.fromJsonObj(con, a) for a in result["projects"]]
365
+ except BaseError:
366
+ return []