mage-ai 0.9.58__py3-none-any.whl → 0.9.59__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 (682) hide show
  1. mage_ai/api/logging.py +11 -7
  2. mage_ai/api/policies/BlockPolicy.py +1 -0
  3. mage_ai/api/policies/CommandCenterItemPolicy.py +56 -0
  4. mage_ai/api/policies/CustomTemplatePolicy.py +0 -3
  5. mage_ai/api/policies/GitBranchPolicy.py +8 -1
  6. mage_ai/api/policies/GitFilePolicy.py +1 -0
  7. mage_ai/api/policies/PipelinePolicy.py +2 -0
  8. mage_ai/api/policies/PipelineSchedulePolicy.py +1 -0
  9. mage_ai/api/policies/VersionControlBranchPolicy.py +98 -0
  10. mage_ai/api/policies/VersionControlFilePolicy.py +96 -0
  11. mage_ai/api/policies/VersionControlProjectPolicy.py +92 -0
  12. mage_ai/api/policies/VersionControlRemotePolicy.py +94 -0
  13. mage_ai/api/presenters/CommandCenterItemPresenter.py +19 -0
  14. mage_ai/api/presenters/GitBranchPresenter.py +2 -0
  15. mage_ai/api/presenters/GitCustomBranchPresenter.py +1 -0
  16. mage_ai/api/presenters/PipelinePresenter.py +5 -5
  17. mage_ai/api/presenters/PipelineSchedulePresenter.py +4 -0
  18. mage_ai/api/presenters/VersionControlBranchPresenter.py +15 -0
  19. mage_ai/api/presenters/VersionControlFilePresenter.py +15 -0
  20. mage_ai/api/presenters/VersionControlProjectPresenter.py +14 -0
  21. mage_ai/api/presenters/VersionControlRemotePresenter.py +15 -0
  22. mage_ai/api/resources/BlockResource.py +110 -80
  23. mage_ai/api/resources/CommandCenterItemResource.py +29 -0
  24. mage_ai/api/resources/FileResource.py +15 -1
  25. mage_ai/api/resources/FolderResource.py +2 -1
  26. mage_ai/api/resources/GitBranchResource.py +183 -108
  27. mage_ai/api/resources/GitCustomBranchResource.py +9 -2
  28. mage_ai/api/resources/GitFileResource.py +26 -13
  29. mage_ai/api/resources/KernelResource.py +9 -1
  30. mage_ai/api/resources/LogResource.py +1 -1
  31. mage_ai/api/resources/OauthResource.py +4 -5
  32. mage_ai/api/resources/PipelineResource.py +71 -38
  33. mage_ai/api/resources/PipelineRunResource.py +7 -2
  34. mage_ai/api/resources/PullRequestResource.py +12 -3
  35. mage_ai/api/resources/SearchResultResource.py +4 -4
  36. mage_ai/api/resources/VersionControlBranchResource.py +85 -0
  37. mage_ai/api/resources/VersionControlFileResource.py +65 -0
  38. mage_ai/api/resources/VersionControlProjectResource.py +46 -0
  39. mage_ai/api/resources/VersionControlRemoteResource.py +64 -0
  40. mage_ai/authentication/oauth/constants.py +13 -16
  41. mage_ai/authentication/operation_history/models.py +11 -32
  42. mage_ai/authentication/operation_history/utils.py +14 -14
  43. mage_ai/authentication/permissions/constants.py +5 -0
  44. mage_ai/authentication/providers/active_directory.py +2 -2
  45. mage_ai/authentication/providers/bitbucket.py +2 -2
  46. mage_ai/authentication/providers/constants.py +6 -12
  47. mage_ai/authentication/providers/ghe.py +2 -2
  48. mage_ai/authentication/providers/google.py +2 -2
  49. mage_ai/authentication/providers/okta.py +2 -2
  50. mage_ai/cache/base.py +11 -3
  51. mage_ai/cache/block.py +116 -32
  52. mage_ai/cache/block_action_object/__init__.py +52 -43
  53. mage_ai/cache/constants.py +1 -0
  54. mage_ai/cache/file.py +114 -0
  55. mage_ai/cache/pipeline.py +34 -8
  56. mage_ai/cache/tag.py +51 -10
  57. mage_ai/cache/utils.py +44 -3
  58. mage_ai/cluster_manager/kubernetes/workload_manager.py +9 -1
  59. mage_ai/command_center/__init__.py +0 -0
  60. mage_ai/command_center/applications/__init__.py +0 -0
  61. mage_ai/command_center/applications/constants.py +96 -0
  62. mage_ai/command_center/applications/factory.py +54 -0
  63. mage_ai/command_center/blocks/__init__.py +0 -0
  64. mage_ai/command_center/blocks/factory.py +39 -0
  65. mage_ai/command_center/blocks/utils.py +127 -0
  66. mage_ai/command_center/constants.py +66 -0
  67. mage_ai/command_center/factory.py +161 -0
  68. mage_ai/command_center/files/__init__.py +0 -0
  69. mage_ai/command_center/files/constants.py +235 -0
  70. mage_ai/command_center/files/factory.py +86 -0
  71. mage_ai/command_center/models.py +442 -0
  72. mage_ai/command_center/pipeline_runs/__init__.py +0 -0
  73. mage_ai/command_center/pipeline_runs/utils.py +141 -0
  74. mage_ai/command_center/pipelines/__init__.py +0 -0
  75. mage_ai/command_center/pipelines/constants.py +118 -0
  76. mage_ai/command_center/pipelines/factory.py +132 -0
  77. mage_ai/command_center/pipelines/utils.py +120 -0
  78. mage_ai/command_center/service.py +45 -0
  79. mage_ai/command_center/settings.py +37 -0
  80. mage_ai/command_center/support/__init__.py +0 -0
  81. mage_ai/command_center/support/constants.py +46 -0
  82. mage_ai/command_center/triggers/__init__.py +0 -0
  83. mage_ai/command_center/triggers/factory.py +49 -0
  84. mage_ai/command_center/triggers/utils.py +463 -0
  85. mage_ai/command_center/utils.py +30 -0
  86. mage_ai/data_preparation/executors/azure_container_instance_executor.py +1 -1
  87. mage_ai/data_preparation/executors/block_executor.py +68 -19
  88. mage_ai/data_preparation/executors/ecs_block_executor.py +2 -2
  89. mage_ai/data_preparation/executors/executor_factory.py +2 -0
  90. mage_ai/data_preparation/executors/gcp_cloud_run_block_executor.py +1 -1
  91. mage_ai/data_preparation/executors/k8s_block_executor.py +2 -2
  92. mage_ai/data_preparation/executors/pyspark_block_executor.py +7 -1
  93. mage_ai/data_preparation/git/__init__.py +29 -11
  94. mage_ai/data_preparation/git/api.py +14 -13
  95. mage_ai/data_preparation/git/clients/base.py +4 -8
  96. mage_ai/data_preparation/git/clients/github.py +1 -0
  97. mage_ai/data_preparation/git/utils.py +5 -7
  98. mage_ai/data_preparation/models/block/__init__.py +556 -329
  99. mage_ai/data_preparation/models/block/content.py +111 -0
  100. mage_ai/data_preparation/models/block/data_integration/mixins.py +1 -0
  101. mage_ai/data_preparation/models/block/dbt/block.py +29 -19
  102. mage_ai/data_preparation/models/block/dbt/block_sql.py +50 -260
  103. mage_ai/data_preparation/models/block/dbt/block_yaml.py +74 -156
  104. mage_ai/data_preparation/models/block/dbt/dbt_adapter.py +22 -10
  105. mage_ai/data_preparation/models/block/dbt/profiles.py +19 -15
  106. mage_ai/data_preparation/models/block/dbt/project.py +3 -0
  107. mage_ai/data_preparation/models/block/dynamic/constants.py +0 -0
  108. mage_ai/data_preparation/models/block/dynamic/dynamic_child.py +507 -47
  109. mage_ai/data_preparation/models/block/dynamic/utils.py +432 -1
  110. mage_ai/data_preparation/models/block/platform/mixins.py +68 -44
  111. mage_ai/data_preparation/models/block/r/__init__.py +19 -9
  112. mage_ai/data_preparation/models/block/sql/__init__.py +34 -20
  113. mage_ai/data_preparation/models/block/sql/utils/shared.py +4 -1
  114. mage_ai/data_preparation/models/block/utils.py +176 -71
  115. mage_ai/data_preparation/models/constants.py +7 -0
  116. mage_ai/data_preparation/models/file.py +21 -2
  117. mage_ai/data_preparation/models/pipeline.py +20 -8
  118. mage_ai/data_preparation/models/project/__init__.py +12 -7
  119. mage_ai/data_preparation/models/project/constants.py +1 -0
  120. mage_ai/data_preparation/models/triggers/__init__.py +7 -0
  121. mage_ai/data_preparation/models/utils.py +20 -0
  122. mage_ai/data_preparation/models/variable.py +113 -15
  123. mage_ai/data_preparation/shared/utils.py +6 -3
  124. mage_ai/data_preparation/storage/base_storage.py +17 -0
  125. mage_ai/data_preparation/storage/gcs_storage.py +4 -0
  126. mage_ai/data_preparation/storage/local_storage.py +15 -0
  127. mage_ai/data_preparation/storage/s3_storage.py +4 -0
  128. mage_ai/data_preparation/templates/data_exporters/qdrant.py +0 -1
  129. mage_ai/data_preparation/templates/data_loaders/qdrant.py +2 -1
  130. mage_ai/data_preparation/variable_manager.py +1 -0
  131. mage_ai/io/base.py +4 -1
  132. mage_ai/io/bigquery.py +25 -16
  133. mage_ai/io/clickhouse.py +3 -0
  134. mage_ai/io/druid.py +3 -0
  135. mage_ai/io/mongodb.py +1 -1
  136. mage_ai/io/pinot.py +3 -0
  137. mage_ai/io/postgres.py +13 -0
  138. mage_ai/io/snowflake.py +4 -0
  139. mage_ai/io/spark.py +8 -3
  140. mage_ai/io/sql.py +6 -0
  141. mage_ai/orchestration/db/__init__.py +26 -19
  142. mage_ai/orchestration/db/cache.py +4 -3
  143. mage_ai/orchestration/db/models/schedules.py +72 -16
  144. mage_ai/orchestration/db/models/schedules_project_platform.py +2 -3
  145. mage_ai/orchestration/pipeline_scheduler_original.py +19 -11
  146. mage_ai/orchestration/pipeline_scheduler_project_platform.py +20 -11
  147. mage_ai/presenters/interactions/constants.py +1 -0
  148. mage_ai/presenters/interactions/models.py +4 -3
  149. mage_ai/presenters/pages/models/client_pages/pipeline_schedules.py +1 -1
  150. mage_ai/server/constants.py +1 -1
  151. mage_ai/server/frontend_dist/404.html +11 -11
  152. mage_ai/server/frontend_dist/_next/static/PPQxHOmWVJ0iQFzG2rc8m/_buildManifest.js +1 -0
  153. mage_ai/server/frontend_dist/_next/static/chunks/1235.c9ed47779baccc05.js +1 -0
  154. mage_ai/server/frontend_dist/_next/static/chunks/125-029194ff22eb33a5.js +1 -0
  155. mage_ai/server/frontend_dist/_next/static/chunks/1557-4f7485c2e2228f77.js +1 -0
  156. mage_ai/server/frontend_dist/_next/static/chunks/2474-8e702cea23ddd16d.js +1 -0
  157. mage_ai/server/frontend_dist/_next/static/chunks/2479-727fa69ee9be6fab.js +1 -0
  158. mage_ai/server/frontend_dist/_next/static/chunks/26-38bc9380422f3900.js +1 -0
  159. mage_ai/server/frontend_dist/_next/static/chunks/2717-3e7ea8543b3825b7.js +1 -0
  160. mage_ai/server/frontend_dist/_next/static/chunks/3366-420721116ea5a665.js +1 -0
  161. mage_ai/server/frontend_dist/_next/static/chunks/3449-a9c98239582cd6f0.js +1 -0
  162. mage_ai/server/frontend_dist/_next/static/chunks/3548-13563a1ff815f922.js +1 -0
  163. mage_ai/server/frontend_dist/_next/static/chunks/3943-9e0a8ba0db34b35f.js +1 -0
  164. mage_ai/server/frontend_dist/_next/static/chunks/4371-ef23f95888d6cd11.js +1 -0
  165. mage_ai/server/frontend_dist/_next/static/chunks/4632.a4171dbf46b31c7c.js +1 -0
  166. mage_ai/server/frontend_dist/_next/static/chunks/523-be11ad59861d00ca.js +1 -0
  167. mage_ai/server/frontend_dist/_next/static/chunks/5457-d582b00545b4cb5e.js +1 -0
  168. mage_ai/server/frontend_dist/_next/static/chunks/5831-2abc4063e887a03e.js +1 -0
  169. mage_ai/server/frontend_dist/_next/static/chunks/6085-692d2f784c0504f2.js +1 -0
  170. mage_ai/server/frontend_dist/_next/static/chunks/635-1e8857c2b6dde289.js +1 -0
  171. mage_ai/server/frontend_dist/_next/static/chunks/7022-0d52dd8868621fb0.js +1 -0
  172. mage_ai/server/frontend_dist/_next/static/chunks/7264-d05f4b7088533f6f.js +1 -0
  173. mage_ai/server/frontend_dist/_next/static/chunks/7361-b3d661ec743bfadf.js +1 -0
  174. mage_ai/server/frontend_dist/_next/static/chunks/737-cc6467310a130dd9.js +1 -0
  175. mage_ai/server/frontend_dist/_next/static/chunks/{4495-4f0340aa82e0c623.js → 7674-9ec4fe64b5bf64d5.js} +1 -1
  176. mage_ai/server/frontend_dist/_next/static/chunks/8038-85d715c8c8394827.js +1 -0
  177. mage_ai/server/frontend_dist/_next/static/chunks/8095-bdce03896ef9639a.js +1 -0
  178. mage_ai/server/frontend_dist/_next/static/chunks/8146-6bed4e7401e067e6.js +1 -0
  179. mage_ai/server/frontend_dist/_next/static/chunks/8192-0c0b91523a38c4ca.js +1 -0
  180. mage_ai/server/frontend_dist/_next/static/chunks/8432-f736d101fc6d9215.js +1 -0
  181. mage_ai/server/frontend_dist/_next/static/chunks/8513-d207733b485c8d03.js +1 -0
  182. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/9264-e7e040a54d34360c.js → frontend_dist/_next/static/chunks/9264-7cd9cd0ba86ec5e4.js} +1 -1
  183. mage_ai/server/frontend_dist/_next/static/chunks/9265-d2a1aaec75ec69b8.js +1 -0
  184. mage_ai/server/frontend_dist/_next/static/chunks/9440-54add041c392517f.js +1 -0
  185. mage_ai/server/frontend_dist/_next/static/chunks/9624-59b2f803f9c88cd6.js +1 -0
  186. mage_ai/server/frontend_dist/_next/static/chunks/9832-67896490f6e8a014.js +1 -0
  187. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/bd1a647f.fe5d87096be24a62.js → frontend_dist/_next/static/chunks/bd1a647f.04f7913662092327.js} +1 -1
  188. mage_ai/server/frontend_dist/_next/static/chunks/pages/404-7cabe357906f44f2.js +1 -0
  189. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-a11bd2ebe11b3fd2.js +1 -0
  190. mage_ai/server/frontend_dist/_next/static/chunks/pages/block-layout-ffca51945cd154ef.js +1 -0
  191. mage_ai/server/frontend_dist/_next/static/chunks/pages/compute-3ba957769292db80.js +1 -0
  192. mage_ai/server/frontend_dist/_next/static/chunks/pages/files-45679fd18b3edd82.js +1 -0
  193. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-95735a218106aa99.js +1 -0
  194. mage_ai/server/frontend_dist/_next/static/chunks/pages/{global-data-products-cf98c2e4d20fd92c.js → global-data-products-81d6c7fd9a9cff38.js} +1 -1
  195. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-eb4421d51fb7368f.js +1 -0
  196. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks-a8c712e20512fede.js +1 -0
  197. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/files-f1be1d4735ba6919.js +1 -0
  198. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-febe676687966276.js +1 -0
  199. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/[user]-70efe222130490b5.js +1 -0
  200. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-0914c36b3c8fd59f.js +1 -0
  201. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/{users-81e6e5319a59cd07.js → users-4f12e989e7809ef9.js} +1 -1
  202. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-809d4c99b44991a1.js +1 -0
  203. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/oauth-0436d395963cd27a.js → frontend_dist/_next/static/chunks/pages/oauth-aa9079c8dbaea3a5.js} +1 -1
  204. mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-4e30fb5b18383b71.js +1 -0
  205. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipeline-runs-5d31c3aace39182d.js +1 -0
  206. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-85a80ee66f60a65c.js +1 -0
  207. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-0bd74047e257e6d9.js +1 -0
  208. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-80619dc504d0103b.js +1 -0
  209. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-3cc8d74ff8525bfd.js +1 -0
  210. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-cdc379ff24ff8858.js +1 -0
  211. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-03396d6086003e16.js +1 -0
  212. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-d6d920758654f6d9.js +1 -0
  213. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-27727bb87be506c3.js +1 -0
  214. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-16aab67743651a0b.js +1 -0
  215. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-e3ca1bedb660b252.js +1 -0
  216. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-9d58701fe7213727.js +1 -0
  217. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-0041fd76ee15e49f.js +1 -0
  218. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-780be9a2da697915.js +1 -0
  219. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-db8bb970b1f2273f.js +1 -0
  220. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-a3422b0ab1dbacd7.js +1 -0
  221. mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks/[...slug]-987a1603f4201943.js +1 -0
  222. mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks-3dc8bf89cab2722b.js +1 -0
  223. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-43d3f2a5071b9537.js +1 -0
  224. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-c97b1a39b22c112a.js +1 -0
  225. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/settings-49efb66da67554ca.js +1 -0
  226. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-be6aaec07c138656.js → [...slug]-5117d3555972484c.js} +1 -1
  227. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions-ee1c19d4a192ae4d.js +1 -0
  228. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-4dc5724486ee3396.js +1 -0
  229. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-f380d293cff7592b.js → [...slug]-fa095aac732368c3.js} +1 -1
  230. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{roles-ddce04fae28bd7f6.js → roles-db6d71f8692a33e7.js} +1 -1
  231. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-99c6a263d2ab9553.js +1 -0
  232. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-213a43564fdfbe17.js → [...slug]-9d881ac0a3db9baa.js} +1 -1
  233. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users-bee414d57c4b55d7.js +1 -0
  234. mage_ai/server/frontend_dist/_next/static/chunks/pages/sign-in-e7030e1a7a9e88e1.js +1 -0
  235. mage_ai/server/frontend_dist/_next/static/chunks/pages/templates/[...slug]-312afc9a3f8d0a4f.js +1 -0
  236. mage_ai/server/frontend_dist/_next/static/chunks/pages/templates-e5300c340aa94c6b.js +1 -0
  237. mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-fa7ca0c86142d146.js +1 -0
  238. mage_ai/server/frontend_dist/_next/static/chunks/pages/test-bd51b3918b39329e.js +1 -0
  239. mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-5158a9d98d2459e8.js +1 -0
  240. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-5ce099a7abb354ff.js +1 -0
  241. mage_ai/server/frontend_dist/_next/static/chunks/{webpack-fea697dd168c6d0c.js → webpack-efa55343114c8128.js} +1 -1
  242. mage_ai/server/{frontend_dist_base_path_template/_next/static/css/d1e8e64d0b07af2f.css → frontend_dist/_next/static/css/b59541b123fd7191.css} +1 -1
  243. mage_ai/server/frontend_dist/block-layout.html +3 -3
  244. mage_ai/server/frontend_dist/compute.html +11 -11
  245. mage_ai/server/frontend_dist/files.html +11 -11
  246. mage_ai/server/frontend_dist/global-data-products/[...slug].html +11 -11
  247. mage_ai/server/frontend_dist/global-data-products.html +11 -11
  248. mage_ai/server/frontend_dist/global-hooks/[...slug].html +11 -11
  249. mage_ai/server/frontend_dist/global-hooks.html +11 -11
  250. mage_ai/server/frontend_dist/index.html +3 -3
  251. mage_ai/server/frontend_dist/manage/files.html +11 -11
  252. mage_ai/server/frontend_dist/manage/settings.html +11 -11
  253. mage_ai/server/frontend_dist/manage/users/[user].html +11 -11
  254. mage_ai/server/frontend_dist/manage/users/new.html +11 -11
  255. mage_ai/server/frontend_dist/manage/users.html +11 -11
  256. mage_ai/server/frontend_dist/manage.html +11 -11
  257. mage_ai/server/frontend_dist/oauth.html +8 -8
  258. mage_ai/server/frontend_dist/overview.html +11 -11
  259. mage_ai/server/frontend_dist/pipeline-runs.html +11 -11
  260. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +11 -11
  261. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +11 -11
  262. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +11 -11
  263. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +3 -3
  264. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +11 -11
  265. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +11 -11
  266. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +11 -11
  267. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +11 -11
  268. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +11 -11
  269. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +11 -11
  270. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +11 -11
  271. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +11 -11
  272. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +11 -11
  273. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +11 -11
  274. mage_ai/server/frontend_dist/pipelines/[pipeline].html +3 -3
  275. mage_ai/server/frontend_dist/pipelines.html +11 -11
  276. mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +11 -11
  277. mage_ai/server/frontend_dist/platform/global-hooks.html +11 -11
  278. mage_ai/server/frontend_dist/settings/account/profile.html +11 -11
  279. mage_ai/server/frontend_dist/settings/platform/preferences.html +11 -11
  280. mage_ai/server/frontend_dist/settings/platform/settings.html +11 -11
  281. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +11 -11
  282. mage_ai/server/frontend_dist/settings/workspace/permissions.html +11 -11
  283. mage_ai/server/frontend_dist/settings/workspace/preferences.html +11 -11
  284. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +11 -11
  285. mage_ai/server/frontend_dist/settings/workspace/roles.html +11 -11
  286. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +11 -11
  287. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +11 -11
  288. mage_ai/server/frontend_dist/settings/workspace/users.html +11 -11
  289. mage_ai/server/frontend_dist/settings.html +3 -3
  290. mage_ai/server/frontend_dist/sign-in.html +41 -41
  291. mage_ai/server/frontend_dist/templates/[...slug].html +11 -11
  292. mage_ai/server/frontend_dist/templates.html +11 -11
  293. mage_ai/server/frontend_dist/terminal.html +11 -11
  294. mage_ai/server/frontend_dist/test.html +3 -5
  295. mage_ai/server/frontend_dist/triggers.html +11 -11
  296. mage_ai/server/frontend_dist/version-control.html +11 -11
  297. mage_ai/server/frontend_dist_base_path_template/404.html +11 -11
  298. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1235.c9ed47779baccc05.js +1 -0
  299. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/125-029194ff22eb33a5.js +1 -0
  300. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-4f7485c2e2228f77.js +1 -0
  301. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2474-8e702cea23ddd16d.js +1 -0
  302. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2479-727fa69ee9be6fab.js +1 -0
  303. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/26-38bc9380422f3900.js +1 -0
  304. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2717-3e7ea8543b3825b7.js +1 -0
  305. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3366-420721116ea5a665.js +1 -0
  306. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3449-a9c98239582cd6f0.js +1 -0
  307. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3548-13563a1ff815f922.js +1 -0
  308. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3943-9e0a8ba0db34b35f.js +1 -0
  309. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4371-ef23f95888d6cd11.js +1 -0
  310. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4632.a4171dbf46b31c7c.js +1 -0
  311. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/523-be11ad59861d00ca.js +1 -0
  312. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-d582b00545b4cb5e.js +1 -0
  313. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5831-2abc4063e887a03e.js +1 -0
  314. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6085-692d2f784c0504f2.js +1 -0
  315. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/635-1e8857c2b6dde289.js +1 -0
  316. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-0d52dd8868621fb0.js +1 -0
  317. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7264-d05f4b7088533f6f.js +1 -0
  318. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-b3d661ec743bfadf.js +1 -0
  319. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/737-cc6467310a130dd9.js +1 -0
  320. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{4495-4f0340aa82e0c623.js → 7674-9ec4fe64b5bf64d5.js} +1 -1
  321. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8038-85d715c8c8394827.js +1 -0
  322. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-bdce03896ef9639a.js +1 -0
  323. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-6bed4e7401e067e6.js +1 -0
  324. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8192-0c0b91523a38c4ca.js +1 -0
  325. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8432-f736d101fc6d9215.js +1 -0
  326. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8513-d207733b485c8d03.js +1 -0
  327. mage_ai/server/{frontend_dist/_next/static/chunks/9264-e7e040a54d34360c.js → frontend_dist_base_path_template/_next/static/chunks/9264-7cd9cd0ba86ec5e4.js} +1 -1
  328. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9265-d2a1aaec75ec69b8.js +1 -0
  329. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-54add041c392517f.js +1 -0
  330. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9624-59b2f803f9c88cd6.js +1 -0
  331. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9832-67896490f6e8a014.js +1 -0
  332. mage_ai/server/{frontend_dist/_next/static/chunks/bd1a647f.fe5d87096be24a62.js → frontend_dist_base_path_template/_next/static/chunks/bd1a647f.04f7913662092327.js} +1 -1
  333. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/404-7cabe357906f44f2.js +1 -0
  334. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-a11bd2ebe11b3fd2.js +1 -0
  335. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/block-layout-ffca51945cd154ef.js +1 -0
  336. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/compute-3ba957769292db80.js +1 -0
  337. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-45679fd18b3edd82.js +1 -0
  338. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-95735a218106aa99.js +1 -0
  339. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{global-data-products-cf98c2e4d20fd92c.js → global-data-products-81d6c7fd9a9cff38.js} +1 -1
  340. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-eb4421d51fb7368f.js +1 -0
  341. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks-a8c712e20512fede.js +1 -0
  342. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/files-f1be1d4735ba6919.js +1 -0
  343. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-febe676687966276.js +1 -0
  344. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-70efe222130490b5.js +1 -0
  345. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-0914c36b3c8fd59f.js +1 -0
  346. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/{users-81e6e5319a59cd07.js → users-4f12e989e7809ef9.js} +1 -1
  347. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-809d4c99b44991a1.js +1 -0
  348. mage_ai/server/{frontend_dist/_next/static/chunks/pages/oauth-0436d395963cd27a.js → frontend_dist_base_path_template/_next/static/chunks/pages/oauth-aa9079c8dbaea3a5.js} +1 -1
  349. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-4e30fb5b18383b71.js +1 -0
  350. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-5d31c3aace39182d.js +1 -0
  351. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-85a80ee66f60a65c.js +1 -0
  352. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-0bd74047e257e6d9.js +1 -0
  353. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-80619dc504d0103b.js +1 -0
  354. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-3cc8d74ff8525bfd.js +1 -0
  355. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-cdc379ff24ff8858.js +1 -0
  356. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-03396d6086003e16.js +1 -0
  357. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-d6d920758654f6d9.js +1 -0
  358. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-27727bb87be506c3.js +1 -0
  359. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-16aab67743651a0b.js +1 -0
  360. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-e3ca1bedb660b252.js +1 -0
  361. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-9d58701fe7213727.js +1 -0
  362. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-0041fd76ee15e49f.js +1 -0
  363. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-780be9a2da697915.js +1 -0
  364. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-db8bb970b1f2273f.js +1 -0
  365. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-a3422b0ab1dbacd7.js +1 -0
  366. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks/[...slug]-987a1603f4201943.js +1 -0
  367. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks-3dc8bf89cab2722b.js +1 -0
  368. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-43d3f2a5071b9537.js +1 -0
  369. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-c97b1a39b22c112a.js +1 -0
  370. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-49efb66da67554ca.js +1 -0
  371. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-be6aaec07c138656.js → [...slug]-5117d3555972484c.js} +1 -1
  372. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions-ee1c19d4a192ae4d.js +1 -0
  373. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-4dc5724486ee3396.js +1 -0
  374. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-f380d293cff7592b.js → [...slug]-fa095aac732368c3.js} +1 -1
  375. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{roles-ddce04fae28bd7f6.js → roles-db6d71f8692a33e7.js} +1 -1
  376. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-99c6a263d2ab9553.js +1 -0
  377. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-213a43564fdfbe17.js → [...slug]-9d881ac0a3db9baa.js} +1 -1
  378. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users-bee414d57c4b55d7.js +1 -0
  379. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-e7030e1a7a9e88e1.js +1 -0
  380. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates/[...slug]-312afc9a3f8d0a4f.js +1 -0
  381. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates-e5300c340aa94c6b.js +1 -0
  382. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-fa7ca0c86142d146.js +1 -0
  383. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-bd51b3918b39329e.js +1 -0
  384. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-5158a9d98d2459e8.js +1 -0
  385. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-5ce099a7abb354ff.js +1 -0
  386. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-d30cb09c85b4c4f0.js → webpack-bd35e1c7bd7b5a9a.js} +1 -1
  387. mage_ai/server/{frontend_dist/_next/static/css/d1e8e64d0b07af2f.css → frontend_dist_base_path_template/_next/static/css/b59541b123fd7191.css} +1 -1
  388. mage_ai/server/frontend_dist_base_path_template/_next/static/do4WOsw7lNhouR0mtPTFi/_buildManifest.js +1 -0
  389. mage_ai/server/frontend_dist_base_path_template/block-layout.html +3 -3
  390. mage_ai/server/frontend_dist_base_path_template/compute.html +11 -11
  391. mage_ai/server/frontend_dist_base_path_template/files.html +11 -11
  392. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +11 -11
  393. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +11 -11
  394. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +11 -11
  395. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +11 -11
  396. mage_ai/server/frontend_dist_base_path_template/index.html +3 -3
  397. mage_ai/server/frontend_dist_base_path_template/manage/files.html +11 -11
  398. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +11 -11
  399. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +11 -11
  400. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +11 -11
  401. mage_ai/server/frontend_dist_base_path_template/manage/users.html +11 -11
  402. mage_ai/server/frontend_dist_base_path_template/manage.html +11 -11
  403. mage_ai/server/frontend_dist_base_path_template/oauth.html +8 -8
  404. mage_ai/server/frontend_dist_base_path_template/overview.html +11 -11
  405. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +11 -11
  406. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +11 -11
  407. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +11 -11
  408. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +11 -11
  409. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +3 -3
  410. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +11 -11
  411. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +11 -11
  412. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +11 -11
  413. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +11 -11
  414. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +11 -11
  415. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +11 -11
  416. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +11 -11
  417. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +11 -11
  418. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +11 -11
  419. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +11 -11
  420. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +3 -3
  421. mage_ai/server/frontend_dist_base_path_template/pipelines.html +11 -11
  422. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +11 -11
  423. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +11 -11
  424. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +11 -11
  425. mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +11 -11
  426. mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +11 -11
  427. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +11 -11
  428. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +11 -11
  429. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +11 -11
  430. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +11 -11
  431. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +11 -11
  432. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +11 -11
  433. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +11 -11
  434. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +11 -11
  435. mage_ai/server/frontend_dist_base_path_template/settings.html +3 -3
  436. mage_ai/server/frontend_dist_base_path_template/sign-in.html +39 -39
  437. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +11 -11
  438. mage_ai/server/frontend_dist_base_path_template/templates.html +11 -11
  439. mage_ai/server/frontend_dist_base_path_template/terminal.html +11 -11
  440. mage_ai/server/frontend_dist_base_path_template/test.html +3 -5
  441. mage_ai/server/frontend_dist_base_path_template/triggers.html +11 -11
  442. mage_ai/server/frontend_dist_base_path_template/version-control.html +11 -11
  443. mage_ai/server/logger.py +8 -2
  444. mage_ai/server/server.py +18 -1
  445. mage_ai/services/aws/ecs/config.py +3 -3
  446. mage_ai/services/aws/ecs/ecs.py +2 -2
  447. mage_ai/services/search/block_action_objects.py +59 -5
  448. mage_ai/settings/models/configuration_option.py +3 -1
  449. mage_ai/settings/platform/__init__.py +54 -18
  450. mage_ai/settings/repo.py +5 -4
  451. mage_ai/shared/custom_logger.py +213 -0
  452. mage_ai/shared/environments.py +4 -0
  453. mage_ai/shared/files.py +52 -1
  454. mage_ai/shared/models.py +2 -1
  455. mage_ai/shared/parsers.py +8 -1
  456. mage_ai/shared/path_fixer.py +62 -5
  457. mage_ai/shared/retry.py +4 -0
  458. mage_ai/shared/strings.py +4 -0
  459. mage_ai/tests/api/endpoints/test_blocks.py +101 -1
  460. mage_ai/tests/api/operations/base/test_base_with_user_permissions.py +4 -1
  461. mage_ai/tests/base_test.py +21 -2
  462. mage_ai/tests/cache/test_pipeline_cache.py +11 -8
  463. mage_ai/tests/data_preparation/executors/test_block_executor.py +55 -45
  464. mage_ai/tests/data_preparation/git/test_api.py +4 -4
  465. mage_ai/tests/data_preparation/models/block/dbt/test_block.py +75 -43
  466. mage_ai/tests/data_preparation/models/block/dbt/test_block_sql.py +329 -329
  467. mage_ai/tests/data_preparation/models/block/dbt/test_block_yaml.py +296 -296
  468. mage_ai/tests/data_preparation/models/block/dbt/test_dbt_adapter.py +2 -2
  469. mage_ai/tests/data_preparation/models/block/dbt/test_dbt_cli.py +4 -4
  470. mage_ai/tests/data_preparation/models/block/dbt/test_profiles.py +2 -2
  471. mage_ai/tests/data_preparation/models/block/dbt/test_project.py +2 -2
  472. mage_ai/tests/data_preparation/models/block/dbt/test_sources.py +2 -2
  473. mage_ai/tests/data_preparation/models/block/dynamic/test_dynamic_child_block_factory.py +477 -474
  474. mage_ai/tests/data_preparation/models/block/dynamic/test_dynamic_helpers.py +25 -24
  475. mage_ai/tests/data_preparation/models/block/platform/test_mixins.py +16 -25
  476. mage_ai/tests/data_preparation/models/block/test_utils.py +8 -8
  477. mage_ai/tests/data_preparation/models/test_block.py +6 -8
  478. mage_ai/tests/data_preparation/models/test_project.py +10 -5
  479. mage_ai/tests/data_preparation/models/test_variable.py +51 -4
  480. mage_ai/tests/orchestration/test_pipeline_scheduler_project_platform.py +1 -0
  481. mage_ai/version_control/__init__.py +0 -0
  482. mage_ai/version_control/models.py +288 -0
  483. {mage_ai-0.9.58.dist-info → mage_ai-0.9.59.dist-info}/METADATA +6 -6
  484. {mage_ai-0.9.58.dist-info → mage_ai-0.9.59.dist-info}/RECORD +490 -476
  485. mage_ai/server/frontend_dist/_next/static/0XnQ0C0nTr1w0o9CGC7wQ/_buildManifest.js +0 -1
  486. mage_ai/server/frontend_dist/_next/static/chunks/1124-d8fc76201b83b376.js +0 -1
  487. mage_ai/server/frontend_dist/_next/static/chunks/1154-2f262f7eb38ebaa1.js +0 -1
  488. mage_ai/server/frontend_dist/_next/static/chunks/1235.53172e14801844e5.js +0 -1
  489. mage_ai/server/frontend_dist/_next/static/chunks/1550-32333b36ac6b061b.js +0 -1
  490. mage_ai/server/frontend_dist/_next/static/chunks/1557-7cfe722a9b83b935.js +0 -1
  491. mage_ai/server/frontend_dist/_next/static/chunks/1598-dd776e3a92e9cccd.js +0 -1
  492. mage_ai/server/frontend_dist/_next/static/chunks/1751-5adf859690505d7b.js +0 -1
  493. mage_ai/server/frontend_dist/_next/static/chunks/1952-b2197a87dd67d8e0.js +0 -1
  494. mage_ai/server/frontend_dist/_next/static/chunks/2056-0ea1faa46646a77e.js +0 -1
  495. mage_ai/server/frontend_dist/_next/static/chunks/2213-52267f1e9ef5751c.js +0 -1
  496. mage_ai/server/frontend_dist/_next/static/chunks/2474-352ae192b826d896.js +0 -1
  497. mage_ai/server/frontend_dist/_next/static/chunks/2512-46141494a1b75897.js +0 -1
  498. mage_ai/server/frontend_dist/_next/static/chunks/2717-accc279ae116b1b9.js +0 -1
  499. mage_ai/server/frontend_dist/_next/static/chunks/2852872c-15b31a7081e6a868.js +0 -1
  500. mage_ai/server/frontend_dist/_next/static/chunks/2886-9e73e1f48f248741.js +0 -1
  501. mage_ai/server/frontend_dist/_next/static/chunks/2920.86a65e5f26ff1795.js +0 -1
  502. mage_ai/server/frontend_dist/_next/static/chunks/3437-6055fd5aa82880f6.js +0 -1
  503. mage_ai/server/frontend_dist/_next/static/chunks/3449-214fce1a0e623b47.js +0 -1
  504. mage_ai/server/frontend_dist/_next/static/chunks/3494-23a9cc2cd649abac.js +0 -1
  505. mage_ai/server/frontend_dist/_next/static/chunks/3745-3662911c364d917b.js +0 -1
  506. mage_ai/server/frontend_dist/_next/static/chunks/3763-70c7eb1fc203c903.js +0 -1
  507. mage_ai/server/frontend_dist/_next/static/chunks/3943-a49377acc514e77f.js +0 -1
  508. mage_ai/server/frontend_dist/_next/static/chunks/4052-f89c85d2c8f51931.js +0 -1
  509. mage_ai/server/frontend_dist/_next/static/chunks/4296-14eaf96d6479e673.js +0 -1
  510. mage_ai/server/frontend_dist/_next/static/chunks/4804-1254a474f238d078.js +0 -1
  511. mage_ai/server/frontend_dist/_next/static/chunks/5283-9df961e430a79bea.js +0 -1
  512. mage_ai/server/frontend_dist/_next/static/chunks/5457-b373ebdf4d05d8e2.js +0 -1
  513. mage_ai/server/frontend_dist/_next/static/chunks/5499-bc2528f8e18f61a6.js +0 -1
  514. mage_ai/server/frontend_dist/_next/static/chunks/5810-e66141c1271bced6.js +0 -1
  515. mage_ai/server/frontend_dist/_next/static/chunks/5849-f30d8694e3318a81.js +0 -1
  516. mage_ai/server/frontend_dist/_next/static/chunks/5896-7b8e36634d7d94eb.js +0 -1
  517. mage_ai/server/frontend_dist/_next/static/chunks/6043-728790621ca9014c.js +0 -1
  518. mage_ai/server/frontend_dist/_next/static/chunks/6050-e48b7f97e96bbcb6.js +0 -1
  519. mage_ai/server/frontend_dist/_next/static/chunks/6285-648f9a732e100b2f.js +0 -1
  520. mage_ai/server/frontend_dist/_next/static/chunks/6639-74eefed142e14ea6.js +0 -1
  521. mage_ai/server/frontend_dist/_next/static/chunks/6965-c613d1834c8ed92d.js +0 -1
  522. mage_ai/server/frontend_dist/_next/static/chunks/7022-ea92cb336bd1aab8.js +0 -1
  523. mage_ai/server/frontend_dist/_next/static/chunks/7361-06ef4c642a8fe8c4.js +0 -1
  524. mage_ai/server/frontend_dist/_next/static/chunks/7858-677c641010ac9160.js +0 -1
  525. mage_ai/server/frontend_dist/_next/static/chunks/8125-b9d53e425b6ddc7e.js +0 -1
  526. mage_ai/server/frontend_dist/_next/static/chunks/8146-fb8f445644e573b0.js +0 -1
  527. mage_ai/server/frontend_dist/_next/static/chunks/8432-0ace6fb7bdbc6864.js +0 -1
  528. mage_ai/server/frontend_dist/_next/static/chunks/844-1e171f361e63b36d.js +0 -1
  529. mage_ai/server/frontend_dist/_next/static/chunks/9269-40e2101f56399dcc.js +0 -1
  530. mage_ai/server/frontend_dist/_next/static/chunks/9302-913007e2f801ad65.js +0 -1
  531. mage_ai/server/frontend_dist/_next/static/chunks/9440-c51bf1e8f271cb25.js +0 -1
  532. mage_ai/server/frontend_dist/_next/static/chunks/9624-89a4b20eb3b3c754.js +0 -1
  533. mage_ai/server/frontend_dist/_next/static/chunks/976-0a8c2c4d7acd957b.js +0 -1
  534. mage_ai/server/frontend_dist/_next/static/chunks/9775-c1142b1312e8f95d.js +0 -1
  535. mage_ai/server/frontend_dist/_next/static/chunks/pages/404-5ddd12931e0e3e41.js +0 -1
  536. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-ec5e62e8e5bb4e4c.js +0 -1
  537. mage_ai/server/frontend_dist/_next/static/chunks/pages/block-layout-44d7291d8f29eb36.js +0 -1
  538. mage_ai/server/frontend_dist/_next/static/chunks/pages/compute-a6661a9c3647532a.js +0 -1
  539. mage_ai/server/frontend_dist/_next/static/chunks/pages/files-26b899d3adb4ed19.js +0 -1
  540. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-9bd164317e652311.js +0 -1
  541. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-c87d46dc53e35638.js +0 -1
  542. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks-24785a5ed4eb340d.js +0 -1
  543. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/files-2c5fd116ecfacb33.js +0 -1
  544. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-8c9285af31efa3fd.js +0 -1
  545. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/[user]-ec7e0419a64ae3b2.js +0 -1
  546. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-039e083cc068da54.js +0 -1
  547. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-8e4d4f6edc515265.js +0 -1
  548. mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-b73185fdcb7a131c.js +0 -1
  549. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipeline-runs-97b3335bf60f8b07.js +0 -1
  550. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-83de126136539668.js +0 -1
  551. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-50f45e96892cfb63.js +0 -1
  552. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-5fe0f1de6fd365f8.js +0 -1
  553. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-306db9e11fa94d21.js +0 -1
  554. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-ebea4be0562b08e3.js +0 -1
  555. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-f09d21d5c2661504.js +0 -1
  556. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-61e770f155ae22ef.js +0 -1
  557. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-d347a4614130e2ab.js +0 -1
  558. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-056c5e5080a3754f.js +0 -1
  559. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-208fa8de91f152bc.js +0 -1
  560. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-a32e02f46a816eb3.js +0 -1
  561. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-8012388b15f0e0a5.js +0 -1
  562. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-6714c72f90923cfb.js +0 -1
  563. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-afc0525ef27fe1f2.js +0 -1
  564. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-a91e7d86cd0540d9.js +0 -1
  565. mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks/[...slug]-7c8e5a8908fe9c83.js +0 -1
  566. mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks-be0684d1527587d8.js +0 -1
  567. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-147660a34351147c.js +0 -1
  568. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-ec5f01b683920ced.js +0 -1
  569. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/settings-28aa4512c0e23ec5.js +0 -1
  570. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions-a2850b2e0a282d16.js +0 -1
  571. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-b1df80674dca4713.js +0 -1
  572. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-41abcd2241958dc8.js +0 -1
  573. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users-a2c5859f53b5e9e1.js +0 -1
  574. mage_ai/server/frontend_dist/_next/static/chunks/pages/sign-in-1aea2a0c373bc6ae.js +0 -1
  575. mage_ai/server/frontend_dist/_next/static/chunks/pages/templates/[...slug]-e7485742708215d2.js +0 -1
  576. mage_ai/server/frontend_dist/_next/static/chunks/pages/templates-b4086d30a89d6801.js +0 -1
  577. mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-3cd171f43f0a0df8.js +0 -1
  578. mage_ai/server/frontend_dist/_next/static/chunks/pages/test-6a22493285c47ba2.js +0 -1
  579. mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-ad20a31dde4fe59b.js +0 -1
  580. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-267952b4c87927c7.js +0 -1
  581. mage_ai/server/frontend_dist_base_path_template/_next/static/RC0Yenm06LvZI-RWFoT5C/_buildManifest.js +0 -1
  582. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1124-d8fc76201b83b376.js +0 -1
  583. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1154-2f262f7eb38ebaa1.js +0 -1
  584. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1235.53172e14801844e5.js +0 -1
  585. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1550-32333b36ac6b061b.js +0 -1
  586. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-7cfe722a9b83b935.js +0 -1
  587. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1598-dd776e3a92e9cccd.js +0 -1
  588. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1751-5adf859690505d7b.js +0 -1
  589. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1952-b2197a87dd67d8e0.js +0 -1
  590. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2056-0ea1faa46646a77e.js +0 -1
  591. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2213-52267f1e9ef5751c.js +0 -1
  592. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2474-352ae192b826d896.js +0 -1
  593. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2512-46141494a1b75897.js +0 -1
  594. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2717-accc279ae116b1b9.js +0 -1
  595. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2852872c-15b31a7081e6a868.js +0 -1
  596. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2886-9e73e1f48f248741.js +0 -1
  597. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2920.86a65e5f26ff1795.js +0 -1
  598. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3437-6055fd5aa82880f6.js +0 -1
  599. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3449-214fce1a0e623b47.js +0 -1
  600. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3494-23a9cc2cd649abac.js +0 -1
  601. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3745-3662911c364d917b.js +0 -1
  602. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3763-70c7eb1fc203c903.js +0 -1
  603. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3943-a49377acc514e77f.js +0 -1
  604. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4052-f89c85d2c8f51931.js +0 -1
  605. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4296-14eaf96d6479e673.js +0 -1
  606. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4804-1254a474f238d078.js +0 -1
  607. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5283-9df961e430a79bea.js +0 -1
  608. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-b373ebdf4d05d8e2.js +0 -1
  609. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5499-bc2528f8e18f61a6.js +0 -1
  610. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5810-e66141c1271bced6.js +0 -1
  611. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5849-f30d8694e3318a81.js +0 -1
  612. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5896-7b8e36634d7d94eb.js +0 -1
  613. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6043-728790621ca9014c.js +0 -1
  614. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6050-e48b7f97e96bbcb6.js +0 -1
  615. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6285-648f9a732e100b2f.js +0 -1
  616. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6639-74eefed142e14ea6.js +0 -1
  617. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6965-c613d1834c8ed92d.js +0 -1
  618. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-ea92cb336bd1aab8.js +0 -1
  619. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-06ef4c642a8fe8c4.js +0 -1
  620. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7858-677c641010ac9160.js +0 -1
  621. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8125-b9d53e425b6ddc7e.js +0 -1
  622. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-fb8f445644e573b0.js +0 -1
  623. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8432-0ace6fb7bdbc6864.js +0 -1
  624. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/844-1e171f361e63b36d.js +0 -1
  625. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9269-40e2101f56399dcc.js +0 -1
  626. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9302-913007e2f801ad65.js +0 -1
  627. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-c51bf1e8f271cb25.js +0 -1
  628. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9624-89a4b20eb3b3c754.js +0 -1
  629. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/976-0a8c2c4d7acd957b.js +0 -1
  630. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9775-c1142b1312e8f95d.js +0 -1
  631. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/404-5ddd12931e0e3e41.js +0 -1
  632. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-ec5e62e8e5bb4e4c.js +0 -1
  633. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/block-layout-44d7291d8f29eb36.js +0 -1
  634. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/compute-a6661a9c3647532a.js +0 -1
  635. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-26b899d3adb4ed19.js +0 -1
  636. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-9bd164317e652311.js +0 -1
  637. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-c87d46dc53e35638.js +0 -1
  638. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks-24785a5ed4eb340d.js +0 -1
  639. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/files-2c5fd116ecfacb33.js +0 -1
  640. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-8c9285af31efa3fd.js +0 -1
  641. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-ec7e0419a64ae3b2.js +0 -1
  642. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-039e083cc068da54.js +0 -1
  643. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-8e4d4f6edc515265.js +0 -1
  644. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-b73185fdcb7a131c.js +0 -1
  645. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-97b3335bf60f8b07.js +0 -1
  646. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-83de126136539668.js +0 -1
  647. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-50f45e96892cfb63.js +0 -1
  648. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-5fe0f1de6fd365f8.js +0 -1
  649. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-306db9e11fa94d21.js +0 -1
  650. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-ebea4be0562b08e3.js +0 -1
  651. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-f09d21d5c2661504.js +0 -1
  652. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-61e770f155ae22ef.js +0 -1
  653. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-d347a4614130e2ab.js +0 -1
  654. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-056c5e5080a3754f.js +0 -1
  655. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-208fa8de91f152bc.js +0 -1
  656. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-a32e02f46a816eb3.js +0 -1
  657. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-8012388b15f0e0a5.js +0 -1
  658. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-6714c72f90923cfb.js +0 -1
  659. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-afc0525ef27fe1f2.js +0 -1
  660. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-a91e7d86cd0540d9.js +0 -1
  661. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks/[...slug]-7c8e5a8908fe9c83.js +0 -1
  662. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks-be0684d1527587d8.js +0 -1
  663. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-147660a34351147c.js +0 -1
  664. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-ec5f01b683920ced.js +0 -1
  665. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-28aa4512c0e23ec5.js +0 -1
  666. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions-a2850b2e0a282d16.js +0 -1
  667. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-b1df80674dca4713.js +0 -1
  668. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-41abcd2241958dc8.js +0 -1
  669. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users-a2c5859f53b5e9e1.js +0 -1
  670. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-1aea2a0c373bc6ae.js +0 -1
  671. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates/[...slug]-e7485742708215d2.js +0 -1
  672. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates-b4086d30a89d6801.js +0 -1
  673. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-3cd171f43f0a0df8.js +0 -1
  674. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-6a22493285c47ba2.js +0 -1
  675. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-ad20a31dde4fe59b.js +0 -1
  676. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-267952b4c87927c7.js +0 -1
  677. /mage_ai/server/frontend_dist/_next/static/{0XnQ0C0nTr1w0o9CGC7wQ → PPQxHOmWVJ0iQFzG2rc8m}/_ssgManifest.js +0 -0
  678. /mage_ai/server/frontend_dist_base_path_template/_next/static/{RC0Yenm06LvZI-RWFoT5C → do4WOsw7lNhouR0mtPTFi}/_ssgManifest.js +0 -0
  679. {mage_ai-0.9.58.dist-info → mage_ai-0.9.59.dist-info}/LICENSE +0 -0
  680. {mage_ai-0.9.58.dist-info → mage_ai-0.9.59.dist-info}/WHEEL +0 -0
  681. {mage_ai-0.9.58.dist-info → mage_ai-0.9.59.dist-info}/entry_points.txt +0 -0
  682. {mage_ai-0.9.58.dist-info → mage_ai-0.9.59.dist-info}/top_level.txt +0 -0
