mage-ai 0.9.70__py3-none-any.whl → 0.9.71__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.

Potentially problematic release.


This version of mage-ai might be problematic. Click here for more details.

Files changed (568) hide show
  1. mage_ai/ai/utils/xgboost.py +222 -0
  2. mage_ai/api/errors.py +37 -25
  3. mage_ai/api/operations/base.py +13 -1
  4. mage_ai/api/parsers/PipelineScheduleParser.py +1 -1
  5. mage_ai/api/policies/BlockOutputPolicy.py +40 -17
  6. mage_ai/api/policies/GlobalDataProductPolicy.py +91 -41
  7. mage_ai/api/policies/KernelPolicy.py +55 -32
  8. mage_ai/api/policies/KernelProcessPolicy.py +56 -0
  9. mage_ai/api/policies/OutputPolicy.py +73 -41
  10. mage_ai/api/policies/PipelinePolicy.py +206 -138
  11. mage_ai/api/presenters/BlockLayoutItemPresenter.py +9 -7
  12. mage_ai/api/presenters/BlockPresenter.py +1 -1
  13. mage_ai/api/presenters/GlobalDataProductPresenter.py +6 -1
  14. mage_ai/api/presenters/KernelPresenter.py +5 -26
  15. mage_ai/api/presenters/KernelProcessPresenter.py +28 -0
  16. mage_ai/api/presenters/PipelinePresenter.py +18 -5
  17. mage_ai/api/presenters/StatusPresenter.py +2 -0
  18. mage_ai/api/presenters/SyncPresenter.py +25 -0
  19. mage_ai/api/resources/AutocompleteItemResource.py +1 -1
  20. mage_ai/api/resources/BlockLayoutItemResource.py +90 -44
  21. mage_ai/api/resources/BlockOutputResource.py +42 -9
  22. mage_ai/api/resources/BlockResource.py +4 -3
  23. mage_ai/api/resources/BlockRunResource.py +27 -22
  24. mage_ai/api/resources/ClusterResource.py +4 -1
  25. mage_ai/api/resources/CustomTemplateResource.py +34 -14
  26. mage_ai/api/resources/DataProviderResource.py +1 -1
  27. mage_ai/api/resources/ExecutionStateResource.py +3 -1
  28. mage_ai/api/resources/FileContentResource.py +8 -2
  29. mage_ai/api/resources/FileResource.py +10 -4
  30. mage_ai/api/resources/FileVersionResource.py +3 -1
  31. mage_ai/api/resources/GitBranchResource.py +46 -9
  32. mage_ai/api/resources/GlobalDataProductResource.py +44 -7
  33. mage_ai/api/resources/GlobalHookResource.py +4 -1
  34. mage_ai/api/resources/IntegrationDestinationResource.py +6 -2
  35. mage_ai/api/resources/IntegrationSourceResource.py +8 -4
  36. mage_ai/api/resources/IntegrationSourceStreamResource.py +6 -2
  37. mage_ai/api/resources/KernelProcessResource.py +44 -0
  38. mage_ai/api/resources/KernelResource.py +25 -3
  39. mage_ai/api/resources/OutputResource.py +33 -11
  40. mage_ai/api/resources/PageBlockLayoutResource.py +34 -23
  41. mage_ai/api/resources/PipelineInteractionResource.py +31 -15
  42. mage_ai/api/resources/PipelineResource.py +250 -123
  43. mage_ai/api/resources/PipelineRunResource.py +11 -3
  44. mage_ai/api/resources/PipelineScheduleResource.py +7 -2
  45. mage_ai/api/resources/PipelineTriggerResource.py +6 -1
  46. mage_ai/api/resources/ProjectResource.py +18 -7
  47. mage_ai/api/resources/SecretResource.py +1 -1
  48. mage_ai/api/resources/SeedResource.py +8 -1
  49. mage_ai/api/resources/StatusResource.py +21 -6
  50. mage_ai/api/resources/SyncResource.py +6 -8
  51. mage_ai/api/resources/VariableResource.py +46 -26
  52. mage_ai/api/resources/VersionControlProjectResource.py +9 -2
  53. mage_ai/api/resources/WidgetResource.py +1 -1
  54. mage_ai/api/resources/WorkspaceResource.py +1 -1
  55. mage_ai/api/views.py +47 -40
  56. mage_ai/authentication/permissions/seed.py +16 -2
  57. mage_ai/authentication/providers/oidc.py +21 -1
  58. mage_ai/autocomplete/utils.py +13 -9
  59. mage_ai/cache/base.py +1 -1
  60. mage_ai/cache/block.py +18 -12
  61. mage_ai/cache/block_action_object/__init__.py +32 -4
  62. mage_ai/cache/file.py +22 -19
  63. mage_ai/cache/pipeline.py +18 -12
  64. mage_ai/cli/main.py +1 -0
  65. mage_ai/cluster_manager/aws/emr_cluster_manager.py +9 -5
  66. mage_ai/cluster_manager/config.py +2 -2
  67. mage_ai/cluster_manager/manage.py +1 -1
  68. mage_ai/cluster_manager/workspace/base.py +1 -1
  69. mage_ai/command_center/applications/factory.py +10 -7
  70. mage_ai/command_center/files/factory.py +17 -15
  71. mage_ai/command_center/utils.py +25 -13
  72. mage_ai/data/__init__.py +0 -0
  73. mage_ai/data/constants.py +45 -0
  74. mage_ai/data/models/__init__.py +0 -0
  75. mage_ai/data/models/base.py +119 -0
  76. mage_ai/data/models/constants.py +1 -0
  77. mage_ai/data/models/generator.py +115 -0
  78. mage_ai/data/models/manager.py +168 -0
  79. mage_ai/data/models/pyarrow/__init__.py +0 -0
  80. mage_ai/data/models/pyarrow/record_batch.py +55 -0
  81. mage_ai/data/models/pyarrow/shared.py +21 -0
  82. mage_ai/data/models/pyarrow/table.py +8 -0
  83. mage_ai/data/models/reader.py +103 -0
  84. mage_ai/data/models/utils.py +59 -0
  85. mage_ai/data/models/writer.py +91 -0
  86. mage_ai/data/tabular/__init__.py +0 -0
  87. mage_ai/data/tabular/constants.py +23 -0
  88. mage_ai/data/tabular/mocks.py +19 -0
  89. mage_ai/data/tabular/models.py +126 -0
  90. mage_ai/data/tabular/reader.py +602 -0
  91. mage_ai/data/tabular/utils.py +102 -0
  92. mage_ai/data/tabular/writer.py +266 -0
  93. mage_ai/data/variables/__init__.py +0 -0
  94. mage_ai/data/variables/wrapper.py +54 -0
  95. mage_ai/data_cleaner/analysis/charts.py +61 -39
  96. mage_ai/data_cleaner/column_types/column_type_detector.py +53 -31
  97. mage_ai/data_cleaner/estimators/encoders.py +5 -2
  98. mage_ai/data_integrations/utils/scheduler.py +16 -11
  99. mage_ai/data_preparation/decorators.py +1 -0
  100. mage_ai/data_preparation/executors/block_executor.py +237 -155
  101. mage_ai/data_preparation/executors/streaming_pipeline_executor.py +1 -1
  102. mage_ai/data_preparation/git/__init__.py +27 -7
  103. mage_ai/data_preparation/git/api.py +7 -1
  104. mage_ai/data_preparation/git/utils.py +22 -16
  105. mage_ai/data_preparation/logging/logger_manager.py +4 -3
  106. mage_ai/data_preparation/models/block/__init__.py +1542 -878
  107. mage_ai/data_preparation/models/block/data_integration/mixins.py +4 -3
  108. mage_ai/data_preparation/models/block/dynamic/__init__.py +17 -6
  109. mage_ai/data_preparation/models/block/dynamic/child.py +41 -102
  110. mage_ai/data_preparation/models/block/dynamic/constants.py +1 -0
  111. mage_ai/data_preparation/models/block/dynamic/counter.py +296 -0
  112. mage_ai/data_preparation/models/block/dynamic/data.py +16 -0
  113. mage_ai/data_preparation/models/block/dynamic/factory.py +163 -0
  114. mage_ai/data_preparation/models/block/dynamic/models.py +19 -0
  115. mage_ai/data_preparation/models/block/dynamic/shared.py +92 -0
  116. mage_ai/data_preparation/models/block/dynamic/utils.py +291 -168
  117. mage_ai/data_preparation/models/block/dynamic/variables.py +384 -144
  118. mage_ai/data_preparation/models/block/dynamic/wrappers.py +77 -0
  119. mage_ai/data_preparation/models/block/extension/utils.py +10 -1
  120. mage_ai/data_preparation/models/block/global_data_product/__init__.py +10 -1
  121. mage_ai/data_preparation/models/block/integration/__init__.py +6 -2
  122. mage_ai/data_preparation/models/block/outputs.py +722 -0
  123. mage_ai/data_preparation/models/block/platform/mixins.py +7 -8
  124. mage_ai/data_preparation/models/block/r/__init__.py +56 -38
  125. mage_ai/data_preparation/models/block/settings/__init__.py +0 -0
  126. mage_ai/data_preparation/models/block/settings/dynamic/__init__.py +0 -0
  127. mage_ai/data_preparation/models/block/settings/dynamic/constants.py +7 -0
  128. mage_ai/data_preparation/models/block/settings/dynamic/mixins.py +118 -0
  129. mage_ai/data_preparation/models/block/settings/dynamic/models.py +31 -0
  130. mage_ai/data_preparation/models/block/settings/global_data_products/__init__.py +0 -0
  131. mage_ai/data_preparation/models/block/settings/global_data_products/mixins.py +20 -0
  132. mage_ai/data_preparation/models/block/settings/global_data_products/models.py +46 -0
  133. mage_ai/data_preparation/models/block/settings/variables/__init__.py +0 -0
  134. mage_ai/data_preparation/models/block/settings/variables/mixins.py +74 -0
  135. mage_ai/data_preparation/models/block/settings/variables/models.py +49 -0
  136. mage_ai/data_preparation/models/block/spark/mixins.py +2 -1
  137. mage_ai/data_preparation/models/block/sql/__init__.py +30 -5
  138. mage_ai/data_preparation/models/block/sql/utils/shared.py +21 -3
  139. mage_ai/data_preparation/models/block/utils.py +127 -70
  140. mage_ai/data_preparation/models/constants.py +19 -14
  141. mage_ai/data_preparation/models/custom_templates/custom_block_template.py +18 -13
  142. mage_ai/data_preparation/models/custom_templates/custom_pipeline_template.py +33 -16
  143. mage_ai/data_preparation/models/custom_templates/utils.py +1 -1
  144. mage_ai/data_preparation/models/file.py +41 -28
  145. mage_ai/data_preparation/models/global_data_product/__init__.py +88 -58
  146. mage_ai/data_preparation/models/global_hooks/models.py +1 -0
  147. mage_ai/data_preparation/models/interfaces.py +29 -0
  148. mage_ai/data_preparation/models/pipeline.py +365 -180
  149. mage_ai/data_preparation/models/pipelines/integration_pipeline.py +1 -2
  150. mage_ai/data_preparation/models/pipelines/seed.py +1 -1
  151. mage_ai/data_preparation/models/project/__init__.py +66 -18
  152. mage_ai/data_preparation/models/project/constants.py +2 -0
  153. mage_ai/data_preparation/models/triggers/__init__.py +120 -24
  154. mage_ai/data_preparation/models/utils.py +467 -17
  155. mage_ai/data_preparation/models/variable.py +1028 -137
  156. mage_ai/data_preparation/models/variables/__init__.py +0 -0
  157. mage_ai/data_preparation/models/variables/cache.py +149 -0
  158. mage_ai/data_preparation/models/variables/constants.py +72 -0
  159. mage_ai/data_preparation/models/variables/summarizer.py +336 -0
  160. mage_ai/data_preparation/models/variables/utils.py +77 -0
  161. mage_ai/data_preparation/models/widget/__init__.py +63 -41
  162. mage_ai/data_preparation/models/widget/charts.py +40 -27
  163. mage_ai/data_preparation/models/widget/constants.py +2 -0
  164. mage_ai/data_preparation/models/widget/utils.py +3 -3
  165. mage_ai/data_preparation/preferences.py +3 -3
  166. mage_ai/data_preparation/repo_manager.py +55 -21
  167. mage_ai/data_preparation/storage/base_storage.py +2 -2
  168. mage_ai/data_preparation/storage/gcs_storage.py +7 -4
  169. mage_ai/data_preparation/storage/local_storage.py +6 -3
  170. mage_ai/data_preparation/storage/s3_storage.py +5 -2
  171. mage_ai/data_preparation/templates/data_exporters/streaming/oracledb.yaml +8 -0
  172. mage_ai/data_preparation/variable_manager.py +281 -76
  173. mage_ai/io/base.py +3 -2
  174. mage_ai/io/bigquery.py +1 -0
  175. mage_ai/io/redshift.py +7 -5
  176. mage_ai/kernels/__init__.py +0 -0
  177. mage_ai/kernels/models.py +188 -0
  178. mage_ai/kernels/utils.py +169 -0
  179. mage_ai/orchestration/concurrency.py +6 -2
  180. mage_ai/orchestration/db/__init__.py +1 -0
  181. mage_ai/orchestration/db/migrations/versions/0227396a216c_add_userproject_table.py +38 -0
  182. mage_ai/orchestration/db/models/dynamic/__init__.py +0 -0
  183. mage_ai/orchestration/db/models/dynamic/controller.py +67 -0
  184. mage_ai/orchestration/db/models/oauth.py +2 -9
  185. mage_ai/orchestration/db/models/projects.py +10 -0
  186. mage_ai/orchestration/db/models/schedules.py +204 -187
  187. mage_ai/orchestration/db/models/schedules_project_platform.py +18 -12
  188. mage_ai/orchestration/db/models/utils.py +46 -5
  189. mage_ai/orchestration/metrics/pipeline_run.py +8 -9
  190. mage_ai/orchestration/notification/sender.py +1 -0
  191. mage_ai/orchestration/pipeline_scheduler_original.py +32 -8
  192. mage_ai/orchestration/pipeline_scheduler_project_platform.py +1 -1
  193. mage_ai/orchestration/run_status_checker.py +11 -4
  194. mage_ai/orchestration/triggers/api.py +12 -1
  195. mage_ai/presenters/charts/data_sources/base.py +4 -2
  196. mage_ai/presenters/charts/data_sources/block.py +15 -9
  197. mage_ai/presenters/charts/data_sources/chart_code.py +8 -5
  198. mage_ai/presenters/charts/data_sources/constants.py +1 -0
  199. mage_ai/presenters/charts/data_sources/system_metrics.py +22 -0
  200. mage_ai/presenters/interactions/models.py +11 -7
  201. mage_ai/presenters/pages/loaders/pipelines.py +5 -3
  202. mage_ai/presenters/pages/models/page_components/pipeline_schedules.py +3 -1
  203. mage_ai/presenters/utils.py +2 -0
  204. mage_ai/server/api/blocks.py +2 -1
  205. mage_ai/server/api/downloads.py +5 -1
  206. mage_ai/server/api/triggers.py +3 -1
  207. mage_ai/server/constants.py +1 -1
  208. mage_ai/server/frontend_dist/404.html +5 -5
  209. mage_ai/server/frontend_dist/_next/static/UZLabyPgcxtZvp0O0EUUS/_buildManifest.js +1 -0
  210. mage_ai/server/frontend_dist/_next/static/chunks/1376-22de38b4ad008d8a.js +1 -0
  211. mage_ai/server/frontend_dist/_next/static/chunks/{1557-b3502f3f1aa92ac7.js → 1557-25a7d985d5564fd3.js} +1 -1
  212. mage_ai/server/frontend_dist/_next/static/chunks/1668-30b4619b9534519b.js +1 -0
  213. mage_ai/server/frontend_dist/_next/static/chunks/1799-c42db95a015689ee.js +1 -0
  214. mage_ai/server/frontend_dist/_next/static/chunks/2996-2108b53b9d371d8d.js +1 -0
  215. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/3763-61b542dafdbf5754.js → frontend_dist/_next/static/chunks/3763-40780c6d1e4b261d.js} +1 -1
  216. mage_ai/server/frontend_dist/_next/static/chunks/3782-129dd2a2448a2e36.js +1 -0
  217. mage_ai/server/frontend_dist/_next/static/chunks/3958-bcdfa414ccfa1eb2.js +1 -0
  218. mage_ai/server/frontend_dist/_next/static/chunks/4168-97fd1578d1a38315.js +1 -0
  219. mage_ai/server/frontend_dist/_next/static/chunks/4982-fa5a238b139fbdd2.js +1 -0
  220. mage_ai/server/frontend_dist/_next/static/chunks/5699-176f445e1313f001.js +1 -0
  221. mage_ai/server/frontend_dist/_next/static/chunks/7162-7dd03f0f605de721.js +1 -0
  222. mage_ai/server/frontend_dist/_next/static/chunks/7779-68d2b72a90c5f925.js +1 -0
  223. mage_ai/server/frontend_dist/_next/static/chunks/7966-5446a8e43711e2f9.js +1 -0
  224. mage_ai/server/frontend_dist/_next/static/chunks/8023-6c2f172f48dcb99b.js +1 -0
  225. mage_ai/server/frontend_dist/_next/static/chunks/8095-c351b8a735d73e0c.js +1 -0
  226. mage_ai/server/frontend_dist/_next/static/chunks/{main-77fe248a6fbd12d8.js → main-b99d4e30a88d9dc7.js} +1 -1
  227. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-9fe2d9d07c94e968.js +1 -0
  228. mage_ai/server/frontend_dist/_next/static/chunks/pages/{block-layout-14f952f66964022f.js → block-layout-7f4b735c67115df5.js} +1 -1
  229. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-e7d48e6b0c3068ac.js +1 -0
  230. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products-b943f31f050fc3a4.js +1 -0
  231. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/overview-597b74828bf105db.js → frontend_dist/_next/static/chunks/pages/overview-9f1ac4ec003884f3.js} +1 -1
  232. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/{[...slug]-7181b086c93784d2.js → [...slug]-7e737f6fc7e83e9b.js} +1 -1
  233. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-d94488e3f2eeef36.js +1 -0
  234. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-cc641a7fa8473796.js +1 -0
  235. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-a5c0362763a21fa8.js → block-runs-284309877f3c5a5a.js} +1 -1
  236. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-26250e5335194ade.js +1 -0
  237. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-7acc7afc00df17c2.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-5f4c8128b2413fd8.js} +1 -1
  238. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-4ebfc8e400315dda.js +1 -0
  239. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-e5e0150a256aadb3.js +1 -0
  240. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/{profile-3f0df3decc856ee9.js → profile-3ae43c932537b254.js} +1 -1
  241. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-32985f3f7c7dd3ab.js → frontend_dist/_next/static/chunks/pages/settings/platform/preferences-b603d7fe4b175256.js} +1 -1
  242. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-c2e9ef989c8bfa73.js → frontend_dist/_next/static/chunks/pages/settings/platform/settings-319ddbabc239e91b.js} +1 -1
  243. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-47b64ced27c24985.js → [...slug]-5c360f72e4498855.js} +1 -1
  244. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{permissions-e5a4d3d815cec25d.js → permissions-fb29fa6c2bd90bb0.js} +1 -1
  245. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-3b76fa959ffa09d3.js +1 -0
  246. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-379e1ee292504842.js → [...slug]-3b787b42f1093b1f.js} +1 -1
  247. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-0b83fbdd39e85f5b.js +1 -0
  248. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-a1e6950974d643a8.js +1 -0
  249. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-2af9afbe727d88aa.js → [...slug]-0aa019d87db8b0b8.js} +1 -1
  250. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{users-a4db8710f703c729.js → users-88c694d19207f2ec.js} +1 -1
  251. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-31d0d50f7f30462b.js +1 -0
  252. mage_ai/server/frontend_dist/_next/static/chunks/{webpack-d079359c241db804.js → webpack-ac7fdc472bedf682.js} +1 -1
  253. mage_ai/server/frontend_dist/block-layout.html +3 -3
  254. mage_ai/server/frontend_dist/compute.html +6 -6
  255. mage_ai/server/frontend_dist/files.html +6 -6
  256. mage_ai/server/frontend_dist/global-data-products/[...slug].html +6 -6
  257. mage_ai/server/frontend_dist/global-data-products.html +6 -6
  258. mage_ai/server/frontend_dist/global-hooks/[...slug].html +6 -6
  259. mage_ai/server/frontend_dist/global-hooks.html +6 -6
  260. mage_ai/server/frontend_dist/index.html +3 -3
  261. mage_ai/server/frontend_dist/manage/files.html +6 -6
  262. mage_ai/server/frontend_dist/manage/settings.html +6 -6
  263. mage_ai/server/frontend_dist/manage/users/[user].html +6 -6
  264. mage_ai/server/frontend_dist/manage/users/new.html +6 -6
  265. mage_ai/server/frontend_dist/manage/users.html +6 -6
  266. mage_ai/server/frontend_dist/manage.html +6 -6
  267. mage_ai/server/frontend_dist/oauth.html +5 -5
  268. mage_ai/server/frontend_dist/overview.html +6 -6
  269. mage_ai/server/frontend_dist/pipeline-runs.html +6 -6
  270. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +6 -6
  271. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +6 -6
  272. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +6 -6
  273. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +3 -3
  274. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +6 -6
  275. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +6 -6
  276. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
  277. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +6 -6
  278. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +6 -6
  279. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +6 -6
  280. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +6 -6
  281. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +6 -6
  282. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +6 -6
  283. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +6 -6
  284. mage_ai/server/frontend_dist/pipelines/[pipeline].html +3 -3
  285. mage_ai/server/frontend_dist/pipelines.html +6 -6
  286. mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +6 -6
  287. mage_ai/server/frontend_dist/platform/global-hooks.html +6 -6
  288. mage_ai/server/frontend_dist/settings/account/profile.html +6 -6
  289. mage_ai/server/frontend_dist/settings/platform/preferences.html +6 -6
  290. mage_ai/server/frontend_dist/settings/platform/settings.html +6 -6
  291. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +6 -6
  292. mage_ai/server/frontend_dist/settings/workspace/permissions.html +6 -6
  293. mage_ai/server/frontend_dist/settings/workspace/preferences.html +6 -6
  294. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +6 -6
  295. mage_ai/server/frontend_dist/settings/workspace/roles.html +6 -6
  296. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +6 -6
  297. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +6 -6
  298. mage_ai/server/frontend_dist/settings/workspace/users.html +6 -6
  299. mage_ai/server/frontend_dist/settings.html +3 -3
  300. mage_ai/server/frontend_dist/sign-in.html +12 -12
  301. mage_ai/server/frontend_dist/templates/[...slug].html +6 -6
  302. mage_ai/server/frontend_dist/templates.html +6 -6
  303. mage_ai/server/frontend_dist/terminal.html +6 -6
  304. mage_ai/server/frontend_dist/test.html +3 -3
  305. mage_ai/server/frontend_dist/triggers.html +6 -6
  306. mage_ai/server/frontend_dist/version-control.html +6 -6
  307. mage_ai/server/frontend_dist_base_path_template/404.html +5 -5
  308. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1376-22de38b4ad008d8a.js +1 -0
  309. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{1557-b3502f3f1aa92ac7.js → 1557-25a7d985d5564fd3.js} +1 -1
  310. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1668-30b4619b9534519b.js +1 -0
  311. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1799-c42db95a015689ee.js +1 -0
  312. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2996-2108b53b9d371d8d.js +1 -0
  313. mage_ai/server/{frontend_dist/_next/static/chunks/3763-61b542dafdbf5754.js → frontend_dist_base_path_template/_next/static/chunks/3763-40780c6d1e4b261d.js} +1 -1
  314. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-129dd2a2448a2e36.js +1 -0
  315. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3958-bcdfa414ccfa1eb2.js +1 -0
  316. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4168-97fd1578d1a38315.js +1 -0
  317. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4982-fa5a238b139fbdd2.js +1 -0
  318. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-176f445e1313f001.js +1 -0
  319. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7162-7dd03f0f605de721.js +1 -0
  320. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7779-68d2b72a90c5f925.js +1 -0
  321. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-5446a8e43711e2f9.js +1 -0
  322. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8023-6c2f172f48dcb99b.js +1 -0
  323. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-c351b8a735d73e0c.js +1 -0
  324. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{main-70b78159c2bb3fe1.js → main-384298e9133cec76.js} +1 -1
  325. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-13a578bce3b7f30c.js +1 -0
  326. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{block-layout-14f952f66964022f.js → block-layout-7f4b735c67115df5.js} +1 -1
  327. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-e7d48e6b0c3068ac.js +1 -0
  328. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products-b943f31f050fc3a4.js +1 -0
  329. mage_ai/server/{frontend_dist/_next/static/chunks/pages/overview-597b74828bf105db.js → frontend_dist_base_path_template/_next/static/chunks/pages/overview-9f1ac4ec003884f3.js} +1 -1
  330. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/{[...slug]-7181b086c93784d2.js → [...slug]-7e737f6fc7e83e9b.js} +1 -1
  331. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-d94488e3f2eeef36.js +1 -0
  332. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-cc641a7fa8473796.js +1 -0
  333. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-a5c0362763a21fa8.js → block-runs-284309877f3c5a5a.js} +1 -1
  334. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-26250e5335194ade.js +1 -0
  335. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-7acc7afc00df17c2.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-5f4c8128b2413fd8.js} +1 -1
  336. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-4ebfc8e400315dda.js +1 -0
  337. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-e5e0150a256aadb3.js +1 -0
  338. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/{profile-3f0df3decc856ee9.js → profile-3ae43c932537b254.js} +1 -1
  339. mage_ai/server/{frontend_dist/_next/static/chunks/pages/settings/platform/preferences-32985f3f7c7dd3ab.js → frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-b603d7fe4b175256.js} +1 -1
  340. mage_ai/server/{frontend_dist/_next/static/chunks/pages/settings/platform/settings-c2e9ef989c8bfa73.js → frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-319ddbabc239e91b.js} +1 -1
  341. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-47b64ced27c24985.js → [...slug]-5c360f72e4498855.js} +1 -1
  342. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{permissions-e5a4d3d815cec25d.js → permissions-fb29fa6c2bd90bb0.js} +1 -1
  343. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-3b76fa959ffa09d3.js +1 -0
  344. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-379e1ee292504842.js → [...slug]-3b787b42f1093b1f.js} +1 -1
  345. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-0b83fbdd39e85f5b.js +1 -0
  346. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-a1e6950974d643a8.js +1 -0
  347. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-2af9afbe727d88aa.js → [...slug]-0aa019d87db8b0b8.js} +1 -1
  348. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{users-a4db8710f703c729.js → users-88c694d19207f2ec.js} +1 -1
  349. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-31d0d50f7f30462b.js +1 -0
  350. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-68c003fb6a175cd7.js → webpack-481689d9989710cd.js} +1 -1
  351. mage_ai/server/frontend_dist_base_path_template/_next/static/kcptwoOU-JJJg6Vwpkfmx/_buildManifest.js +1 -0
  352. mage_ai/server/frontend_dist_base_path_template/block-layout.html +3 -3
  353. mage_ai/server/frontend_dist_base_path_template/compute.html +6 -6
  354. mage_ai/server/frontend_dist_base_path_template/files.html +6 -6
  355. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +6 -6
  356. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +6 -6
  357. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +6 -6
  358. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +6 -6
  359. mage_ai/server/frontend_dist_base_path_template/index.html +3 -3
  360. mage_ai/server/frontend_dist_base_path_template/manage/files.html +6 -6
  361. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +6 -6
  362. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +6 -6
  363. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +6 -6
  364. mage_ai/server/frontend_dist_base_path_template/manage/users.html +6 -6
  365. mage_ai/server/frontend_dist_base_path_template/manage.html +6 -6
  366. mage_ai/server/frontend_dist_base_path_template/oauth.html +5 -5
  367. mage_ai/server/frontend_dist_base_path_template/overview.html +6 -6
  368. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +6 -6
  369. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +6 -6
  370. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +6 -6
  371. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +6 -6
  372. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +3 -3
  373. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +6 -6
  374. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +6 -6
  375. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
  376. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +6 -6
  377. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +6 -6
  378. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +6 -6
  379. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +6 -6
  380. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +6 -6
  381. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +6 -6
  382. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +6 -6
  383. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +3 -3
  384. mage_ai/server/frontend_dist_base_path_template/pipelines.html +6 -6
  385. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +6 -6
  386. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +6 -6
  387. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +6 -6
  388. mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +6 -6
  389. mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +6 -6
  390. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +6 -6
  391. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +6 -6
  392. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +6 -6
  393. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +6 -6
  394. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +6 -6
  395. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +6 -6
  396. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +6 -6
  397. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +6 -6
  398. mage_ai/server/frontend_dist_base_path_template/settings.html +3 -3
  399. mage_ai/server/frontend_dist_base_path_template/sign-in.html +12 -12
  400. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +6 -6
  401. mage_ai/server/frontend_dist_base_path_template/templates.html +6 -6
  402. mage_ai/server/frontend_dist_base_path_template/terminal.html +6 -6
  403. mage_ai/server/frontend_dist_base_path_template/test.html +3 -3
  404. mage_ai/server/frontend_dist_base_path_template/triggers.html +6 -6
  405. mage_ai/server/frontend_dist_base_path_template/version-control.html +6 -6
  406. mage_ai/server/kernel_output_parser.py +4 -1
  407. mage_ai/server/scheduler_manager.py +9 -0
  408. mage_ai/server/server.py +35 -31
  409. mage_ai/server/utils/custom_output.py +284 -0
  410. mage_ai/server/utils/execute_custom_code.py +245 -0
  411. mage_ai/server/utils/output_display.py +123 -289
  412. mage_ai/server/websocket_server.py +116 -69
  413. mage_ai/services/k8s/config.py +23 -0
  414. mage_ai/services/k8s/job_manager.py +6 -1
  415. mage_ai/services/ssh/aws/emr/utils.py +8 -8
  416. mage_ai/settings/keys/auth.py +1 -0
  417. mage_ai/settings/platform/__init__.py +159 -38
  418. mage_ai/settings/platform/constants.py +5 -0
  419. mage_ai/settings/platform/utils.py +53 -10
  420. mage_ai/settings/repo.py +26 -12
  421. mage_ai/settings/server.py +128 -37
  422. mage_ai/shared/array.py +24 -1
  423. mage_ai/shared/complex.py +45 -0
  424. mage_ai/shared/config.py +2 -1
  425. mage_ai/shared/custom_logger.py +11 -0
  426. mage_ai/shared/dates.py +10 -6
  427. mage_ai/shared/files.py +63 -8
  428. mage_ai/shared/hash.py +33 -9
  429. mage_ai/shared/io.py +9 -5
  430. mage_ai/shared/models.py +82 -24
  431. mage_ai/shared/outputs.py +87 -0
  432. mage_ai/shared/parsers.py +141 -15
  433. mage_ai/shared/path_fixer.py +11 -7
  434. mage_ai/shared/singletons/__init__.py +0 -0
  435. mage_ai/shared/singletons/base.py +47 -0
  436. mage_ai/shared/singletons/memory.py +38 -0
  437. mage_ai/shared/strings.py +34 -1
  438. mage_ai/shared/yaml.py +24 -0
  439. mage_ai/streaming/sinks/oracledb.py +57 -0
  440. mage_ai/streaming/sinks/sink_factory.py +4 -0
  441. mage_ai/system/__init__.py +0 -0
  442. mage_ai/system/constants.py +14 -0
  443. mage_ai/system/memory/__init__.py +0 -0
  444. mage_ai/system/memory/constants.py +1 -0
  445. mage_ai/system/memory/manager.py +174 -0
  446. mage_ai/system/memory/presenters.py +158 -0
  447. mage_ai/system/memory/process.py +216 -0
  448. mage_ai/system/memory/samples.py +13 -0
  449. mage_ai/system/memory/utils.py +656 -0
  450. mage_ai/system/memory/wrappers.py +177 -0
  451. mage_ai/system/models.py +58 -0
  452. mage_ai/system/storage/__init__.py +0 -0
  453. mage_ai/system/storage/utils.py +29 -0
  454. mage_ai/tests/api/endpoints/mixins.py +2 -2
  455. mage_ai/tests/api/endpoints/test_blocks.py +2 -1
  456. mage_ai/tests/api/endpoints/test_custom_designs.py +4 -4
  457. mage_ai/tests/api/endpoints/test_pipeline_runs.py +2 -2
  458. mage_ai/tests/api/endpoints/test_projects.py +2 -1
  459. mage_ai/tests/api/operations/base/test_base.py +27 -27
  460. mage_ai/tests/api/operations/base/test_base_with_user_authentication.py +27 -27
  461. mage_ai/tests/api/operations/base/test_base_with_user_permissions.py +23 -23
  462. mage_ai/tests/api/operations/test_syncs.py +6 -4
  463. mage_ai/tests/api/resources/test_pipeline_resource.py +9 -2
  464. mage_ai/tests/authentication/providers/test_oidc.py +59 -0
  465. mage_ai/tests/base_test.py +2 -2
  466. mage_ai/tests/data/__init__.py +0 -0
  467. mage_ai/tests/data/models/__init__.py +0 -0
  468. mage_ai/tests/data_preparation/executors/test_block_executor.py +23 -16
  469. mage_ai/tests/data_preparation/git/test_git.py +4 -1
  470. mage_ai/tests/data_preparation/models/block/dynamic/test_combos.py +305 -0
  471. mage_ai/tests/data_preparation/models/block/dynamic/test_counter.py +212 -0
  472. mage_ai/tests/data_preparation/models/block/dynamic/test_factory.py +360 -0
  473. mage_ai/tests/data_preparation/models/block/dynamic/test_variables.py +332 -0
  474. mage_ai/tests/data_preparation/models/block/hook/test_hook_block.py +2 -2
  475. mage_ai/tests/data_preparation/models/block/platform/test_mixins.py +1 -1
  476. mage_ai/tests/data_preparation/models/block/sql/utils/test_shared.py +26 -1
  477. mage_ai/tests/data_preparation/models/block/test_global_data_product.py +3 -2
  478. mage_ai/tests/data_preparation/models/custom_templates/test_utils.py +5 -4
  479. mage_ai/tests/data_preparation/models/global_hooks/test_hook.py +3 -0
  480. mage_ai/tests/data_preparation/models/global_hooks/test_predicates.py +9 -3
  481. mage_ai/tests/data_preparation/models/test_block.py +115 -120
  482. mage_ai/tests/data_preparation/models/test_blocks_helper.py +114 -0
  483. mage_ai/tests/data_preparation/models/test_global_data_product.py +41 -24
  484. mage_ai/tests/data_preparation/models/test_pipeline.py +9 -6
  485. mage_ai/tests/data_preparation/models/test_project.py +4 -1
  486. mage_ai/tests/data_preparation/models/test_utils.py +80 -0
  487. mage_ai/tests/data_preparation/models/test_variable.py +242 -69
  488. mage_ai/tests/data_preparation/models/variables/__init__.py +0 -0
  489. mage_ai/tests/data_preparation/models/variables/test_summarizer.py +481 -0
  490. mage_ai/tests/data_preparation/storage/shared/__init__.py +0 -0
  491. mage_ai/tests/data_preparation/test_repo_manager.py +6 -7
  492. mage_ai/tests/data_preparation/test_variable_manager.py +57 -48
  493. mage_ai/tests/factory.py +64 -43
  494. mage_ai/tests/orchestration/db/models/test_schedules.py +3 -3
  495. mage_ai/tests/orchestration/db/models/test_schedules_dynamic_blocks.py +279 -0
  496. mage_ai/tests/orchestration/test_pipeline_scheduler.py +1 -0
  497. mage_ai/tests/orchestration/triggers/test_global_data_product.py +3 -2
  498. mage_ai/tests/orchestration/triggers/test_utils.py +3 -2
  499. mage_ai/tests/services/k8s/test_job_manager.py +18 -0
  500. mage_ai/tests/streaming/sinks/test_oracledb.py +38 -0
  501. mage_ai/tests/test_shared.py +61 -0
  502. mage_ai/usage_statistics/logger.py +7 -2
  503. mage_ai/utils/code.py +33 -19
  504. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/METADATA +5 -2
  505. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/RECORD +513 -417
  506. mage_ai/data_preparation/models/global_data_product/constants.py +0 -6
  507. mage_ai/server/frontend_dist/_next/static/RhDiJSkcjCsh4xxX4BFBk/_buildManifest.js +0 -1
  508. mage_ai/server/frontend_dist/_next/static/chunks/2631-b9f9bea3f1cf906d.js +0 -1
  509. mage_ai/server/frontend_dist/_next/static/chunks/3782-ef4cd4f0b52072d0.js +0 -1
  510. mage_ai/server/frontend_dist/_next/static/chunks/4783-422429203610c318.js +0 -1
  511. mage_ai/server/frontend_dist/_next/static/chunks/5699-6d708c6b2153ea08.js +0 -1
  512. mage_ai/server/frontend_dist/_next/static/chunks/635-0d6b7c8804bcd2dc.js +0 -1
  513. mage_ai/server/frontend_dist/_next/static/chunks/7022-0d52dd8868621fb0.js +0 -1
  514. mage_ai/server/frontend_dist/_next/static/chunks/7361-8a23dd8360593e7a.js +0 -1
  515. mage_ai/server/frontend_dist/_next/static/chunks/7966-b9b85ba10667e654.js +0 -1
  516. mage_ai/server/frontend_dist/_next/static/chunks/8095-bdce03896ef9639a.js +0 -1
  517. mage_ai/server/frontend_dist/_next/static/chunks/8146-6bed4e7401e067e6.js +0 -1
  518. mage_ai/server/frontend_dist/_next/static/chunks/9265-d2a1aaec75ec69b8.js +0 -1
  519. mage_ai/server/frontend_dist/_next/static/chunks/9440-4069842b90d4b801.js +0 -1
  520. mage_ai/server/frontend_dist/_next/static/chunks/9832-67896490f6e8a014.js +0 -1
  521. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-2a69553d8c6eeb53.js +0 -1
  522. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-591abd392dc50ed4.js +0 -1
  523. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products-78e8e88f2a757a18.js +0 -1
  524. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-95ffcd3e2b27e567.js +0 -1
  525. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-b645a6d13ab9fe3a.js +0 -1
  526. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-1ed9045b2f1dfd65.js +0 -1
  527. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.js +0 -1
  528. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +0 -1
  529. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-349af617d05f001b.js +0 -1
  530. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-36fa165a48af586b.js +0 -1
  531. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-60d01d3887e31136.js +0 -1
  532. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-3433c8b22e8342aa.js +0 -1
  533. mage_ai/server/frontend_dist_base_path_template/_next/static/TdpLLFome13qvM0gXvpHs/_buildManifest.js +0 -1
  534. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2631-b9f9bea3f1cf906d.js +0 -1
  535. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-ef4cd4f0b52072d0.js +0 -1
  536. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4783-422429203610c318.js +0 -1
  537. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-6d708c6b2153ea08.js +0 -1
  538. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/635-0d6b7c8804bcd2dc.js +0 -1
  539. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-0d52dd8868621fb0.js +0 -1
  540. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-8a23dd8360593e7a.js +0 -1
  541. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-b9b85ba10667e654.js +0 -1
  542. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-bdce03896ef9639a.js +0 -1
  543. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-6bed4e7401e067e6.js +0 -1
  544. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9265-d2a1aaec75ec69b8.js +0 -1
  545. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-4069842b90d4b801.js +0 -1
  546. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9832-67896490f6e8a014.js +0 -1
  547. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-2a69553d8c6eeb53.js +0 -1
  548. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-591abd392dc50ed4.js +0 -1
  549. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products-78e8e88f2a757a18.js +0 -1
  550. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-95ffcd3e2b27e567.js +0 -1
  551. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-b645a6d13ab9fe3a.js +0 -1
  552. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-1ed9045b2f1dfd65.js +0 -1
  553. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.js +0 -1
  554. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +0 -1
  555. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-349af617d05f001b.js +0 -1
  556. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-36fa165a48af586b.js +0 -1
  557. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-60d01d3887e31136.js +0 -1
  558. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-3433c8b22e8342aa.js +0 -1
  559. mage_ai/shared/memory.py +0 -90
  560. mage_ai/tests/data_preparation/models/block/dynamic/test_dynamic_helpers.py +0 -48
  561. /mage_ai/{tests/data_preparation/shared → ai/utils}/__init__.py +0 -0
  562. /mage_ai/server/frontend_dist/_next/static/{RhDiJSkcjCsh4xxX4BFBk → UZLabyPgcxtZvp0O0EUUS}/_ssgManifest.js +0 -0
  563. /mage_ai/server/frontend_dist_base_path_template/_next/static/{TdpLLFome13qvM0gXvpHs → kcptwoOU-JJJg6Vwpkfmx}/_ssgManifest.js +0 -0
  564. /mage_ai/tests/data_preparation/{shared → storage/shared}/test_secrets.py +0 -0
  565. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/LICENSE +0 -0
  566. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/WHEEL +0 -0
  567. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/entry_points.txt +0 -0
  568. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/top_level.txt +0 -0
