edu-rdm-integration 3.9.1__py3-none-any.whl → 3.10.0__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 (279) hide show
  1. edu_rdm_integration/__init__.py +0 -1
  2. edu_rdm_integration/adapters/apps.py +15 -2
  3. edu_rdm_integration/adapters/caches.py +25 -12
  4. edu_rdm_integration/adapters/errors.py +13 -2
  5. edu_rdm_integration/adapters/functions.py +53 -14
  6. edu_rdm_integration/adapters/helpers.py +34 -8
  7. edu_rdm_integration/adapters/managers.py +41 -5
  8. edu_rdm_integration/adapters/presenters.py +26 -2
  9. edu_rdm_integration/adapters/receivers.py +16 -2
  10. edu_rdm_integration/adapters/results.py +50 -4
  11. edu_rdm_integration/adapters/runners.py +79 -20
  12. edu_rdm_integration/adapters/strategies.py +56 -54
  13. edu_rdm_integration/adapters/validators.py +43 -4
  14. edu_rdm_integration/apps.py +3 -23
  15. edu_rdm_integration/collect_and_export_data/__init__.py +1 -1
  16. edu_rdm_integration/collect_and_export_data/apps.py +1 -0
  17. edu_rdm_integration/collect_and_export_data/migrations/0001_initial.py +107 -17
  18. edu_rdm_integration/collect_and_export_data/migrations/0002_auto_20250204_1413.py +4 -2
  19. edu_rdm_integration/{consts.py → core/consts.py} +0 -11
  20. edu_rdm_integration/{enums.py → core/enums.py} +7 -54
  21. edu_rdm_integration/core/helpers.py +331 -0
  22. edu_rdm_integration/core/operations.py +71 -0
  23. edu_rdm_integration/core/redis_cache.py +20 -0
  24. edu_rdm_integration/{collect_and_export_data → core/registry}/actions.py +6 -12
  25. edu_rdm_integration/core/registry/apps.py +11 -0
  26. edu_rdm_integration/{collect_and_export_data → core/registry}/ui.py +1 -1
  27. edu_rdm_integration/{storages.py → core/storages.py} +8 -17
  28. edu_rdm_integration/{utils.py → core/utils.py} +29 -91
  29. edu_rdm_integration/migrations/0001_initial.py +294 -44
  30. edu_rdm_integration/migrations/0002_init_data_uploadstatus.py +1 -3
  31. edu_rdm_integration/migrations/0003_create_index_file_upload_status.py +0 -1
  32. edu_rdm_integration/migrations/0004_uploaderclientlog.py +1 -2
  33. edu_rdm_integration/migrations/0005_auto_20231204_1224.py +16 -4
  34. edu_rdm_integration/migrations/0006_request_status_data.py +60 -58
  35. edu_rdm_integration/migrations/0007_delete_upload_status.py +0 -1
  36. edu_rdm_integration/migrations/0009_auto_20240522_1619.py +1 -5
  37. edu_rdm_integration/migrations/0010_transferredentity_export_enabled.py +0 -1
  38. edu_rdm_integration/migrations/0011_exportingdatasubstageentity.py +16 -3
  39. edu_rdm_integration/migrations/0012_exportingdatasubstageattachment_attachment_size.py +0 -1
  40. edu_rdm_integration/migrations/0013_set_attachment_size.py +8 -12
  41. edu_rdm_integration/migrations/0014_uploaddatacommand.py +33 -6
  42. edu_rdm_integration/migrations/0015_set_exporting_sub_stage_status.py +1 -5
  43. edu_rdm_integration/migrations/0016_transferredentity_queue_level.py +2 -2
  44. edu_rdm_integration/migrations/0017_delete_uploaddatacommand.py +3 -2
  45. edu_rdm_integration/migrations/__init__.py +1 -0
  46. edu_rdm_integration/{registry → pipelines/transfer}/actions.py +13 -26
  47. edu_rdm_integration/pipelines/transfer/app_meta.py +18 -0
  48. edu_rdm_integration/pipelines/transfer/apps.py +19 -0
  49. edu_rdm_integration/pipelines/transfer/enums.py +34 -0
  50. edu_rdm_integration/pipelines/transfer/migrations/0001_initial.py +57 -0
  51. edu_rdm_integration/{base.py → pipelines/transfer/mixins.py} +29 -53
  52. edu_rdm_integration/pipelines/transfer/models.py +48 -0
  53. edu_rdm_integration/{tasks.py → pipelines/transfer/tasks.py} +51 -150
  54. edu_rdm_integration/{registry → pipelines/transfer}/ui.py +4 -10
  55. edu_rdm_integration/rdm_entities/apps.py +11 -0
  56. edu_rdm_integration/{entities.py → rdm_entities/entities.py} +67 -57
  57. edu_rdm_integration/rdm_entities/migrations/0001_initial.py +44 -0
  58. edu_rdm_integration/{enum_register → rdm_entities}/mixins.py +8 -59
  59. edu_rdm_integration/rdm_entities/models.py +63 -0
  60. edu_rdm_integration/rdm_entities/utils.py +33 -0
  61. edu_rdm_integration/rdm_models/apps.py +16 -0
  62. edu_rdm_integration/rdm_models/migrations/0001_initial.py +40 -0
  63. edu_rdm_integration/rdm_models/mixins.py +67 -0
  64. edu_rdm_integration/rdm_models/models.py +73 -0
  65. edu_rdm_integration/rdm_models/utils.py +23 -0
  66. edu_rdm_integration/stages/collect_data/apps.py +11 -0
  67. edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/functions.py-tpl +2 -2
  68. edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/managers.py-tpl +1 -1
  69. edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/runners.py-tpl +1 -1
  70. edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/tests.py-tpl +2 -1
  71. edu_rdm_integration/{collect_data → stages/collect_data/functions}/base/caches.py +2 -2
  72. edu_rdm_integration/{collect_data → stages/collect_data/functions}/base/functions.py +15 -18
  73. edu_rdm_integration/stages/collect_data/functions/base/helpers.py +20 -0
  74. edu_rdm_integration/{collect_data → stages/collect_data/functions}/base/managers.py +20 -27
  75. edu_rdm_integration/{collect_data → stages/collect_data/functions}/base/mixins.py +38 -55
  76. edu_rdm_integration/{collect_data → stages/collect_data/functions}/base/runners.py +2 -5
  77. edu_rdm_integration/stages/collect_data/functions/calculated/base/__init__.py +0 -0
  78. edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/caches.py +3 -7
  79. edu_rdm_integration/stages/collect_data/functions/calculated/base/errors.py +7 -0
  80. edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/functions.py +8 -16
  81. edu_rdm_integration/stages/collect_data/functions/calculated/base/helpers.py +24 -0
  82. edu_rdm_integration/stages/collect_data/functions/calculated/base/managers.py +19 -0
  83. edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/presenters.py +1 -3
  84. edu_rdm_integration/stages/collect_data/functions/calculated/base/results.py +12 -0
  85. edu_rdm_integration/stages/collect_data/functions/calculated/base/runners.py +28 -0
  86. edu_rdm_integration/stages/collect_data/functions/calculated/base/validators.py +20 -0
  87. edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/strategies.py +32 -70
  88. edu_rdm_integration/stages/collect_data/functions/non_calculated/__init__.py +0 -0
  89. edu_rdm_integration/stages/collect_data/functions/non_calculated/base/__init__.py +0 -0
  90. edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/caches.py +13 -22
  91. edu_rdm_integration/stages/collect_data/functions/non_calculated/base/errors.py +7 -0
  92. edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/functions.py +8 -16
  93. edu_rdm_integration/stages/collect_data/functions/non_calculated/base/helpers.py +24 -0
  94. edu_rdm_integration/stages/collect_data/functions/non_calculated/base/managers.py +19 -0
  95. edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/presenters.py +1 -3
  96. edu_rdm_integration/stages/collect_data/functions/non_calculated/base/results.py +12 -0
  97. edu_rdm_integration/stages/collect_data/functions/non_calculated/base/runners.py +28 -0
  98. edu_rdm_integration/stages/collect_data/functions/non_calculated/base/validators.py +20 -0
  99. edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/strategies.py +32 -70
  100. edu_rdm_integration/{collect_data → stages/collect_data}/generators.py +9 -14
  101. edu_rdm_integration/stages/collect_data/helpers.py +154 -0
  102. edu_rdm_integration/stages/collect_data/management/__init__.py +0 -0
  103. edu_rdm_integration/stages/collect_data/management/base.py +100 -0
  104. edu_rdm_integration/stages/collect_data/management/commands/__init__.py +0 -0
  105. edu_rdm_integration/{management → stages/collect_data/management}/commands/collect_latest_models_data.py +5 -7
  106. edu_rdm_integration/{management → stages/collect_data/management}/commands/collect_models_data.py +5 -7
  107. edu_rdm_integration/stages/collect_data/migrations/0001_initial.py +187 -0
  108. edu_rdm_integration/stages/collect_data/migrations/0002_edurdmcollectdatacommandprogress.py +105 -0
  109. edu_rdm_integration/stages/collect_data/migrations/__init__.py +0 -0
  110. edu_rdm_integration/stages/collect_data/mixins.py +56 -0
  111. edu_rdm_integration/stages/collect_data/models.py +318 -0
  112. edu_rdm_integration/{collect_data/collect.py → stages/collect_data/operations.py} +30 -43
  113. edu_rdm_integration/stages/collect_data/registry/__init__.py +0 -0
  114. edu_rdm_integration/{collect_data → stages/collect_data/registry}/actions.py +17 -20
  115. edu_rdm_integration/stages/collect_data/registry/apps.py +11 -0
  116. edu_rdm_integration/{collect_data → stages/collect_data/registry}/ui.py +8 -15
  117. edu_rdm_integration/{collect_data → stages/collect_data}/tests.py +2 -2
  118. edu_rdm_integration/stages/export_data/__init__.py +0 -0
  119. edu_rdm_integration/stages/export_data/apps.py +11 -0
  120. edu_rdm_integration/stages/export_data/function_templates/__init__.py +0 -0
  121. edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/functions.py-tpl +2 -2
  122. edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/managers.py-tpl +2 -2
  123. edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/runners.py-tpl +2 -2
  124. edu_rdm_integration/stages/export_data/functions/__init__.py +0 -0
  125. edu_rdm_integration/stages/export_data/functions/base/__init__.py +0 -0
  126. edu_rdm_integration/{export_data → stages/export_data/functions}/base/caches.py +3 -8
  127. edu_rdm_integration/stages/export_data/functions/base/errors.py +7 -0
  128. edu_rdm_integration/{export_data → stages/export_data/functions}/base/functions.py +28 -59
  129. edu_rdm_integration/{export_data → stages/export_data/functions}/base/helpers.py +7 -17
  130. edu_rdm_integration/{export_data → stages/export_data/functions}/base/managers.py +19 -28
  131. edu_rdm_integration/stages/export_data/functions/base/presenters.py +11 -0
  132. edu_rdm_integration/{export_data → stages/export_data/functions}/base/requests.py +13 -40
  133. edu_rdm_integration/stages/export_data/functions/base/results.py +12 -0
  134. edu_rdm_integration/{export_data → stages/export_data/functions}/base/runners.py +9 -21
  135. edu_rdm_integration/stages/export_data/functions/base/validators.py +20 -0
  136. edu_rdm_integration/{export_data → stages/export_data}/generators.py +7 -6
  137. edu_rdm_integration/stages/export_data/helpers.py +203 -0
  138. edu_rdm_integration/stages/export_data/management/__init__.py +0 -0
  139. edu_rdm_integration/stages/export_data/management/base.py +101 -0
  140. edu_rdm_integration/stages/export_data/management/commands/__init__.py +0 -0
  141. edu_rdm_integration/{management → stages/export_data/management}/commands/export_entities_data.py +5 -7
  142. edu_rdm_integration/{management → stages/export_data/management}/commands/export_latest_entities_data.py +5 -7
  143. edu_rdm_integration/stages/export_data/migrations/0001_initial.py +324 -0
  144. edu_rdm_integration/stages/export_data/migrations/__init__.py +0 -0
  145. edu_rdm_integration/stages/export_data/mixins.py +50 -0
  146. edu_rdm_integration/stages/export_data/models.py +362 -0
  147. edu_rdm_integration/{export_data/export.py → stages/export_data/operations.py} +30 -192
  148. edu_rdm_integration/stages/export_data/registry/__init__.py +0 -0
  149. edu_rdm_integration/{export_data → stages/export_data/registry}/actions.py +18 -18
  150. edu_rdm_integration/stages/export_data/registry/apps.py +11 -0
  151. edu_rdm_integration/{export_data → stages/export_data/registry}/ui.py +5 -7
  152. edu_rdm_integration/{export_data → stages/export_data}/strategies.py +30 -68
  153. edu_rdm_integration/stages/service/__init__.py +0 -0
  154. edu_rdm_integration/stages/service/apps.py +19 -0
  155. edu_rdm_integration/stages/service/tasks.py +63 -0
  156. edu_rdm_integration/stages/upload_data/__init__.py +0 -0
  157. edu_rdm_integration/stages/upload_data/apps.py +19 -0
  158. edu_rdm_integration/stages/upload_data/consts.py +10 -0
  159. edu_rdm_integration/{export_data → stages/upload_data}/dataclasses.py +1 -0
  160. edu_rdm_integration/stages/upload_data/enums.py +17 -0
  161. edu_rdm_integration/{export_data/export_manager.py → stages/upload_data/export_managers.py} +73 -68
  162. edu_rdm_integration/stages/upload_data/helpers.py +164 -0
  163. edu_rdm_integration/stages/upload_data/management/__init__.py +0 -0
  164. edu_rdm_integration/stages/upload_data/management/base.py +134 -0
  165. edu_rdm_integration/stages/upload_data/management/commands/__init__.py +0 -0
  166. edu_rdm_integration/{management → stages/upload_data/management}/commands/async_fix_attachment_size.py +32 -54
  167. edu_rdm_integration/{management → stages/upload_data/management}/commands/check_upload_status.py +7 -6
  168. edu_rdm_integration/{management → stages/upload_data/management}/commands/datamart_status.py +3 -3
  169. edu_rdm_integration/{management → stages/upload_data/management}/commands/datamart_upload.py +4 -4
  170. edu_rdm_integration/stages/upload_data/migrations/0001_initial.py +161 -0
  171. edu_rdm_integration/stages/upload_data/migrations/__init__.py +0 -0
  172. edu_rdm_integration/stages/upload_data/models.py +175 -0
  173. edu_rdm_integration/stages/upload_data/operations.py +156 -0
  174. edu_rdm_integration/{export_data/queue.py → stages/upload_data/queues.py} +10 -8
  175. edu_rdm_integration/stages/upload_data/tasks.py +103 -0
  176. edu_rdm_integration/stages/upload_data/uploader_log/__init__.py +0 -0
  177. edu_rdm_integration/{uploader_log → stages/upload_data/uploader_log}/actions.py +14 -16
  178. edu_rdm_integration/stages/upload_data/uploader_log/apps.py +11 -0
  179. edu_rdm_integration/{uploader_log → stages/upload_data/uploader_log}/managers.py +15 -30
  180. edu_rdm_integration/stages/upload_data/uploader_log/migrations/0001_initial.py +31 -0
  181. edu_rdm_integration/stages/upload_data/uploader_log/migrations/__init__.py +0 -0
  182. edu_rdm_integration/stages/upload_data/uploader_log/models.py +86 -0
  183. edu_rdm_integration/{uploader_log → stages/upload_data/uploader_log}/ui.py +8 -6
  184. {edu_rdm_integration-3.9.1.dist-info → edu_rdm_integration-3.10.0.dist-info}/METADATA +238 -238
  185. edu_rdm_integration-3.10.0.dist-info/RECORD +255 -0
  186. edu_rdm_integration/app_meta.py +0 -16
  187. edu_rdm_integration/app_settings.py +0 -77
  188. edu_rdm_integration/collect_and_export_data/models.py +0 -67
  189. edu_rdm_integration/collect_and_export_data/utils.py +0 -224
  190. edu_rdm_integration/collect_data/base/helpers.py +0 -26
  191. edu_rdm_integration/collect_data/calculated/base/errors.py +0 -9
  192. edu_rdm_integration/collect_data/calculated/base/helpers.py +0 -32
  193. edu_rdm_integration/collect_data/calculated/base/managers.py +0 -23
  194. edu_rdm_integration/collect_data/calculated/base/results.py +0 -16
  195. edu_rdm_integration/collect_data/calculated/base/runners.py +0 -36
  196. edu_rdm_integration/collect_data/calculated/base/validators.py +0 -28
  197. edu_rdm_integration/collect_data/helpers.py +0 -92
  198. edu_rdm_integration/collect_data/non_calculated/base/errors.py +0 -9
  199. edu_rdm_integration/collect_data/non_calculated/base/helpers.py +0 -32
  200. edu_rdm_integration/collect_data/non_calculated/base/managers.py +0 -23
  201. edu_rdm_integration/collect_data/non_calculated/base/results.py +0 -16
  202. edu_rdm_integration/collect_data/non_calculated/base/runners.py +0 -36
  203. edu_rdm_integration/collect_data/non_calculated/base/validators.py +0 -28
  204. edu_rdm_integration/enum_register/register.py +0 -79
  205. edu_rdm_integration/export_data/base/errors.py +0 -9
  206. edu_rdm_integration/export_data/base/presenters.py +0 -13
  207. edu_rdm_integration/export_data/base/results.py +0 -16
  208. edu_rdm_integration/export_data/base/validators.py +0 -28
  209. edu_rdm_integration/export_data/helpers.py +0 -92
  210. edu_rdm_integration/helpers.py +0 -412
  211. edu_rdm_integration/management/general.py +0 -327
  212. edu_rdm_integration/models.py +0 -982
  213. edu_rdm_integration/redis_cache.py +0 -51
  214. edu_rdm_integration/uploader_log/apps.py +0 -10
  215. edu_rdm_integration-3.9.1.dist-info/RECORD +0 -198
  216. /edu_rdm_integration/{collect_and_export_data/migrations → core}/__init__.py +0 -0
  217. /edu_rdm_integration/{mapping.py → core/mapping.py} +0 -0
  218. /edu_rdm_integration/{collect_data → core/registry}/__init__.py +0 -0
  219. /edu_rdm_integration/{templates → core/registry/templates}/ui-js/start-task.js +0 -0
  220. /edu_rdm_integration/{signals.py → core/signals.py} +0 -0
  221. /edu_rdm_integration/{typing.py → core/typing.py} +0 -0
  222. /edu_rdm_integration/{collect_data/base → pipelines}/__init__.py +0 -0
  223. /edu_rdm_integration/{collect_data/calculated → pipelines/transfer}/__init__.py +0 -0
  224. /edu_rdm_integration/{collect_data/calculated/base → pipelines/transfer/migrations}/__init__.py +0 -0
  225. /edu_rdm_integration/{templates → pipelines/transfer/templates}/ui-js/transferred-entity-list.js +0 -0
  226. /edu_rdm_integration/{collect_data/non_calculated → rdm_entities}/__init__.py +0 -0
  227. /edu_rdm_integration/{collect_data/non_calculated/base → rdm_entities/migrations}/__init__.py +0 -0
  228. /edu_rdm_integration/{enum_register → rdm_models}/__init__.py +0 -0
  229. /edu_rdm_integration/{export_data → rdm_models/migrations}/__init__.py +0 -0
  230. /edu_rdm_integration/{export_data/base → stages}/__init__.py +0 -0
  231. /edu_rdm_integration/{function_templates → stages/collect_data}/__init__.py +0 -0
  232. /edu_rdm_integration/{collect_data/const.py → stages/collect_data/consts.py} +0 -0
  233. /edu_rdm_integration/{management → stages/collect_data/function_templates}/__init__.py +0 -0
  234. /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/__init__.py-tpl +0 -0
  235. /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/apps.py-tpl +0 -0
  236. /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/caches.py-tpl +0 -0
  237. /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/consts.py-tpl +0 -0
  238. /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/enums.py-tpl +0 -0
  239. /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/errors.py-tpl +0 -0
  240. /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/helpers.py-tpl +0 -0
  241. /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/presenters.py-tpl +0 -0
  242. /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/results.py-tpl +0 -0
  243. /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/strings.py-tpl +0 -0
  244. /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/validators.py-tpl +0 -0
  245. /edu_rdm_integration/{management/commands → stages/collect_data/functions}/__init__.py +0 -0
  246. /edu_rdm_integration/{registry → stages/collect_data/functions/base}/__init__.py +0 -0
  247. /edu_rdm_integration/{collect_data → stages/collect_data/functions}/base/consts.py +0 -0
  248. /edu_rdm_integration/{uploader_log → stages/collect_data/functions/calculated}/__init__.py +0 -0
  249. /edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/consts.py +0 -0
  250. /edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/enums.py +0 -0
  251. /edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/strings.py +0 -0
  252. /edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/tests.py +0 -0
  253. /edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/consts.py +0 -0
  254. /edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/enums.py +0 -0
  255. /edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/strings.py +0 -0
  256. /edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/tests.py +0 -0
  257. /edu_rdm_integration/{export_data → stages/export_data}/consts.py +0 -0
  258. /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/__init__.py-tpl +0 -0
  259. /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/apps.py-tpl +0 -0
  260. /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/caches.py-tpl +0 -0
  261. /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/consts.py-tpl +0 -0
  262. /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/enums.py-tpl +0 -0
  263. /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/errors.py-tpl +0 -0
  264. /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/helpers.py-tpl +0 -0
  265. /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/presenters.py-tpl +0 -0
  266. /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/results.py-tpl +0 -0
  267. /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/strings.py-tpl +0 -0
  268. /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/tests.py-tpl +0 -0
  269. /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/validators.py-tpl +0 -0
  270. /edu_rdm_integration/{export_data → stages/export_data/functions}/base/consts.py +0 -0
  271. /edu_rdm_integration/{export_data → stages/export_data/functions}/base/enums.py +0 -0
  272. /edu_rdm_integration/{export_data → stages/export_data/functions}/base/strings.py +0 -0
  273. /edu_rdm_integration/{export_data → stages/export_data/functions}/base/tests.py +0 -0
  274. /edu_rdm_integration/{templates → stages/export_data/registry/templates}/ui-js/stage_for_export.js +0 -0
  275. /edu_rdm_integration/{uploader_log → stages/upload_data/uploader_log}/enums.py +0 -0
  276. /edu_rdm_integration/{uploader_log → stages/upload_data/uploader_log}/templates/ui-js/object-grid-buttons.js +0 -0
  277. {edu_rdm_integration-3.9.1.dist-info → edu_rdm_integration-3.10.0.dist-info}/WHEEL +0 -0
  278. {edu_rdm_integration-3.9.1.dist-info → edu_rdm_integration-3.10.0.dist-info}/licenses/LICENSE +0 -0
  279. {edu_rdm_integration-3.9.1.dist-info → edu_rdm_integration-3.10.0.dist-info}/top_level.txt +0 -0