@@ -2,22 +2,41 @@ from typing import Dict, List, Tuple
2
2
 
3
3
  import pandas as pd
4
4
 
5
+ from mage_ai.data_preparation.models.block.dynamic.utils import (
6
+ DynamicBlockWrapper,
7
+ MetadataInstructions,
8
+ )
5
9
  from mage_ai.data_preparation.models.block.utils import (
6
- dynamic_block_uuid,
10
+ build_dynamic_block_uuid,
7
11
  dynamic_block_values_and_metadata,
8
- is_dynamic_block,
9
- is_dynamic_block_child,
10
12
  )
11
13
  from mage_ai.data_preparation.models.constants import BlockType
12
- from mage_ai.shared.array import find_index
14
+ from mage_ai.orchestration.db.models.schedules import BlockRun
15
+ from mage_ai.shared.array import find, find_index
16
+ from mage_ai.shared.custom_logger import DX_PRINTER
17
+ from mage_ai.shared.environments import is_test
13
18
 
14
19
 
15
20
  class DynamicChildBlockFactory:
16
- def __init__(self, block, pipeline_run=None, **kwargs):
21
+ def __init__(
22
+ self,
23
+ block,
24
+ pipeline_run=None,
25
+ block_run_id: int = None,
26
+ block_run: BlockRun = None,
27
+ block_runs: List = None,
28
+ **kwargs,
29
+ ):
17
30
  self.block = block