@@ -2,7 +2,7 @@ import asyncio
2
2
  import json
3
3
  import traceback
4
4
  from datetime import datetime, timedelta
5
- from typing import Callable, Dict, List, Union
5
+ from typing import Callable, Dict, List, Optional, Union
6
6
 
7
7
  import pytz
8
8
  import requests
@@ -22,7 +22,8 @@ from mage_ai.data_preparation.models.block.data_integration.utils import (
22
22
  source_module_file_path,
23
23
  )
24
24
  from mage_ai.data_preparation.models.block.dynamic.child import DynamicChildController
25
- from mage_ai.data_preparation.models.block.dynamic.utils import (
25
+ from mage_ai.data_preparation.models.block.dynamic.factory import DynamicBlockFactory
26
+ from mage_ai.data_preparation.models.block.dynamic.shared import (
26
27
  is_dynamic_block,
27
28
  is_dynamic_block_child,
28
29
  should_reduce_output,
@@ -58,8 +59,8 @@ class BlockExecutor:
58
59
  self,
59
60
  pipeline,
60
61
  block_uuid,
61
- execution_partition: str = None,
62
- block_run_id: int = None,
62
+ execution_partition: Optional[str] = None,
63
+ block_run_id: Optional[int] = None,
63
64
  ):
64
65
  """
65
66
  Initialize the BlockExecutor.
@@ -80,26 +81,27 @@ class BlockExecutor:
80
81
  repo_path=self.pipeline.repo_path,
81
82
  )
82
83
  self.logger = DictLogger(self.logger_manager.logger)
83
- self.project = Project(self.pipeline.repo_config)
84
+ self.project = Project(repo_config=self.pipeline.repo_config)
84
85
  self.retry_metadata = dict(attempts=0)
85
86
 
86
87
  self.block = self.pipeline.get_block(self.block_uuid, check_template=True)
87
-
88
- if self.block and \
89
- is_dynamic_block_child(self.block) and \
90
- (
91
- self.block.uuid == block_uuid or (
92
- self.block.replicated_block and self.block.uuid_replicated == block_uuid
93
- )
94
- ):
95
-
96
- self.block = DynamicChildController(
97
- self.block,
98
- block_run_id=block_run_id,
99
- )
100
-
101
88
  self.block_run = None
102
89
 
90
+ # Ensure the original block run is wrapped only, not the clones.
91
+ if self.block is not None and self.block.is_original_block(block_uuid):
92
+ if self.block.is_dynamic_child_streaming:
93
+ self.block = DynamicBlockFactory(
94
+ self.block,
95
+ block_run_id=block_run_id,
96
+ execution_partition=execution_partition,
97
+ logger=self.logger,
98
+ )
99
+ elif is_dynamic_block_child(self.block):
100
+ self.block = DynamicChildController(
101
+ self.block,
102
+ block_run_id=block_run_id,
103
+ )
104
+
103
105
  def execute(
104
106
  self,
105
107
  analyze_outputs: bool = False,
@@ -153,9 +155,12 @@ class BlockExecutor:
153
155
  global_vars = {}
154
156
  block_run = None
155
157
 
156
- if Project.is_feature_enabled_in_root_or_active_project(
157
- FeatureUUID.GLOBAL_HOOKS,
158
- ) and not self.block:
158
+ if (
159
+ Project.is_feature_enabled_in_root_or_active_project(
160
+ FeatureUUID.GLOBAL_HOOKS,
161
+ )
162
+ and not self.block
163
+ ):
159
164
  block_run = BlockRun.query.get(block_run_id) if block_run_id else None
160
165
  self.block_run = block_run
161
166
  if block_run and block_run.metrics and block_run.metrics.get('hook'):
@@ -183,9 +188,7 @@ class BlockExecutor:
183
188
  result = dict()
184
189
 
185
190
  tags = self.build_tags(
186
- block_run_id=block_run_id,
187
- pipeline_run_id=pipeline_run_id,
188
- **kwargs
191
+ block_run_id=block_run_id, pipeline_run_id=pipeline_run_id, **kwargs
189
192
  )
190
193
 
191
194
  self.logger.logging_tags = tags
@@ -252,12 +255,14 @@ class BlockExecutor:
252
255
  end_date = (execution_date).isoformat()
253
256
  start_date = (execution_date - date_diff).isoformat()
254
257
 
255
- runtime_arguments.update(dict(
256
- _end_date=end_date,
257
- _execution_date=execution_date.isoformat(),
258
- _execution_partition=pipeline_run.execution_partition,
259
- _start_date=start_date,
260
- ))
258
+ runtime_arguments.update(
259
+ dict(
260
+ _end_date=end_date,
261
+ _execution_date=execution_date.isoformat(),
262
+ _execution_partition=pipeline_run.execution_partition,
263
+ _start_date=start_date,
264
+ )
265
+ )
261
266
 
262
267
  if block_run and block_run.metrics and is_data_integration:
263
268
  data_integration_metadata = block_run.metrics
@@ -283,8 +288,9 @@ class BlockExecutor:
283
288
  'parent_stream',
284
289
  ]:
285
290
  if key in data_integration_metadata:
286
- self.block.template_runtime_configuration[key] = \
291
+ self.block.template_runtime_configuration[key] = (
287
292
  data_integration_metadata.get(key)
293
+ )
288
294
 
289
295
  if not is_data_integration_controller or is_data_integration_child:
290
296
  self.logger.info(f'Start executing block with {self.__class__.__name__}.', **tags)
@@ -298,7 +304,8 @@ class BlockExecutor:
298
304
  # This is used when there are 2 or more upstream dynamic blocks or dynamic childs.
299
305
  dynamic_block_indexes = block_run_data.get('dynamic_block_indexes', None)
300
306
  dynamic_upstream_block_uuids = block_run_data.get(
301
- 'dynamic_upstream_block_uuids', None)
307
+ 'dynamic_upstream_block_uuids', None
308
+ )
302
309
 
303
310
  # 2023/12/12 (tommy dang): this doesn’t seem to be used anymore because the
304
311
  # fetching the reduce output from upstream dynamic child blocks is handled in
@@ -328,11 +335,12 @@ class BlockExecutor:
328
335
  # We currently limit a block to only have 1 direct dynamic parent.
329
336
  # We are looping over the upstream blocks just in case we support having
330
337
  # multiple direct dynamic parents.
331
- for block_grandparent in list(filter(
332
- lambda x: is_dynamic_block(x),
333
- upstream_block.upstream_blocks,
334
- )):
335
-
338
+ for block_grandparent in list(
339
+ filter(
340
+ lambda x: is_dynamic_block(x),
341
+ upstream_block.upstream_blocks,
342
+ )
343
+ ):
336
344
  block_grandparent_uuid = block_grandparent.uuid
337
345
 
338
346
  if suffix and is_dynamic_block_child(block_grandparent):
@@ -356,15 +364,23 @@ class BlockExecutor:
356
364
  metadata,
357
365
  idx,
358
366
  upstream_block_uuid=block_grandparent_uuid,
359
- ))
367
+ )
368
+ )
360
369
 
361
- dynamic_upstream_block_uuids = dynamic_upstream_block_uuids_reduce + \
362
- dynamic_upstream_block_uuids_no_reduce
370
+ dynamic_upstream_block_uuids = (
371
+ dynamic_upstream_block_uuids_reduce + dynamic_upstream_block_uuids_no_reduce
372
+ )
363
373
 
364
374
  should_run_conditional = True
365
375
 
366
376
  if is_dynamic_block_child(self.block):
367
- if self.block_run and self.block_run.block_uuid == self.block.uuid:
377
+ if self.block_run and (
378
+ self.block_run.block_uuid == self.block.uuid
379
+ or (
380
+ self.block.replicated_block
381
+ and self.block_run.block_uuid == self.block.uuid_replicated
382
+ )
383
+ ):
368
384
  should_run_conditional = False
369
385
 
370
386
  if should_run_conditional:
@@ -382,10 +398,13 @@ class BlockExecutor:
382
398
  self.logger.info(
383
399
  f'Conditional block(s) returned false for {self.block.uuid}. '
384
400
  'This block run and downstream blocks will be set as CONDITION_FAILED.',
385
- **merge_dict(tags, dict(
386
- block_type=self.block.type,
387
- block_uuid=self.block.uuid,
388
- )),
401
+ **merge_dict(
402
+ tags,
403
+ dict(
404
+ block_type=self.block.type,
405
+ block_uuid=self.block.uuid,
406
+ ),
407
+ ),
389
408
  )
390
409
 
391
410
  if is_data_integration:
@@ -459,16 +478,20 @@ class BlockExecutor:
459
478
  self.logger.info(
460
479
  'All child block runs completed, updating controller block run '
461
480
  f'for block {controller_block_uuid} to complete.',
462
- **merge_dict(tags, dict(
463
- block_uuid=self.block.uuid,
464
- controller_block_uuid=controller_block_uuid,
465
- )),
481
+ **merge_dict(
482
+ tags,
483
+ dict(
484
+ block_uuid=self.block.uuid,
485
+ controller_block_uuid=controller_block_uuid,
486
+ ),
487
+ ),
466
488
  )
467
489
  should_execute = False
468
- elif is_data_integration_controller and \
469
- is_data_integration_child and not \
470
- run_in_parallel:
471
-
490
+ elif (
491
+ is_data_integration_controller
492
+ and is_data_integration_child
493
+ and not run_in_parallel
494
+ ):
472
495
  children = []
473
496
  status_count = {}
474
497
  block_run_dicts_mapping = {}
@@ -493,10 +516,14 @@ class BlockExecutor:
493
516
  # Only update the child controller (for a specific stream) to complete
494
517
  # if all its child block runs are complete (only for source).
495
518
  children_length = len(children)
496
- should_finish = children_length >= 1 and status_count.get(
497
- BlockRun.BlockRunStatus.COMPLETED.value,
498
- 0,
499
- ) >= children_length
519
+ should_finish = (
520
+ children_length >= 1
521
+ and status_count.get(
522
+ BlockRun.BlockRunStatus.COMPLETED.value,
523
+ 0,
524
+ )
525
+ >= children_length
526
+ )
500
527
 
501
528
  if upstream_block_uuids:
502
529
  statuses_completed = []
@@ -504,7 +531,8 @@ class BlockExecutor:
504
531
  block_run_dict = block_run_dicts_mapping.get(up_block_uuid)
505
532
  if block_run_dict:
506
533
  statuses_completed.append(
507
- BlockRun.BlockRunStatus.COMPLETED.value == block_run_dict.get(
534
+ BlockRun.BlockRunStatus.COMPLETED.value
535
+ == block_run_dict.get(
508
536
  'status',
509
537
  ),
510
538
  )
@@ -530,26 +558,31 @@ class BlockExecutor:
530
558
  continue
531
559
 
532
560
  # Same controller
533
- if controller_block_uuid == metrics.get('controller_block_uuid') and \
534
- index - 1 == int(metrics.get('index') or 0):
535
-
561
+ if controller_block_uuid == metrics.get(
562
+ 'controller_block_uuid'
563
+ ) and index - 1 == int(metrics.get('index') or 0):
536
564
  block_run_dict_previous = block_run_dict
537
565
 
538
566
  if block_run_dict_previous:
539
- should_execute = BlockRun.BlockRunStatus.COMPLETED.value == \
540
- block_run_dict_previous.get('status')
567
+ should_execute = (
568
+ BlockRun.BlockRunStatus.COMPLETED.value
569
+ == block_run_dict_previous.get('status')
570
+ )
541
571
 
542
572
  if not should_execute:
543
573
  stream = data_integration_metadata.get('stream')
544
574
  self.logger.info(
545
575
  f'Block run ({block_run_id}) {self.block_uuid} for stream {stream} '
546
576
  f'and batch {index} is waiting for batch {index - 1} to complete.',
547
- **merge_dict(tags, dict(
548
- batch=index - 1,
549
- block_uuid=self.block.uuid,
550
- controller_block_uuid=controller_block_uuid,
551
- index=index,
552
- )),
577
+ **merge_dict(
578
+ tags,
579
+ dict(
580
+ batch=index - 1,
581
+ block_uuid=self.block.uuid,
582
+ controller_block_uuid=controller_block_uuid,
583
+ index=index,
584
+ ),
585
+ ),
553
586
  )
554
587
 
555
588
  return
@@ -601,7 +634,8 @@ class BlockExecutor:
601
634
  template_runtime_configuration=template_runtime_configuration,
602
635
  dynamic_block_index=dynamic_block_index,
603
636
  dynamic_block_indexes=dynamic_block_indexes,
604
- dynamic_block_uuid=None if dynamic_block_index is None
637
+ dynamic_block_uuid=None
638
+ if dynamic_block_index is None
605
639
  else block_run.block_uuid,
606
640
  dynamic_upstream_block_uuids=dynamic_upstream_block_uuids,
607
641
  data_integration_metadata=data_integration_metadata,
@@ -614,9 +648,12 @@ class BlockExecutor:
614
648
  except Exception as error:
615
649
  self.logger.exception(
616
650
  f'Failed to execute block {self.block.uuid}',
617
- **merge_dict(tags, dict(
618
- error=error,
619
- )),
651
+ **merge_dict(
652
+ tags,
653
+ dict(
654
+ error=error,
655
+ ),
656
+ ),
620
657
  )
621
658
 
622
659
  errors = traceback.format_stack()
@@ -627,15 +664,19 @@ class BlockExecutor:
627
664
  )
628
665
 
629
666
  if not skip_logging:
630
- asyncio.run(UsageStatisticLogger().error(
631
- event_name=EventNameType.BLOCK_RUN_ERROR,
632
- errors='\n'.join(errors or []),
633
- message=str(error),
634
- resource=EventObjectType.BLOCK_RUN,
635
- resource_id=self.block_uuid,
636
- resource_parent=EventObjectType.PIPELINE if self.pipeline else None,
637
- resource_parent_id=self.pipeline.uuid if self.pipeline else None,
638
- ))
667
+ asyncio.run(
668
+ UsageStatisticLogger().error(
669
+ event_name=EventNameType.BLOCK_RUN_ERROR,
670
+ errors='\n'.join(errors or []),
671
+ message=str(error),
672
+ resource=EventObjectType.BLOCK_RUN,
673
+ resource_id=self.block_uuid,
674
+ resource_parent=EventObjectType.PIPELINE
675
+ if self.pipeline
676
+ else None,
677
+ resource_parent_id=self.pipeline.uuid if self.pipeline else None,
678
+ )
679
+ )
639
680
 
640
681
  if on_failure is not None:
641
682
  on_failure(
@@ -665,8 +706,9 @@ class BlockExecutor:
665
706
  raise error
666
707
 
667
708
  if not should_finish:
668
- should_finish = not is_data_integration_controller or \
669
- (is_data_integration_child and run_in_parallel)
709
+ should_finish = not is_data_integration_controller or (
710
+ is_data_integration_child and run_in_parallel
711
+ )
670
712
 
671
713
  # Destination must complete immediately or else it’ll keep trying to
672
714
  # convert its upstream blocks’ (that aren’t sources) data to Singer Spec output.
@@ -674,9 +716,14 @@ class BlockExecutor:
674
716
  # If this child controller continues to convert the data while the child block run
675
717
  # is ingesting the data, there will be a mismatch of records.
676
718
  if not should_finish:
677
- should_finish = is_data_integration_controller and \
678
- is_data_integration_child and \
679
- self.block.is_destination()
719
+ should_finish = (
720
+ is_data_integration_controller
721
+ and is_data_integration_child
722
+ and self.block.is_destination()
723
+ )
724
+
725
+ if isinstance(self.block, DynamicBlockFactory):
726
+ should_finish = self.block.is_complete()
680
727
 
681
728
  if should_finish:
682
729
  self.logger.info(f'Finish executing block with {self.__class__.__name__}.', **tags)
@@ -712,6 +759,11 @@ class BlockExecutor:
712
759
  pipeline_run=pipeline_run,
713
760
  )
714
761
 
762
+ from mage_ai.settings.server import VARIABLE_DATA_OUTPUT_META_CACHE
763
+
764
+ if VARIABLE_DATA_OUTPUT_META_CACHE:
765
+ self.block.aggregate_summary_info(execution_partition=self.execution_partition)
766
+
715
767
  return result
716
768
  finally:
717
769
  # The code below causes error when running blocks in pipeline_executor
@@ -808,16 +860,18 @@ class BlockExecutor:
808
860
  # This is required or else loading the module within the block execute
809
861
  # method will create very large log files that compound. Not sure why,
810
862
  # so this is the temp fix.
811
- data_integration_uuid = \
812
- data_integration_settings.get('data_integration_uuid')
863
+ data_integration_uuid = data_integration_settings.get(
864
+ 'data_integration_uuid'
865
+ )
813
866
 
814
867
  if data_integration_uuid:
815
868
  if 'data_integration_runtime_settings' not in extra_options:
816
869
  extra_options['data_integration_runtime_settings'] = {}
817
870
 
818
- if 'module_file_paths' not in \
819
- extra_options['data_integration_runtime_settings']:
820
-
871
+ if (
872
+ 'module_file_paths'
873
+ not in extra_options['data_integration_runtime_settings']
874
+ ):
821
875
  extra_options['data_integration_runtime_settings'][
822
876
  'module_file_paths'
823
877
  ] = dict(
@@ -832,11 +886,12 @@ class BlockExecutor:
832
886
  key = 'destinations'
833
887
  file_path_func = destination_module_file_path
834
888
 
835
- if data_integration_uuid not in \
836
- extra_options['data_integration_runtime_settings'][
837
- 'module_file_paths'
838
- ][key]:
839
-
889
+ if (
890
+ data_integration_uuid
891
+ not in extra_options['data_integration_runtime_settings'][
892
+ 'module_file_paths'
893
+ ][key]
894
+ ):
840
895
  extra_options['data_integration_runtime_settings'][
841
896
  'module_file_paths'
842
897
  ][key][data_integration_uuid] = file_path_func(
@@ -862,11 +917,12 @@ class BlockExecutor:
862
917
  if execution_partition_previous:
863
918
  extra_options['execution_partition_previous'] = execution_partition_previous
864
919
 
865
- if di_settings and \
866
- data_integration_metadata and \
867
- data_integration_metadata.get('controller') and \
868
- data_integration_metadata.get('original_block_uuid'):
869
-
920
+ if (
921
+ di_settings
922
+ and data_integration_metadata
923
+ and data_integration_metadata.get('controller')
924
+ and data_integration_metadata.get('original_block_uuid')
925
+ ):
870
926
  original_block_uuid = data_integration_metadata.get('original_block_uuid')
871
927
 
872
928
  # This is the source/destination controller block run
@@ -902,31 +958,38 @@ class BlockExecutor:
902
958
  for br_metadata in block_run_metadata:
903
959
  index = br_metadata.get('index') or 0
904
960
  number_of_batches = br_metadata.get('number_of_batches') or 0
905
- block_run_block_uuid = \
961
+ block_run_block_uuid = (
906
962
  f'{original_block_uuid}:{data_integration_uuid}:{stream}:{index}'
963
+ )
907
964
 
908
965
  if block_run_block_uuid not in block_run_block_uuids:
909
966
  br = pipeline_run.create_block_run(
910
967
  block_run_block_uuid,
911
- metrics=merge_dict(dict(
912
- child=1,
913
- controller_block_uuid=self.block_uuid,
914
- is_last_block_run=index == number_of_batches - 1,
915
- original_block_uuid=original_block_uuid,
916
- stream=stream,
917
- ), br_metadata),
968
+ metrics=merge_dict(
969
+ dict(
970
+ child=1,
971
+ controller_block_uuid=self.block_uuid,
972
+ is_last_block_run=index == number_of_batches - 1,
973
+ original_block_uuid=original_block_uuid,
974
+ stream=stream,
975
+ ),
976
+ br_metadata,
977
+ ),
918
978
  )
919
979
 
920
980
  self.logger.info(
921
981
  f'Created block run {br.id} for block {br.block_uuid} in batch '
922
982
  f'index {index} ({index + 1} out of {number_of_batches}).',
923
- **merge_dict(logging_tags, dict(
924
- data_integration_uuid=data_integration_uuid,
925
- index=index,
926
- number_of_batches=number_of_batches,
927
- original_block_uuid=original_block_uuid,
928
- stream=stream,
929
- )),
983
+ **merge_dict(
984
+ logging_tags,
985
+ dict(
986
+ data_integration_uuid=data_integration_uuid,
987
+ index=index,
988
+ number_of_batches=number_of_batches,
989
+ original_block_uuid=original_block_uuid,
990
+ stream=stream,
991
+ ),
992
+ ),
930
993
  )
931
994
 
932
995
  arr.append(br)
@@ -955,14 +1018,17 @@ class BlockExecutor:
955
1018
  if block_run_block_uuid not in block_run_block_uuids:
956
1019
  return dict(
957
1020
  block_uuid=block_run_block_uuid,
958
- metrics=merge_dict(dict(
959
- child=1,
960
- controller=1,
961
- controller_block_uuid=controller_block_uuid,
962
- original_block_uuid=original_block_uuid,
963
- run_in_parallel=1 if run_in_parallel else 0,
964
- stream=stream,
965
- ), metrics or {}),
1021
+ metrics=merge_dict(
1022
+ dict(
1023
+ child=1,
1024
+ controller=1,
1025
+ controller_block_uuid=controller_block_uuid,
1026
+ original_block_uuid=original_block_uuid,
1027
+ run_in_parallel=1 if run_in_parallel else 0,
1028
+ stream=stream,
1029
+ ),
1030
+ metrics or {},
1031
+ ),
966
1032
  )
967
1033
 
968
1034
  if is_source:
@@ -1005,11 +1071,16 @@ class BlockExecutor:
1005
1071
  execution_partition=self.execution_partition,
1006
1072
  )
1007
1073
  for stream_id in output_file_path_by_stream.keys():
1008
- stream_dict = get_streams_from_catalog(catalog, [stream_id])
1074
+ stream_dict = get_streams_from_catalog(
1075
+ catalog, [stream_id]
1076
+ )
1009
1077
  if stream_dict:
1010
- run_in_parallel = stream_dict[0].get(
1011
- 'run_in_parallel',
1012
- ) or False
1078
+ run_in_parallel = (
1079
+ stream_dict[0].get(
1080
+ 'run_in_parallel',
1081
+ )
1082
+ or False
1083
+ )
1013
1084
 
1014
1085
  block_dict = _build_controller_block_run_dict(
1015
1086
  stream_id,
@@ -1023,15 +1094,18 @@ class BlockExecutor:
1023
1094
  else:
1024
1095
  stream_dict = get_streams_from_catalog(catalog, [up_uuid])
1025
1096
  if stream_dict:
1026
- run_in_parallel = stream_dict[0].get(
1027
- 'run_in_parallel',
1028
- ) or False
1097
+ run_in_parallel = (
1098
+ stream_dict[0].get(
1099
+ 'run_in_parallel',
1100
+ )
1101
+ or False
1102
+ )
1029
1103
 
1030
1104
  block_dict = _build_controller_block_run_dict(
1031
1105
  up_uuid,
1032
1106
  metrics=dict(
1033
1107
  run_in_parallel=run_in_parallel,
1034
- )
1108
+ ),
1035
1109
  )
1036
1110
  if block_dict:
1037
1111
  block_run_dicts.append(block_dict)
@@ -1063,11 +1137,14 @@ class BlockExecutor:
1063
1137
  self.logger.info(
1064
1138
  f'Created block run {br.id} for block {br.block_uuid} '
1065
1139
  f'for stream {stream} {metrics}.',
1066
- **merge_dict(logging_tags, dict(
1067
- data_integration_uuid=data_integration_uuid,
1068
- original_block_uuid=original_block_uuid,
1069
- stream=stream,
1070
- )),
1140
+ **merge_dict(
1141
+ logging_tags,
1142
+ dict(
1143
+ data_integration_uuid=data_integration_uuid,
1144
+ original_block_uuid=original_block_uuid,
1145
+ stream=stream,
1146
+ ),
1147
+ ),
1071
1148
  )
1072
1149
 
1073
1150
  arr.append(br)
@@ -1102,8 +1179,9 @@ class BlockExecutor:
1102
1179
  logging_tags=logging_tags,
1103
1180
  outputs=result if cache_block_output_in_memory else None,
1104
1181
  )
1105
- elif PipelineType.INTEGRATION != self.pipeline.type and \
1106
- (not is_data_integration or BlockLanguage.PYTHON == self.block.language):
1182
+ elif PipelineType.INTEGRATION != self.pipeline.type and (
1183
+ not is_data_integration or BlockLanguage.PYTHON == self.block.language
1184
+ ):
1107
1185
  self.block.run_tests(
1108
1186
  execution_partition=self.execution_partition,
1109
1187
  global_vars=global_vars,
@@ -1164,9 +1242,12 @@ class BlockExecutor:
1164
1242
  self.logger.exception(
1165
1243
  f'Failed to execute conditional block {conditional_block.uuid} '
1166
1244
  f'for block {self.block.uuid}.',
1167
- **merge_dict(logging_tags, dict(
1168
- error=conditional_err,
1169
- )),
1245
+ **merge_dict(
1246
+ logging_tags,
1247
+ dict(
1248
+ error=conditional_err,
1249
+ ),
1250
+ ),
1170
1251
  )
1171
1252
  result = False
1172
1253
 
@@ -1227,9 +1308,12 @@ class BlockExecutor:
1227
1308
  self.logger.exception(
1228
1309
  f'Failed to execute {callback} callback block {callback_block.uuid} '
1229
1310
  f'for block {self.block.uuid}.',
1230
- **merge_dict(logging_tags, dict(
1231
- error=callback_err,
1232
- )),
1311
+ **merge_dict(
1312
+ logging_tags,
1313
+ dict(
1314
+ error=callback_err,
1315
+ ),
1316
+ ),
1233
1317
  )
1234
1318
 
1235
1319
  def _run_commands(
@@ -1250,8 +1334,10 @@ class BlockExecutor:
1250
1334
  Returns:
1251
1335
  A list of command arguments.
1252
1336
  """
1253
- cmd = f'/app/run_app.sh ' \
1254
- f'mage run {self.pipeline.repo_config.repo_path} {self.pipeline.uuid}'
1337
+ cmd = (
1338
+ f'/app/run_app.sh '
1339
+ f'mage run {self.pipeline.repo_config.repo_path} {self.pipeline.uuid}'
1340
+ )
1255
1341
  options = [
1256
1342
  '--block-uuid',
1257
1343
  self.block_uuid,
@@ -1303,9 +1389,7 @@ class BlockExecutor:
1303
1389
  block_run_id = int(callback_url.split('/')[-1])
1304
1390
 
1305
1391
  block_run = BlockRun.query.get(block_run_id)
1306
- update_kwargs = dict(
1307
- status=status
1308
- )
1392
+ update_kwargs = dict(status=status)
1309
1393
 
1310
1394
  if status == BlockRun.BlockRunStatus.COMPLETED:
1311
1395
  update_kwargs['completed_at'] = datetime.now(tz=pytz.UTC)
@@ -1326,9 +1410,7 @@ class BlockExecutor:
1326
1410
  except Exception as err2:
1327
1411
  self.logger.exception(
1328
1412
  f'Failed to update block run status to {status} for block {self.block.uuid}.',
1329
- **merge_dict(tags, dict(
1330
- error=err2
1331
- )),
1413
+ **merge_dict(tags, dict(error=err2)),
1332
1414
  )
1333
1415
 
1334
1416
  block_run_data = dict(status=status)