@@ -3,8 +3,6 @@ from pathlib import (
3
3
  )
4
4
  from typing import (
5
5
  TYPE_CHECKING,
6
- Any,
7
- Iterable,
8
6
  Optional,
9
7
  )
10
8
 
@@ -22,51 +20,63 @@ from django.db.transaction import (
22
20
  from uploader_client.adapters import (
23
21
  adapter,
24
22
  )
23
+ from web_edu.plugins.gis_ruo.enums import (
24
+ OPERATIONS_METHODS_MAP,
25
+ )
25
26
 
26
27
  from educommon import (
27
28
  logger,
28
29
  )
29
30
 
30
- from edu_rdm_integration.consts import (
31
+ from edu_rdm_integration.core.consts import (
31
32
  LOGS_DELIMITER,
32
33
  )
33
- from edu_rdm_integration.enums import (
34
- FileUploadStatusEnum,
34
+ from edu_rdm_integration.core.redis_cache import (
35
+ AbstractCache,
35
36
  )
36
- from edu_rdm_integration.export_data.base.consts import (
37
- OPERATIONS_METHODS_MAP,
37
+ from edu_rdm_integration.stages.export_data.consts import (
38
+ ATTACHMENTS_LIMIT,
39
+ TOTAL_ATTACHMENTS_SIZE_KEY,
40
+ )
41
+ from edu_rdm_integration.stages.export_data.functions.base.consts import (
38
42
  OPERATIONS_URLS_MAP,
39
43
  )
40
- from edu_rdm_integration.export_data.base.requests import (
44
+ from edu_rdm_integration.stages.export_data.functions.base.requests import (
41
45
  RegionalDataMartEntityRequest,
42
46
  )
43
- from edu_rdm_integration.export_data.consts import (
44
- ATTACHMENTS_LIMIT,
45
- TOTAL_ATTACHMENTS_SIZE_KEY,
47
+ from edu_rdm_integration.stages.export_data.models import (
48
+ ExportingDataSubStage,
49
+ ExportingDataSubStageAttachment,
50
+ ExportingDataSubStageStatus,
46
51
  )
47
- from edu_rdm_integration.export_data.dataclasses import (
52
+ from edu_rdm_integration.stages.upload_data.consts import (
53
+ FAILED_STATUSES,
54
+ )
55
+ from edu_rdm_integration.stages.upload_data.dataclasses import (
48
56
  UploadFile,
49
57
  )
50
- from edu_rdm_integration.export_data.queue import (
51
- Queue,
58
+ from edu_rdm_integration.stages.upload_data.enums import (
59
+ FileUploadStatusEnum,
52
60
  )
53
- from edu_rdm_integration.helpers import (
54
- FAILED_STATUSES,
61
+ from edu_rdm_integration.stages.upload_data.helpers import (
55
62
  UploadStatusHelper,
56
63
  )
57
- from edu_rdm_integration.models import (
64
+ from edu_rdm_integration.stages.upload_data.models import (
58
65
  DataMartRequestStatus,
59
- ExportingDataSubStage,
60
- ExportingDataSubStageAttachment,
61
- ExportingDataSubStageStatus,
62
66
  ExportingDataSubStageUploaderClientLog,
63
67
  UploadStatusRequestLog,
64
68
  )
65
- from edu_rdm_integration.redis_cache import (
66
- AbstractCache,
69
+ from edu_rdm_integration.stages.upload_data.queues import (
70
+ Queue,
67
71
  )
68
72
 
69
73
 
74
+ if TYPE_CHECKING:
75
+ from uploader_client.models import (
76
+ Entry,
77
+ )
78
+
79
+
70
80
  class ExportQueueSender:
71
81
  """Класс отправки данных в очередь РВД."""
72
82
 
@@ -86,9 +96,9 @@ class ExportQueueSender:
86
96
  sended_attachment_ids = ExportingDataSubStageUploaderClientLog.objects.filter(
87
97
  file_upload_status=FileUploadStatusEnum.IN_PROGRESS
88
98
  ).values_list('attachment_id', flat=True)
89
- file_size = ExportingDataSubStageAttachment.objects.filter(
90
- id__in=sended_attachment_ids
91
- ).aggregate(Sum('attachment_size'))['attachment_size__sum']
99
+ file_size = ExportingDataSubStageAttachment.objects.filter(id__in=sended_attachment_ids).aggregate(
100
+ Sum('attachment_size')
101
+ )['attachment_size__sum']
92
102
 
93
103
  return file_size or 0
94
104
 
@@ -98,25 +108,30 @@ class ExportQueueSender:
98
108
 
99
109
  def get_sub_stages_attachments_to_export(self):
100
110
  """Выборка готовых к экспорту подэтапов."""
101
- sub_stage_ids = ExportingDataSubStage.objects.filter(
102
- self._make_stage_filter()
103
- ).order_by('started_at').values_list('id', flat=True)[:self.limit]
104
-
105
- return ExportingDataSubStage.objects.filter(
106
- id__in=sub_stage_ids
107
- ).annotate(
108
- attachment_id=F('exportingdatasubstageattachment__id'),
109
- attachment_name=F('exportingdatasubstageattachment__attachment'),
110
- attachment_size=F('exportingdatasubstageattachment__attachment_size'),
111
- operation=F('exportingdatasubstageattachment__operation'),
112
- entity=F('exportingdatasubstageentity__entity_id')
113
- ).order_by('id', 'operation').values(
114
- 'id',
115
- 'attachment_id',
116
- 'attachment_name',
117
- 'attachment_size',
118
- 'operation',
119
- 'entity',
111
+ sub_stage_ids = (
112
+ ExportingDataSubStage.objects.filter(self._make_stage_filter())
113
+ .order_by('started_at')
114
+ .values_list('id', flat=True)[: self.limit]
115
+ )
116
+
117
+ return (
118
+ ExportingDataSubStage.objects.filter(id__in=sub_stage_ids)
119
+ .annotate(
120
+ attachment_id=F('exportingdatasubstageattachment__id'),
121
+ attachment_name=F('exportingdatasubstageattachment__attachment'),
122
+ attachment_size=F('exportingdatasubstageattachment__attachment_size'),
123
+ operation=F('exportingdatasubstageattachment__operation'),
124
+ entity=F('exportingdatasubstageentity__entity_id'),
125
+ )
126
+ .order_by('id', 'operation')
127
+ .values(
128
+ 'id',
129
+ 'attachment_id',
130
+ 'attachment_name',
131
+ 'attachment_size',
132
+ 'operation',
133
+ 'entity',
134
+ )
120
135
  )
121
136
 
122
137
  def set_sub_stage_to_cache(self, sub_stage_id: int, entity_name: str, attachments: list[UploadFile]) -> bool:
@@ -129,14 +144,10 @@ class ExportQueueSender:
129
144
  self.queue_total_file_size += sub_stage_total_size
130
145
  # Обновим размер файлов в кеш
131
146
  self.cache.set(
132
- TOTAL_ATTACHMENTS_SIZE_KEY,
133
- self.queue_total_file_size,
134
- timeout=settings.RDM_REDIS_CACHE_TIMEOUT_SECONDS
147
+ TOTAL_ATTACHMENTS_SIZE_KEY, self.queue_total_file_size, timeout=settings.RDM_REDIS_CACHE_TIMEOUT_SECONDS
135
148
  )
136
149
 
137
- logger.info(
138
- f'{LOGS_DELIMITER * 2}ExportedDataSubStage {sub_stage_id} {entity_name} added to the queue'
139
- )
150
+ logger.info(f'{LOGS_DELIMITER * 2}ExportedDataSubStage {sub_stage_id} {entity_name} added to the queue')
140
151
 
141
152
  return True
142
153
 
@@ -162,12 +173,14 @@ class ExportQueueSender:
162
173
  prev_sub_stage = stage_attachment['id']
163
174
 
164
175
  if stage_attachment['attachment_size']:
165
- stage_files.append(UploadFile(
166
- stage_attachment['attachment_id'],
167
- stage_attachment['attachment_name'],
168
- stage_attachment['attachment_size'],
169
- stage_attachment['operation']
170
- ))
176
+ stage_files.append(
177
+ UploadFile(
178
+ stage_attachment['attachment_id'],
179
+ stage_attachment['attachment_name'],
180
+ stage_attachment['attachment_size'],
181
+ stage_attachment['operation'],
182
+ )
183
+ )
171
184
  entity = stage_attachment['entity']
172
185
 
173
186
  # Обновляем общий объем очереди и закидываем последний элемент
@@ -176,14 +189,10 @@ class ExportQueueSender:
176
189
  else:
177
190
  # Сохраняем объем отправленных файлов в кеш
178
191
  self.cache.set(
179
- TOTAL_ATTACHMENTS_SIZE_KEY,
180
- self.queue_total_file_size,
181
- timeout=settings.RDM_REDIS_CACHE_TIMEOUT_SECONDS
192
+ TOTAL_ATTACHMENTS_SIZE_KEY, self.queue_total_file_size, timeout=settings.RDM_REDIS_CACHE_TIMEOUT_SECONDS
182
193
  )
183
194
  self.queue_is_full = True
184
- logger.warning(
185
- f'Total exported file size: {self.queue_total_file_size} - queue is full!!!'
186
- )
195
+ logger.warning(f'Total exported file size: {self.queue_total_file_size} - queue is full!!!')
187
196
 
188
197
 
189
198
  class WorkerSender:
@@ -303,9 +312,7 @@ class WorkerSender:
303
312
  errors.append(result.error)
304
313
  status = ExportingDataSubStageStatus.FAILED.key
305
314
  else:
306
- logger.info(
307
- f'Response with {result.response.status_code} code and content {result.response.text}'
308
- )
315
+ logger.info(f'Response with {result.response.status_code} code and content {result.response.text}')
309
316
  self.entities.add(entity_key)
310
317
 
311
318
  # Сохраняем информацию об отправке файлов и убираем подэтап с файлами из очереди
@@ -316,9 +323,7 @@ class WorkerSender:
316
323
  sub_stage.save()
317
324
 
318
325
  self.queue.delete_from_queue(sub_stage_id=sub_stage_id, entity_name=entity_key)
319
- logger.info(
320
- f'{LOGS_DELIMITER * 3}ExportedDataSubStage {sub_stage_id} {entity_key} sended from the queue'
321
- )
326
+ logger.info(f'{LOGS_DELIMITER * 3}ExportedDataSubStage {sub_stage_id} {entity_key} sent from the queue')
322
327
 
323
328
  def run(self):
324
329
  """Запуск воркера отправки."""
@@ -0,0 +1,164 @@
1
+ from concurrent.futures import (
2
+ ThreadPoolExecutor,
3
+ )
4
+ from json import (
5
+ JSONDecodeError,
6
+ )
7
+ from typing import (
8
+ TYPE_CHECKING,
9
+ Any,
10
+ Optional,
11
+ )
12
+
13
+ from django.conf import (
14
+ settings,
15
+ )
16
+ from django.db import (
17
+ transaction,
18
+ )
19
+ from django.db.models import (
20
+ QuerySet,
21
+ )
22
+ from uploader_client.adapters import (
23
+ adapter,
24
+ )
25
+
26
+ from educommon import (
27
+ logger,
28
+ )
29
+
30
+ from edu_rdm_integration.core.redis_cache import (
31
+ AbstractCache,
32
+ )
33
+ from edu_rdm_integration.stages.export_data.consts import (
34
+ TOTAL_ATTACHMENTS_SIZE_KEY,
35
+ )
36
+ from edu_rdm_integration.stages.export_data.functions.base.requests import (
37
+ RegionalDataMartStatusRequest,
38
+ )
39
+ from edu_rdm_integration.stages.export_data.models import (
40
+ ExportingDataSubStageStatus,
41
+ )
42
+ from edu_rdm_integration.stages.upload_data.consts import (
43
+ FAILED_STATUSES,
44
+ )
45
+ from edu_rdm_integration.stages.upload_data.enums import (
46
+ FileUploadStatusEnum,
47
+ )
48
+ from edu_rdm_integration.stages.upload_data.models import (
49
+ DataMartRequestStatus,
50
+ ExportingDataSubStageUploaderClientLog,
51
+ UploadStatusRequestLog,
52
+ )
53
+
54
+
55
+ if TYPE_CHECKING:
56
+ from uploader_client.logging.base import (
57
+ Entry,
58
+ )
59
+
60
+
61
+ class UploadStatusHelper:
62
+ """Хелпер проверки статуса загрузки данных в витрину."""
63
+
64
+ def __init__(self, in_progress_uploads: QuerySet, cache: AbstractCache) -> None:
65
+ self._in_progress_uploads = in_progress_uploads
66
+ self.cache = cache
67
+
68
+ def run(self, thread_count: int = 1) -> None:
69
+ """Запускает проверки статусов."""
70
+ if thread_count > 1:
71
+ with ThreadPoolExecutor(max_workers=thread_count) as pool:
72
+ pool.map(self._process_upload, self._in_progress_uploads)
73
+ else:
74
+ for upload in self._in_progress_uploads:
75
+ self._process_upload(upload)
76
+
77
+ @classmethod
78
+ def send_upload_status_request(cls, request_id: str) -> tuple[Optional[dict[str, Any]], 'Entry']:
79
+ """Формирует и отправляет запрос для получения статуса загрузки данных в витрину."""
80
+ request = RegionalDataMartStatusRequest(
81
+ request_id=request_id,
82
+ method='GET',
83
+ parameters={},
84
+ headers={
85
+ 'Content-Type': 'application/json',
86
+ },
87
+ )
88
+
89
+ result = adapter.send(request)
90
+
91
+ response = None
92
+
93
+ if result.error:
94
+ logger.warning(
95
+ f'Ошибка при получении статуса загрузки данных в витрину. Идентификатор загрузки: {request_id}. '
96
+ f'Ошибка: {result.error}, запрос: {result.log.request}, ответ: {result.log.response}',
97
+ )
98
+ else:
99
+ logger.info(
100
+ f'Получен ответ со статусом {result.response.status_code} и содержимым {result.response.text}. '
101
+ f'Идентификатор загрузки: {request_id}',
102
+ )
103
+ try:
104
+ response = result.response.json()
105
+ except JSONDecodeError:
106
+ logger.error(
107
+ f'Не удалось получить данные из ответа запроса статуса загрузки данных в витрину. '
108
+ f'Идентификатор загрузки: {request_id}, ответ: {result.response.text}',
109
+ )
110
+
111
+ return response, result.log
112
+
113
+ @classmethod
114
+ def update_upload_status(
115
+ cls,
116
+ upload: ExportingDataSubStageUploaderClientLog,
117
+ response: Optional[dict[str, Any]],
118
+ log_entry: 'Entry',
119
+ ) -> None:
120
+ """Обновляет статус загрузки данных в витрину."""
121
+ request_status = None
122
+
123
+ if isinstance(response, dict):
124
+ request_status = DataMartRequestStatus.get_values_to_enum_data().get(response.get('code'))
125
+
126
+ if not request_status:
127
+ logger.error(
128
+ 'Не удалось определить статус загрузки данных в витрину. Идентификатор загрузки: '
129
+ f'{upload.request_id}, данные ответа: {response}',
130
+ )
131
+
132
+ with transaction.atomic():
133
+ UploadStatusRequestLog.objects.create(
134
+ upload=upload,
135
+ entry=log_entry,
136
+ request_status_id=getattr(request_status, 'key', None),
137
+ )
138
+
139
+ if request_status in FAILED_STATUSES:
140
+ upload.file_upload_status = FileUploadStatusEnum.ERROR
141
+ upload.sub_stage.status_id = ExportingDataSubStageStatus.PROCESS_ERROR.key
142
+ upload.sub_stage.save()
143
+
144
+ elif request_status == DataMartRequestStatus.SUCCESSFULLY_PROCESSED:
145
+ upload.file_upload_status = FileUploadStatusEnum.FINISHED
146
+
147
+ if upload.file_upload_status != FileUploadStatusEnum.IN_PROGRESS:
148
+ upload.save()
149
+
150
+ def _process_upload(self, upload: ExportingDataSubStageUploaderClientLog) -> None:
151
+ """Обрабатывает запись загрузки данных в витрину."""
152
+ response, log_entry = self.send_upload_status_request(upload.request_id)
153
+ self.update_upload_status(upload, response, log_entry)
154
+ # Обновим размер файлов в кеш (с блокировкой на время обновления)
155
+ with self.cache.lock(f'{TOTAL_ATTACHMENTS_SIZE_KEY}:lock', timeout=300):
156
+ queue_total_file_size = self.cache.get(TOTAL_ATTACHMENTS_SIZE_KEY) or 0
157
+ if queue_total_file_size:
158
+ queue_total_file_size -= upload.attachment.attachment_size
159
+ if queue_total_file_size > 0:
160
+ self.cache.set(
161
+ TOTAL_ATTACHMENTS_SIZE_KEY,
162
+ queue_total_file_size,
163
+ timeout=settings.RDM_REDIS_CACHE_TIMEOUT_SECONDS,
164
+ )
@@ -0,0 +1,134 @@
1
+ from typing import (
2
+ TYPE_CHECKING,
3
+ )
4
+
5
+ import uploader_client
6
+ from django.core.cache import (
7
+ DEFAULT_CACHE_ALIAS,
8
+ caches,
9
+ )
10
+ from django.core.management import (
11
+ BaseCommand,
12
+ )
13
+ from uploader_client.adapters import (
14
+ UploaderAdapter,
15
+ )
16
+ from uploader_client.contrib.rdm.interfaces.configurations import (
17
+ RegionalDataMartUploaderConfig,
18
+ )
19
+
20
+
21
+ if TYPE_CHECKING:
22
+ from uploader_client.interfaces import (
23
+ OpenAPIRequest,
24
+ )
25
+
26
+
27
+ class BaseDatamartClientCommand(BaseCommand):
28
+ """Базовая команда для загрузки данных/получение статуса в РВД с использованием uploader_client."""
29
+
30
+ TIMEOUT = 300
31
+ REQUEST_RETRIES = 1
32
+
33
+ def add_arguments(self, parser):
34
+ """Добавление параметров."""
35
+ parser.add_argument(
36
+ '--url',
37
+ type=str,
38
+ required=True,
39
+ help='url хоста Datamart Studio',
40
+ )
41
+ parser.add_argument(
42
+ '--datamart_mnemonic',
43
+ type=str,
44
+ required=True,
45
+ help='мнемоника Витрины',
46
+ )
47
+ parser.add_argument(
48
+ '--organization_ogrn',
49
+ type=str,
50
+ required=True,
51
+ help='ОГРН организации, в рамках которой развёрнута Витрина',
52
+ )
53
+ parser.add_argument(
54
+ '--installation_name',
55
+ type=str,
56
+ required=True,
57
+ help='имя инсталляции в целевой Витрине',
58
+ )
59
+ parser.add_argument(
60
+ '--installation_id',
61
+ type=int,
62
+ required=True,
63
+ help='идентификатор инсталляции (присутствует в её названии)',
64
+ )
65
+ parser.add_argument(
66
+ '--username',
67
+ type=str,
68
+ required=True,
69
+ help='имя пользователя IAM',
70
+ )
71
+ parser.add_argument(
72
+ '--password',
73
+ type=str,
74
+ required=True,
75
+ help='пароль пользователя IAM',
76
+ )
77
+
78
+ def _configure_agent_client(
79
+ self,
80
+ url,
81
+ datamart_mnemonic,
82
+ organization_ogrn,
83
+ installation_name,
84
+ installation_id,
85
+ username,
86
+ password,
87
+ ):
88
+ """Конфигурирование клиента загрузчика данных в Витрину."""
89
+ uploader_client.set_config(
90
+ RegionalDataMartUploaderConfig(
91
+ interface='uploader_client.contrib.rdm.interfaces.rest.ProxyAPIInterface',
92
+ cache=caches[DEFAULT_CACHE_ALIAS],
93
+ url=url,
94
+ datamart_name=datamart_mnemonic,
95
+ organization_ogrn=organization_ogrn,
96
+ installation_name=installation_name,
97
+ installation_id=installation_id,
98
+ username=username,
99
+ password=password,
100
+ timeout=self.TIMEOUT,
101
+ request_retries=self.REQUEST_RETRIES,
102
+ )
103
+ )
104
+
105
+ def _get_request(self, **options) -> 'OpenAPIRequest':
106
+ """Возвращает запрос для отправки в РВД."""
107
+ raise NotImplementedError
108
+
109
+ def handle(self, *args, **options):
110
+ """Выполнение действий команды."""
111
+ self._configure_agent_client(
112
+ url=options['url'],
113
+ datamart_mnemonic=options['datamart_mnemonic'],
114
+ organization_ogrn=options['organization_ogrn'],
115
+ installation_name=options['installation_name'],
116
+ installation_id=options['installation_id'],
117
+ username=options['username'],
118
+ password=options['password'],
119
+ )
120
+
121
+ request = self._get_request(**options)
122
+
123
+ result = UploaderAdapter().send(request)
124
+
125
+ if result.error:
126
+ self.stdout.write(self.style.ERROR('ERROR:\n'))
127
+ self.stdout.write(
128
+ f'{result.error}\nREQUEST:\n"{result.log.request}"\n\nRESPONSE:\n"{result.log.response}"\n'
129
+ )
130
+ else:
131
+ self.stdout.write(self.style.SUCCESS('SUCCESS:\n'))
132
+ self.stdout.write(
133
+ f'Response with {result.response.status_code} code and content:\n{result.response.text}\n'
134
+ )