18
- self.pipeline_run = pipeline_run
31
+ self.block_run_id = block_run_id
19
32
  self.type = BlockType.DYNAMIC_CHILD
20
33
 
34
+ self._block_run = block_run
35
+ self._block_runs = block_runs
36
+ self._block_runs_fetched = True if self._block_runs else False
37
+ self._pipeline_run = pipeline_run
38
+ self._wrapper = None
39
+
21
40
  def __getattr__(self, name):
22
41
  val = getattr(self.block, name)
23
42
 
@@ -29,19 +48,139 @@ class DynamicChildBlockFactory:
29
48
 
30
49
  return val
31
50
 
51
+ def block_run(self) -> BlockRun:
52
+ if self._block_run:
53
+ return self._block_run
54
+
55
+ if self._block_runs:
56
+ self._block_run = find(
57
+ lambda br, factory=self: (
58
+ factory.block_run_id and br.id == factory.block_run_id
59
+ ) or (br.block_uuid == factory.block.uuid),
60
+ self._block_runs,
61
+ )
62
+ DX_PRINTER.debug(
63
+ f'Block run: for block {self.block.uuid}: '
64
+ f'{self._block_run.id if self._block_run else ""} '
65
+ f'{self._block_run.block_uuid if self._block_run else ""}'
66
+ )
67
+
68
+ if not self._block_run:
69
+ try:
70
+ self._block_run = BlockRun.query.get(self.block_run_id)
71
+ except AttributeError as err:
72
+ if not is_test():
73
+ raise err
74
+ print(err)
75
+
76
+ return self._block_run
77
+
78
+ def set_pipeline_run(self, pipeline_run):
79
+ self._pipeline_run = pipeline_run
80
+
81
+ def pipeline_run(self):
82
+ if self._pipeline_run:
83
+ return self._pipeline_run
84
+
85
+ block_run = self.block_run()
86
+ if block_run:
87
+ self._pipeline_run = block_run.pipeline_run
88
+
89
+ return self._pipeline_run
90
+
91
+ def block_runs(self) -> List[BlockRun]:
92
+ if self._block_runs or self._block_runs_fetched:
93
+ return self._block_runs
94
+
95
+ block_run = self.block_run()
96
+ if block_run:
97
+ self._block_runs = BlockRun.query.filter(
98
+ BlockRun.pipeline_run_id == block_run.pipeline_run_id,
99
+ ).all()
100
+ self._block_runs_fetched = True
101
+
102
+ return self._block_runs
103
+
104
+ def block_run_metadata(self) -> Dict:
105
+ block_run = self.block_run()
106
+ if block_run:
107
+ return block_run.metrics
108
+
109
+ def wrapper(self) -> DynamicBlockWrapper:
110
+ if self._wrapper:
111
+ return self._wrapper
112
+
113
+ self._wrapper = DynamicBlockWrapper(factory=self)
114
+
115
+ return self._wrapper
116
+
32
117
  def execute_sync(
33
118
  self,
34
119
  execution_partition: str = None,
35
120
  **kwargs,
36
121
  ) -> List[Dict]:
37
- arr = []
122
+ """
123
+ When a pipeline run is created and it begins to create its block runs,
124
+ we can statically detect which blocks have at least 1 upstream block that is both
125
+ a dynamic block and a dynamic child block (nickname dynamic squared).
126
+
127
+ If there exists a block with an upstream block that is dynamic squared (nickname),
128
+ that means we’ll eventually have to generate N clones of the original dynamic child
129
+ block.
130
+
131
+ Original dynamic child blocks (the one below) are responsible for spawning dynamic
132
+ child block runs generated from the output data of an upstream dynamic block.
133
+
134
+ We cannot create those block runs statically because the output from the upstream
135
+ dynamic squared block hasn’t been created yet.
136
+
137
+ When the original (non-cloned version) of the dynamic child block with an upstream
138
+ dynamic squared block executes (logic is contained in the DynamicChildBlockFactory
139
+ class), instead of generating purely dynamic child block runs, it’ll create
140
+ clones of the original block (itself).
141
+
142
+ Those clones of the original will then depend on each individual spawn of the
143
+ upstream dynamic squared block. Once a spawn finishes running, the output from
144
+ that spawn will be used by the clone of the original to dynamically create
145
+ block runs.
146
+
147
+ When the original (non-cloned) dynamic child block executes, perform these 2 special checks:
148
+ 1. Are there any upstream blocks that are dynamic and dynamic child (dynamic squared)
149
+ 2. If yes, does that upstream block reduce output
150
+
151
+ If the upstream block doesn’t reduce output, then do the following:
152
+ 1. Get the number of spawns from the upstream block
153
+ 2. Create N block runs that is a clone of its original self, for every spawn
154
+ 3. Set block run’s metadata/metrics to have an upstream dependency on that spawn.
155
+
156
+ If the upstream block reduces output, then use the logic already defined below to:
157
+ 1. Get the number of spawns from the upstream block
158
+ 2. Create a block run for a clone of its original self
159
+ 3. That block run’s metadata/metrics will include all the block run block UUIDs of all the
160
+ spawns as an upstream dependency.
161
+ """
162
+ DX_PRINTER.label = 'DynamicChildBlockFactory'
163
+ DX_PRINTER.info(
164
+ 'execute_sync',
165
+ block=self.block,
166
+ dynamic_block=self.wrapper().to_dict(),
167
+ )
38
168
 
39
- values = self.__build_block_runs(self.block, execution_partition)
169
+ arr = []
170
+ values = self.__build_block_runs(self.wrapper(), execution_partition=execution_partition)
40
171
  if not values:
172
+ DX_PRINTER.error('No block runs to create from values', block=self.block)
41
173
  return None
42
174
 
175
+ DX_PRINTER.info(
176
+ f'Blocks runs to create: {len(values)}',
177
+ block=self.block,
178
+ uuids=[tup[0] for tup in values],
179
+ )
180
+
181
+ pipeline_run = self.pipeline_run()
43
182
  for block_uuid, metrics in values:
44
- self.pipeline_run.create_block_run(
183
+ pipeline_run.create_block_run(
45
184
  block_uuid,
46
185
  metrics=metrics,
47
186
  skip_if_exists=True,
@@ -53,63 +192,307 @@ class DynamicChildBlockFactory:
53
192
 
54
193
  return arr
55
194
 
56
- def __build_block_runs(self, block, execution_partition: str = None) -> List[Tuple]:
57
- upstream_blocks = []
58
- for upstream_block in block.upstream_blocks:
59
- if is_dynamic_block(upstream_block):
60
- upstream_blocks.append((upstream_block, False))
61
- elif is_dynamic_block_child(upstream_block):
62
- upstream_blocks.append((upstream_block, True))
195
+ def upstream_blocks_wrapped(self) -> List[DynamicBlockWrapper]:
196
+ block_runs = self.block_runs() or []
197
+ metadata = self.block_run_metadata() or {}
198
+
199
+ upstream_blocks_mapping = {}
200
+
201
+ dynamic_upstream_block_uuids = (metadata or {}).get('dynamic_upstream_block_uuids') or []
202
+ for upstream_block_uuid in dynamic_upstream_block_uuids:
203
+ block_original = self.block.pipeline.get_block(upstream_block_uuid)
204
+ if block_original:
205
+ upstream_blocks_mapping[block_original.uuid] = DynamicBlockWrapper(
206
+ factory=DynamicChildBlockFactory(
207
+ block_original,
208
+ block_run=find(
209
+ lambda br, uuid=upstream_block_uuid: br.block_uuid == uuid,
210
+ block_runs,
211
+ ),
212
+ block_runs=block_runs,
213
+ ),
214
+ )
215
+
216
+ for upstream_block in self.block.upstream_blocks:
217
+ if upstream_block.uuid in upstream_blocks_mapping:
218
+ continue
219
+
220
+ upstream_blocks_mapping[upstream_block.uuid] = DynamicBlockWrapper(
221
+ factory=DynamicChildBlockFactory(
222
+ upstream_block,
223
+ block_run=find(
224
+ lambda br, uuid=upstream_block.uuid: br.block_uuid == uuid,
225
+ block_runs,
226
+ ),
227
+ block_runs=block_runs,
228
+ ),
229
+ )
230
+
231
+ return list(upstream_blocks_mapping.values())
232
+
233
+ def __build_block_runs(
234
+ self,
235
+ wrapper: DynamicBlockWrapper,
236
+ execution_partition: str = None,
237
+ ) -> List[Tuple]:
238
+ """
239
+ Check to see if this block is a clone of the original block.
240
+ A clone will act as an original block (e.g. controller that create block runs
241
+ for itself) but its upstream is associated to a dynamic child’s spawns (a spawn is
242
+ a block run that was created for a dynamic child by the dynamic child block itself.)
243
+
244
+ When an original clone block calculates how many block runs it should spawn,
245
+ it must treat any upstream dynamic + dynamic child (e.g. D2) blocks simply as a
246
+ dynamic block.
247
+ """
248
+
249
+ upstream_wrappers = []
250
+ for upstream_wrapper in wrapper.factory.upstream_blocks_wrapped():
251
+ """
252
+ This order is very important!
253
+ Is the upstream block is both dynamic and a dynamic child,
254
+ it needs to act like a dynamic child first so that it spawns 1 block run
255
+ for each of its downstream blocks.
256
+ Then, when this upstream block’s block runs are completed, those blocks
257
+ will act as a dynamic block and create N block runs for its downstream.
258
+
259
+ For example, A -> B -> C
260
+ A: dynamic block
261
+ B: dynamic block, dynamic child
262
+ C: dynamic child
263
+
264
+ A: creates 3 B
265
+ B: 3 block runs, each create 3 C
266
+ C: 9 block runs in total
267
+
268
+ The current block needs to spawn 3 block runs that act as original blocks
269
+ so that when its upstream block (that is both dynamic & dynamic child)
270
+ is completed, the 3 "original blocks" will run through this process and
271
+ dynamically create block runs based on the upstream block’s output.
272
+ """
273
+
274
+ upstream_is_dynamic = upstream_wrapper.is_dynamic()
275
+ upstream_is_dynamic_child = upstream_wrapper.is_dynamic_child()
276
+
277
+ if wrapper.is_clone_of_original() and upstream_is_dynamic:
278
+ """
279
+ If this is the clone of the original and the upstream block is at least a
280
+ dynamic block, handle the block run creation process as usual.
281
+
282
+ Treat this process as if its generating block runs from an upstream
283
+ dynamic block.
284
+
285
+ However, to determine how many children to create from that dynamic block,
286
+ we must fetch the output data of a specific spawn because the output data
287
+ can vary depending on which spawn it is.
288
+
289
+ How do we know which dynamic child spawn block this is assigned to?
290
+ """
291
+ upstream_wrappers.append((upstream_wrapper, False))
292
+ elif wrapper.is_original() and upstream_is_dynamic and upstream_is_dynamic_child:
293
+ """
294
+ If this is the original (non-cloned) dynamic child block and
295
+ the upstream block is dynamic squared, then create N clones of original.
296
+ Treat this process as if its generating block runs from an upstream
297
+ dynamic child block. The difference will be after the block run metadata
298
+ is generated.
299
+ Before creating the block run record in the database, we must hydrate the
300
+ block run’s metadata/metrics with data that will allow the clones to
301
+ recognize itself as a clone of the original.
302
+ """
303
+ upstream_wrappers.append((upstream_wrapper, True))
304
+
305
+ wrapper.metadata_instructions = MetadataInstructions(
306
+ clone_original=True,
307
+ original=wrapper,
308
+ upstream=upstream_wrapper,
309
+ )
310
+ elif upstream_is_dynamic:
311
+ upstream_wrappers.append((upstream_wrapper, False))
312
+ elif upstream_is_dynamic_child:
313
+ upstream_wrappers.append((upstream_wrapper, True))
314
+
315
+ DX_PRINTER.info(
316
+ f'Upstream block: {upstream_wrapper.uuid}',
317
+ block=wrapper.block,
318
+ upstream_is_dynamic=upstream_is_dynamic,
319
+ upstream_is_dynamic_child=upstream_is_dynamic_child,
320
+ )
321
+
322
+ DX_PRINTER.info(
323
+ f'Upstream blocks: {len(upstream_wrappers)}',
324
+ block=wrapper.block,
325
+ uuids=[f'{tup[0].uuid}: {tup[1]}' for tup in upstream_wrappers],
326
+ )
63
327
 
64
328
  outputs = []
65
- for upstream_block, is_dynamic_child in upstream_blocks:
329
+ for upstream_parent_index, pair in enumerate(upstream_wrappers):
330
+ upstream_wrapper, is_dynamic_child = pair
331
+
66
332
  values = None
67
333
  block_metadata = None
68
334
 
69
335
  if is_dynamic_child:
70
- values = [dict(
71
- parent_index=None,
72
- upstream_block_uuid=block_uuid,
73
- extra_settings=dict(
74
- block_uuid_prefix=block_uuid.split(':')[-1],
75
- dynamic_upstream_block_uuids=[
76
- block_uuid,
77
- ],
78
- ),
79
- ) for block_uuid, metrics in self.__build_block_runs(
80
- upstream_block,
336
+ DX_PRINTER.debug(
337
+ f'Getting block runs for upstream dynamic child: {upstream_wrapper.uuid}',
338
+ block=wrapper.block,
339
+ upstream_block=upstream_wrapper.uuid,
340
+ )
341
+
342
+ # If the upstream block is also a dynamic block, dynamic block behavior
343
+ # takes precedence. Every child block of the upstream block will act as a
344
+ # separate dynamic block that create dynamic children. We must use the index
345
+ # of that dynamic block which is a single number to differentiate between
346
+ # this current block having multiple upstream dynamic blocks.
347
+ parent_index_for_child_block = None
348
+ if upstream_wrapper.is_dynamic():
349
+ parent_index_for_child_block = upstream_parent_index
350
+
351
+ values_pairs = self.__build_block_runs(
352
+ upstream_wrapper,
81
353
  execution_partition=execution_partition,
82
- )]
354
+ )
355
+
356
+ DX_PRINTER.debug(
357
+ f'Block runs built for upstream dynamic child {upstream_wrapper.uuid}: '
358
+ f'{len(values_pairs)}',
359
+ block=wrapper.block,
360
+ upstream_block=upstream_wrapper.uuid,
361
+ )
362
+
363
+ values = []
364
+
365
+ if isinstance(values_pairs, dict):
366
+ values_pairs = list(values_pairs.items())
367
+
368
+ for upstream_block_uuid, _metrics in values_pairs:
369
+ values.append(dict(
370
+ parent_index=parent_index_for_child_block,
371
+ upstream_block_uuid=upstream_block_uuid,
372
+ extra_settings=dict(
373
+ block_uuid_prefix=upstream_block_uuid.split(':')[-1],
374
+ dynamic_upstream_block_uuids=[
375
+ upstream_block_uuid,
376
+ ],
377
+ ),
378
+ ))
379
+
380
+ DX_PRINTER.critical(
381
+ 'Adding outputs from upstream dynamic child block',
382
+ block=wrapper.block,
383
+ parent_index=parent_index_for_child_block,
384
+ upstream_block_uuid=upstream_block_uuid,
385
+ extra_settings=dict(
386
+ block_uuid_prefix=upstream_block_uuid.split(':')[-1],
387
+ dynamic_upstream_block_uuids=[
388
+ upstream_block_uuid,
389
+ ],
390
+ ),
391
+ )
392
+
393
+ DX_PRINTER.debug(
394
+ f'Values from upstream dynamic child: {len(values)}',
395
+ block=wrapper.block,
396
+ upstream_block=upstream_wrapper.uuid,
397
+ )
398
+
83
399
  outputs.append((values, None))
84
400
  else:
401
+ dynamic_block_index_from_parent = wrapper.get_dynamic_block_index_from_parent(
402
+ upstream_wrapper.uuid,
403
+ )
404
+ # Validate that the output of this function returns the correct output
405
+ # for dynamic squared blocks (aka dynamic + dynamic child).
85
406
  values, block_metadata = dynamic_block_values_and_metadata(
86
- upstream_block,
87
- execution_partition,
88
- upstream_block.uuid,
407
+ upstream_wrapper.block,
408
+ block_uuid=wrapper.get_parent_block_uuid_for_output_variables(
409
+ upstream_wrapper.block,
410
+ upstream_wrapper.uuid,
411
+ ),
412
+ dynamic_block_index=dynamic_block_index_from_parent,
413
+ execution_partition=execution_partition,
414
+ )
415
+
416
+ DX_PRINTER.critical(
417
+ 'dynamic_block_values_and_metadata',
418
+ block=wrapper.block,
419
+ block_uuid=wrapper.get_parent_block_uuid_for_output_variables(
420
+ upstream_wrapper.block,
421
+ upstream_wrapper.uuid,
422
+ ),
423
+ dynamic_block_index=dynamic_block_index_from_parent,
424
+ upstream_block=upstream_wrapper.block.uuid,
425
+ upstream_block_uuid=upstream_wrapper.uuid,
426
+ values=values,
427
+ __uuid='dynamic_block_values_and_metadata',
89
428
  )
90
429
 
91
430
  if isinstance(values, pd.DataFrame):
92
431
  values = values.to_dict(orient='records')
93
432
 
94
433
  if values:
434
+ dynamic_upstream_block_uuids = None
435
+
436
+ # If these child blocks are being created by its clone of
437
+ # original dynamic child block, then we need to use the parent index of the
438
+ # spawn of the upstream dynamic squared block.
439
+ if wrapper.is_clone_of_original():
440
+ dynamic_upstream_block_uuids = [
441
+ upstream_wrapper.uuid,
442
+ ]
443
+ upstream_parent_index = wrapper.get_dynamic_block_index()
444
+
445
+ DX_PRINTER.critical(
446
+ 'dynamic_upstream_index from current upstream is '
447
+ f'{upstream_wrapper.get_dynamic_block_index()}',
448
+ )
449
+
450
+ child_data = []
451
+ for parent_index, value in enumerate(values):
452
+ extra_settings = dict(
453
+ dynamic_upstream_block_uuids=dynamic_upstream_block_uuids,
454
+ index=parent_index,
455
+ value=value,
456
+ )
457
+
458
+ if dynamic_block_index_from_parent is not None:
459
+ extra_settings['block_uuid_prefix'] = dynamic_block_index_from_parent
460
+
461
+ child_data.append(dict(
462
+ parent_index=upstream_parent_index,
463
+ upstream_block_uuid=upstream_wrapper.uuid,
464
+ extra_settings=extra_settings,
465
+ ))
466
+
467
+ DX_PRINTER.critical(
468
+ 'Adding outputs from upstream dynamic block',
469
+ block=wrapper.block,
470
+ upstream_block=upstream_wrapper.block.uuid,
471
+ upstream_block_uuid=upstream_wrapper.uuid,
472
+ parent_index=upstream_parent_index,
473
+ block_metadata=block_metadata,
474
+ )
475
+
95
476
  outputs.append((
96
- [dict(
97
- parent_index=parent_index,
98
- upstream_block_uuid=upstream_block.uuid,
99
- extra_settings=dict(value=value),
100
- ) for parent_index, value in enumerate(values)],
477
+ child_data,
101
478
  block_metadata,
102
479
  ))
103
480
 
481
+ DX_PRINTER.info(f'Outputs: {len(outputs)}', block=wrapper.block)
482
+ if len(outputs) == 0:
483
+ DX_PRINTER.critical('No outputs', block=wrapper.block)
484
+
104
485
  all_data = None
105
486
  for output in outputs:
106
487
  child_data = None
107
488
  child_metadata = None
108
489
 
109
490
  if len(output) >= 1:
491
+ # list of values from 1 parent
110
492
  child_data = output[0]
111
493
 
112
494
  if len(output) >= 2:
495
+ # list of metadata from 1 parent
113
496
  child_metadata = output[1]
114
497
 
115
498
  metadata_len = len(child_metadata) if child_metadata else 0
@@ -117,20 +500,32 @@ class DynamicChildBlockFactory:
117
500
  if all_data is None:
118
501
  all_data = []
119
502
  if child_data:
120
- for data_dict in child_data:
503
+ for index_within_same_parent, data_dict in enumerate(child_data):
121
504
  parent_index = data_dict['parent_index']
122
505
  upstream_block_uuid = data_dict['upstream_block_uuid']
123
506
  extra_settings = data_dict['extra_settings']
124
507
 
125
508
  metadata = None
126
- if parent_index is not None and parent_index < metadata_len:
127
- metadata = child_metadata[parent_index]
509
+
510
+ if index_within_same_parent is not None and \
511
+ index_within_same_parent < metadata_len:
512
+
513
+ metadata = child_metadata[index_within_same_parent]
514
+
128
515
  all_data.append([(
129
516
  upstream_block_uuid,
130
517
  parent_index,
131
518
  metadata,
132
519
  extra_settings,
133
520
  )])
521
+
522
+ DX_PRINTER.critical(
523
+ 'Looping over all data',
524
+ upstream_block_uuid=upstream_block_uuid,
525
+ parent_index=parent_index,
526
+ metadata=metadata,
527
+ extra_settings=extra_settings,
528
+ )
134
529
  else:
135
530
  all_data.append([(None, None, None, None)])
136
531
  else:
@@ -151,20 +546,33 @@ class DynamicChildBlockFactory:
151
546
  metadata,
152
547
  extra_settings,
153
548
  )])
549
+
550
+ DX_PRINTER.critical(
551
+ 'Looping over all data',
552
+ upstream_block_uuid=upstream_block_uuid,
553
+ parent_index=parent_index,
554
+ metadata=metadata,
555
+ extra_settings=extra_settings,
556
+ )
154
557
  else:
155
558
  arr.append(data_arr + [(None, None, None, None)])
156
559
 
157
560
  all_data = arr
158
561
 
562
+ block_runs_tuples = []
563
+
159
564
  if all_data is None:
160
- return None
565
+ return block_runs_tuples
161
566
 
162
- block_runs_tuples = []
163
567
  for idx, child_data_list in enumerate(all_data):
164
- block_runs_tuples.append(self.__build_block_run(block, idx, child_data_list))
568
+ block_runs_tuples.append(self.__build_block_run(
569
+ wrapper,
570
+ idx,
571
+ child_data_list,
572
+ ))
165
573
 
166
574
  # Add upstream blocks defined dynamically from the dynamic block’s metadata
167
- pipeline = block.pipeline
575
+ pipeline = wrapper.block.pipeline
168
576
  for idx, child_data_list in enumerate(all_data):
169
577
  for idx2, tup in enumerate(child_data_list):
170
578
  _upstream_block_uuid, _parent_index, metadata_inner, _extra_settings = tup
@@ -195,17 +603,24 @@ class DynamicChildBlockFactory:
195
603
  metrics = {}
196
604
  metrics['dynamic_upstream_block_uuids'] = \
197
605
  (metrics.get('dynamic_upstream_block_uuids') or []) + up_uuids
606
+
198
607
  block_runs_tuples[idx] = (block_uuid, metrics)
199
608
 
200
609
  return block_runs_tuples
201
610
 
202
- def __build_block_run(self, block, index: int, child_data_list: List[Tuple]) -> Tuple:
611
+ def __build_block_run(
612
+ self,
613
+ wrapper: DynamicBlockWrapper,
614
+ index: int,
615
+ child_data_list: List[Tuple],
616
+ ) -> Tuple:
203
617
  metadata = {}
204
618
  dynamic_block_indexes = None
205
619
  block_uuids = []
206
620
  upstream_blocks = []
207
621
  dynamic_upstream_block_uuids = []
208
622
  upstream_block_uuids_for_dynamic_block_uuid = []
623
+ parent_indexes = []
209
624
 
210
625
  for tup in child_data_list:
211
626
  parent_block_uuid, parent_index, metadata_inner, extra_settings = tup
@@ -216,6 +631,8 @@ class DynamicChildBlockFactory:
216
631
  extra_settings.get('dynamic_upstream_block_uuids') or [],
217
632
  )
218
633
 
634
+ # Don’t include this in the naming constructor if the block creating this child or
635
+ # spawn is from itself.
219
636
  block_uuid_prefix = str(parent_index) if parent_index is not None else None
220
637
  if 'block_uuid_prefix' in extra_settings:
221
638
  block_uuid_prefix = extra_settings.get('block_uuid_prefix')
@@ -235,6 +652,7 @@ class DynamicChildBlockFactory:
235
652
  if dynamic_block_indexes is None:
236
653
  dynamic_block_indexes = {}
237
654
  dynamic_block_indexes[parent_block_uuid] = parent_index
655
+ parent_indexes.append(parent_index)
238
656
 
239
657
  metadata_for_uuid = {}
240
658
  if any([uuid is not None for uuid in block_uuids]):
@@ -242,13 +660,55 @@ class DynamicChildBlockFactory:
242
660
  [uuid or str(idx) for idx, uuid in enumerate(block_uuids)],
243
661
  )
244
662
 
245
- block_uuid = dynamic_block_uuid(
246
- block.uuid,
663
+ # The parent_indexes are a list representation of dynamic_block_indexes.
664
+ # dynamic_block_indexes is used to determine what folder to retrieve the output
665
+ # variables from when fetching input data from an upstream dynamic or dynamic child block.
666
+ # We need parent_indexes to create a unique combination of values when constructing
667
+ # the block run block UUID.
668
+ if parent_indexes and \
669
+ len(parent_indexes) >= len(upstream_block_uuids_for_dynamic_block_uuid):
670
+
671
+ upstream_block_uuids_for_dynamic_block_uuid = parent_indexes
672
+
673
+ base_block_uuid = wrapper.block_uuid
674
+ block_uuid = build_dynamic_block_uuid(
675
+ base_block_uuid,
247
676
  metadata_for_uuid,
248
677
  index=index,
249
678
  upstream_block_uuids=upstream_block_uuids_for_dynamic_block_uuid,
250
679
  )
251
680
 
681
+ DX_PRINTER.critical(
682
+ 'Dynamic block UUID',
683
+ block=wrapper.block,
684
+ block_uuid=block_uuid,
685
+ index=index,
686
+ metadata_for_uuid=metadata_for_uuid,
687
+ upstream_block_uuids=upstream_block_uuids_for_dynamic_block_uuid,
688
+ wrapper_block_uuid=wrapper.block_uuid,
689
+ wrapper_uuid=wrapper.uuid,
690
+ )
691
+
692
+ clone_original = \
693
+ wrapper.metadata_instructions and wrapper.metadata_instructions.clone_original
694
+ if clone_original:
695
+ metadata.update(wrapper.to_dict(use_metadata_instructions=True))
696
+ block_uuid = ':'.join([
697
+ base_block_uuid,
698
+ 'clone',
699
+ ] + block_uuid.split(':')[2:])
700
+
701
+ DX_PRINTER.critical(
702
+ 'Dynamic block UUID clone of original',
703
+ block=wrapper.block,
704
+ block_uuid=block_uuid,
705
+ index=index,
706
+ metadata_for_uuid=metadata_for_uuid,
707
+ upstream_block_uuids=upstream_block_uuids_for_dynamic_block_uuid,
708
+ wrapper_block_uuid=wrapper.block_uuid,
709
+ wrapper_uuid=wrapper.uuid,
710
+ )
711
+
252
712
  metrics = dict(
253
713
  dynamic_block_index=index,
254
714
  )