mage-ai 0.9.69__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 (624) 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/BackfillPolicy.py +1 -0
  6. mage_ai/api/policies/BlockOutputPolicy.py +40 -17
  7. mage_ai/api/policies/GlobalDataProductPolicy.py +91 -41
  8. mage_ai/api/policies/KernelPolicy.py +55 -32
  9. mage_ai/api/policies/KernelProcessPolicy.py +56 -0
  10. mage_ai/api/policies/OutputPolicy.py +73 -41
  11. mage_ai/api/policies/PipelinePolicy.py +206 -137
  12. mage_ai/api/policies/WorkspacePolicy.py +1 -0
  13. mage_ai/api/presenters/BackfillPresenter.py +1 -0
  14. mage_ai/api/presenters/BlockLayoutItemPresenter.py +9 -7
  15. mage_ai/api/presenters/BlockPresenter.py +1 -1
  16. mage_ai/api/presenters/GlobalDataProductPresenter.py +6 -1
  17. mage_ai/api/presenters/KernelPresenter.py +5 -26
  18. mage_ai/api/presenters/KernelProcessPresenter.py +28 -0
  19. mage_ai/api/presenters/PipelinePresenter.py +18 -5
  20. mage_ai/api/presenters/StatusPresenter.py +2 -0
  21. mage_ai/api/presenters/SyncPresenter.py +25 -0
  22. mage_ai/api/resources/AutocompleteItemResource.py +1 -1
  23. mage_ai/api/resources/BlockLayoutItemResource.py +90 -44
  24. mage_ai/api/resources/BlockOutputResource.py +42 -9
  25. mage_ai/api/resources/BlockResource.py +4 -3
  26. mage_ai/api/resources/BlockRunResource.py +27 -22
  27. mage_ai/api/resources/ClusterResource.py +4 -1
  28. mage_ai/api/resources/CustomTemplateResource.py +34 -14
  29. mage_ai/api/resources/DataProviderResource.py +1 -1
  30. mage_ai/api/resources/ExecutionStateResource.py +3 -1
  31. mage_ai/api/resources/FileContentResource.py +8 -2
  32. mage_ai/api/resources/FileResource.py +10 -4
  33. mage_ai/api/resources/FileVersionResource.py +3 -1
  34. mage_ai/api/resources/GitBranchResource.py +101 -31
  35. mage_ai/api/resources/GitCustomBranchResource.py +29 -1
  36. mage_ai/api/resources/GlobalDataProductResource.py +44 -7
  37. mage_ai/api/resources/GlobalHookResource.py +4 -1
  38. mage_ai/api/resources/IntegrationDestinationResource.py +6 -2
  39. mage_ai/api/resources/IntegrationSourceResource.py +8 -4
  40. mage_ai/api/resources/IntegrationSourceStreamResource.py +6 -2
  41. mage_ai/api/resources/KernelProcessResource.py +44 -0
  42. mage_ai/api/resources/KernelResource.py +25 -3
  43. mage_ai/api/resources/OauthResource.py +1 -1
  44. mage_ai/api/resources/OutputResource.py +33 -11
  45. mage_ai/api/resources/PageBlockLayoutResource.py +34 -23
  46. mage_ai/api/resources/PipelineInteractionResource.py +31 -15
  47. mage_ai/api/resources/PipelineResource.py +258 -125
  48. mage_ai/api/resources/PipelineRunResource.py +52 -7
  49. mage_ai/api/resources/PipelineScheduleResource.py +11 -2
  50. mage_ai/api/resources/PipelineTriggerResource.py +6 -1
  51. mage_ai/api/resources/ProjectResource.py +18 -7
  52. mage_ai/api/resources/PullRequestResource.py +6 -4
  53. mage_ai/api/resources/SecretResource.py +1 -1
  54. mage_ai/api/resources/SeedResource.py +8 -1
  55. mage_ai/api/resources/StatusResource.py +21 -6
  56. mage_ai/api/resources/SyncResource.py +6 -8
  57. mage_ai/api/resources/VariableResource.py +46 -26
  58. mage_ai/api/resources/VersionControlProjectResource.py +9 -2
  59. mage_ai/api/resources/WidgetResource.py +1 -1
  60. mage_ai/api/resources/WorkspaceResource.py +6 -5
  61. mage_ai/api/views.py +47 -40
  62. mage_ai/authentication/permissions/seed.py +16 -2
  63. mage_ai/authentication/providers/oidc.py +21 -1
  64. mage_ai/autocomplete/utils.py +13 -9
  65. mage_ai/cache/base.py +1 -1
  66. mage_ai/cache/block.py +18 -12
  67. mage_ai/cache/block_action_object/__init__.py +33 -5
  68. mage_ai/cache/file.py +22 -19
  69. mage_ai/cache/pipeline.py +18 -12
  70. mage_ai/cli/main.py +1 -0
  71. mage_ai/cluster_manager/aws/emr_cluster_manager.py +9 -5
  72. mage_ai/cluster_manager/config.py +2 -2
  73. mage_ai/cluster_manager/kubernetes/workload_manager.py +52 -1
  74. mage_ai/cluster_manager/manage.py +1 -1
  75. mage_ai/cluster_manager/workspace/base.py +7 -1
  76. mage_ai/cluster_manager/workspace/kubernetes.py +22 -1
  77. mage_ai/command_center/applications/factory.py +10 -7
  78. mage_ai/command_center/applications/utils.py +2 -2
  79. mage_ai/command_center/files/factory.py +17 -15
  80. mage_ai/command_center/presenters/text.py +1 -1
  81. mage_ai/command_center/utils.py +25 -13
  82. mage_ai/data/__init__.py +0 -0
  83. mage_ai/data/constants.py +45 -0
  84. mage_ai/data/models/__init__.py +0 -0
  85. mage_ai/data/models/base.py +119 -0
  86. mage_ai/data/models/constants.py +1 -0
  87. mage_ai/data/models/generator.py +115 -0
  88. mage_ai/data/models/manager.py +168 -0
  89. mage_ai/data/models/pyarrow/__init__.py +0 -0
  90. mage_ai/data/models/pyarrow/record_batch.py +55 -0
  91. mage_ai/data/models/pyarrow/shared.py +21 -0
  92. mage_ai/data/models/pyarrow/table.py +8 -0
  93. mage_ai/data/models/reader.py +103 -0
  94. mage_ai/data/models/utils.py +59 -0
  95. mage_ai/data/models/writer.py +91 -0
  96. mage_ai/data/tabular/__init__.py +0 -0
  97. mage_ai/data/tabular/constants.py +23 -0
  98. mage_ai/data/tabular/mocks.py +19 -0
  99. mage_ai/data/tabular/models.py +126 -0
  100. mage_ai/data/tabular/reader.py +602 -0
  101. mage_ai/data/tabular/utils.py +102 -0
  102. mage_ai/data/tabular/writer.py +266 -0
  103. mage_ai/data/variables/__init__.py +0 -0
  104. mage_ai/data/variables/wrapper.py +54 -0
  105. mage_ai/data_cleaner/analysis/charts.py +61 -39
  106. mage_ai/data_cleaner/column_types/column_type_detector.py +53 -31
  107. mage_ai/data_cleaner/estimators/encoders.py +5 -2
  108. mage_ai/data_integrations/utils/scheduler.py +16 -11
  109. mage_ai/data_preparation/decorators.py +1 -0
  110. mage_ai/data_preparation/executors/block_executor.py +237 -155
  111. mage_ai/data_preparation/executors/k8s_block_executor.py +30 -7
  112. mage_ai/data_preparation/executors/k8s_pipeline_executor.py +30 -7
  113. mage_ai/data_preparation/executors/streaming_pipeline_executor.py +2 -2
  114. mage_ai/data_preparation/git/__init__.py +77 -29
  115. mage_ai/data_preparation/git/api.py +69 -8
  116. mage_ai/data_preparation/git/utils.py +64 -34
  117. mage_ai/data_preparation/logging/logger_manager.py +4 -3
  118. mage_ai/data_preparation/models/block/__init__.py +1562 -879
  119. mage_ai/data_preparation/models/block/data_integration/mixins.py +4 -3
  120. mage_ai/data_preparation/models/block/dynamic/__init__.py +17 -6
  121. mage_ai/data_preparation/models/block/dynamic/child.py +41 -102
  122. mage_ai/data_preparation/models/block/dynamic/constants.py +1 -0
  123. mage_ai/data_preparation/models/block/dynamic/counter.py +296 -0
  124. mage_ai/data_preparation/models/block/dynamic/data.py +16 -0
  125. mage_ai/data_preparation/models/block/dynamic/factory.py +163 -0
  126. mage_ai/data_preparation/models/block/dynamic/models.py +19 -0
  127. mage_ai/data_preparation/models/block/dynamic/shared.py +92 -0
  128. mage_ai/data_preparation/models/block/dynamic/utils.py +295 -167
  129. mage_ai/data_preparation/models/block/dynamic/variables.py +384 -144
  130. mage_ai/data_preparation/models/block/dynamic/wrappers.py +77 -0
  131. mage_ai/data_preparation/models/block/extension/utils.py +10 -1
  132. mage_ai/data_preparation/models/block/global_data_product/__init__.py +35 -3
  133. mage_ai/data_preparation/models/block/integration/__init__.py +6 -2
  134. mage_ai/data_preparation/models/block/outputs.py +722 -0
  135. mage_ai/data_preparation/models/block/platform/mixins.py +7 -8
  136. mage_ai/data_preparation/models/block/r/__init__.py +56 -38
  137. mage_ai/data_preparation/models/block/remote/__init__.py +0 -0
  138. mage_ai/data_preparation/models/block/remote/models.py +58 -0
  139. mage_ai/data_preparation/models/block/settings/__init__.py +0 -0
  140. mage_ai/data_preparation/models/block/settings/dynamic/__init__.py +0 -0
  141. mage_ai/data_preparation/models/block/settings/dynamic/constants.py +7 -0
  142. mage_ai/data_preparation/models/block/settings/dynamic/mixins.py +118 -0
  143. mage_ai/data_preparation/models/block/settings/dynamic/models.py +31 -0
  144. mage_ai/data_preparation/models/block/settings/global_data_products/__init__.py +0 -0
  145. mage_ai/data_preparation/models/block/settings/global_data_products/mixins.py +20 -0
  146. mage_ai/data_preparation/models/block/settings/global_data_products/models.py +46 -0
  147. mage_ai/data_preparation/models/block/settings/variables/__init__.py +0 -0
  148. mage_ai/data_preparation/models/block/settings/variables/mixins.py +74 -0
  149. mage_ai/data_preparation/models/block/settings/variables/models.py +49 -0
  150. mage_ai/data_preparation/models/block/spark/mixins.py +2 -1
  151. mage_ai/data_preparation/models/block/sql/__init__.py +30 -5
  152. mage_ai/data_preparation/models/block/sql/utils/shared.py +21 -3
  153. mage_ai/data_preparation/models/block/utils.py +164 -69
  154. mage_ai/data_preparation/models/constants.py +21 -14
  155. mage_ai/data_preparation/models/custom_templates/custom_block_template.py +18 -13
  156. mage_ai/data_preparation/models/custom_templates/custom_pipeline_template.py +33 -16
  157. mage_ai/data_preparation/models/custom_templates/utils.py +1 -1
  158. mage_ai/data_preparation/models/file.py +41 -28
  159. mage_ai/data_preparation/models/global_data_product/__init__.py +100 -58
  160. mage_ai/data_preparation/models/global_hooks/models.py +1 -0
  161. mage_ai/data_preparation/models/interfaces.py +29 -0
  162. mage_ai/data_preparation/models/pipeline.py +374 -185
  163. mage_ai/data_preparation/models/pipelines/integration_pipeline.py +1 -2
  164. mage_ai/data_preparation/models/pipelines/seed.py +1 -1
  165. mage_ai/data_preparation/models/project/__init__.py +66 -18
  166. mage_ai/data_preparation/models/project/constants.py +2 -0
  167. mage_ai/data_preparation/models/triggers/__init__.py +124 -26
  168. mage_ai/data_preparation/models/utils.py +467 -17
  169. mage_ai/data_preparation/models/variable.py +1028 -137
  170. mage_ai/data_preparation/models/variables/__init__.py +0 -0
  171. mage_ai/data_preparation/models/variables/cache.py +149 -0
  172. mage_ai/data_preparation/models/variables/constants.py +72 -0
  173. mage_ai/data_preparation/models/variables/summarizer.py +336 -0
  174. mage_ai/data_preparation/models/variables/utils.py +77 -0
  175. mage_ai/data_preparation/models/widget/__init__.py +63 -41
  176. mage_ai/data_preparation/models/widget/charts.py +40 -27
  177. mage_ai/data_preparation/models/widget/constants.py +2 -0
  178. mage_ai/data_preparation/models/widget/utils.py +3 -3
  179. mage_ai/data_preparation/preferences.py +3 -3
  180. mage_ai/data_preparation/repo_manager.py +55 -21
  181. mage_ai/data_preparation/storage/base_storage.py +2 -2
  182. mage_ai/data_preparation/storage/gcs_storage.py +7 -4
  183. mage_ai/data_preparation/storage/local_storage.py +18 -9
  184. mage_ai/data_preparation/storage/s3_storage.py +5 -2
  185. mage_ai/data_preparation/templates/data_exporters/streaming/oracledb.yaml +8 -0
  186. mage_ai/data_preparation/variable_manager.py +281 -76
  187. mage_ai/io/base.py +3 -2
  188. mage_ai/io/bigquery.py +1 -0
  189. mage_ai/io/redshift.py +7 -5
  190. mage_ai/kernels/__init__.py +0 -0
  191. mage_ai/kernels/models.py +188 -0
  192. mage_ai/kernels/utils.py +169 -0
  193. mage_ai/orchestration/concurrency.py +6 -2
  194. mage_ai/orchestration/db/__init__.py +1 -0
  195. mage_ai/orchestration/db/migrations/versions/0227396a216c_add_userproject_table.py +38 -0
  196. mage_ai/orchestration/db/migrations/versions/42a14d6143f1_update_token_column_type.py +54 -0
  197. mage_ai/orchestration/db/models/dynamic/__init__.py +0 -0
  198. mage_ai/orchestration/db/models/dynamic/controller.py +67 -0
  199. mage_ai/orchestration/db/models/oauth.py +12 -18
  200. mage_ai/orchestration/db/models/projects.py +10 -0
  201. mage_ai/orchestration/db/models/schedules.py +225 -187
  202. mage_ai/orchestration/db/models/schedules_project_platform.py +18 -12
  203. mage_ai/orchestration/db/models/utils.py +46 -5
  204. mage_ai/orchestration/metrics/pipeline_run.py +8 -9
  205. mage_ai/orchestration/notification/sender.py +38 -15
  206. mage_ai/orchestration/pipeline_scheduler_original.py +64 -33
  207. mage_ai/orchestration/pipeline_scheduler_project_platform.py +1 -1
  208. mage_ai/orchestration/run_status_checker.py +11 -4
  209. mage_ai/orchestration/triggers/api.py +41 -2
  210. mage_ai/orchestration/triggers/global_data_product.py +9 -4
  211. mage_ai/orchestration/triggers/utils.py +10 -1
  212. mage_ai/orchestration/utils/resources.py +3 -0
  213. mage_ai/presenters/charts/data_sources/base.py +4 -2
  214. mage_ai/presenters/charts/data_sources/block.py +15 -9
  215. mage_ai/presenters/charts/data_sources/chart_code.py +8 -5
  216. mage_ai/presenters/charts/data_sources/constants.py +1 -0
  217. mage_ai/presenters/charts/data_sources/system_metrics.py +22 -0
  218. mage_ai/presenters/interactions/models.py +11 -7
  219. mage_ai/presenters/pages/loaders/pipelines.py +5 -3
  220. mage_ai/presenters/pages/models/page_components/pipeline_schedules.py +3 -1
  221. mage_ai/presenters/utils.py +2 -0
  222. mage_ai/server/api/blocks.py +2 -1
  223. mage_ai/server/api/downloads.py +9 -2
  224. mage_ai/server/api/runs.py +151 -0
  225. mage_ai/server/api/triggers.py +3 -1
  226. mage_ai/server/constants.py +1 -1
  227. mage_ai/server/frontend_dist/404.html +8 -8
  228. mage_ai/server/frontend_dist/_next/static/UZLabyPgcxtZvp0O0EUUS/_buildManifest.js +1 -0
  229. mage_ai/server/frontend_dist/_next/static/chunks/1376-22de38b4ad008d8a.js +1 -0
  230. mage_ai/server/frontend_dist/_next/static/chunks/1557-25a7d985d5564fd3.js +1 -0
  231. mage_ai/server/frontend_dist/_next/static/chunks/1668-30b4619b9534519b.js +1 -0
  232. mage_ai/server/frontend_dist/_next/static/chunks/1799-c42db95a015689ee.js +1 -0
  233. mage_ai/server/frontend_dist/_next/static/chunks/2996-2108b53b9d371d8d.js +1 -0
  234. mage_ai/server/frontend_dist/_next/static/chunks/{3548-fa0792ddb88f4646.js → 3548-9d26185b3fb663b1.js} +1 -1
  235. mage_ai/server/frontend_dist/_next/static/chunks/{3763-61b542dafdbf5754.js → 3763-40780c6d1e4b261d.js} +1 -1
  236. mage_ai/server/frontend_dist/_next/static/chunks/3782-129dd2a2448a2e36.js +1 -0
  237. mage_ai/server/frontend_dist/_next/static/chunks/3958-bcdfa414ccfa1eb2.js +1 -0
  238. mage_ai/server/frontend_dist/_next/static/chunks/4168-97fd1578d1a38315.js +1 -0
  239. mage_ai/server/frontend_dist/_next/static/chunks/4982-fa5a238b139fbdd2.js +1 -0
  240. mage_ai/server/frontend_dist/_next/static/chunks/5699-176f445e1313f001.js +1 -0
  241. mage_ai/server/frontend_dist/_next/static/chunks/7162-7dd03f0f605de721.js +1 -0
  242. mage_ai/server/frontend_dist/_next/static/chunks/7779-68d2b72a90c5f925.js +1 -0
  243. mage_ai/server/frontend_dist/_next/static/chunks/7966-5446a8e43711e2f9.js +1 -0
  244. mage_ai/server/frontend_dist/_next/static/chunks/8023-6c2f172f48dcb99b.js +1 -0
  245. mage_ai/server/frontend_dist/_next/static/chunks/8095-c351b8a735d73e0c.js +1 -0
  246. mage_ai/server/frontend_dist/_next/static/chunks/9624-8b8e100079ab69e1.js +1 -0
  247. mage_ai/server/frontend_dist/_next/static/chunks/{main-77fe248a6fbd12d8.js → main-b99d4e30a88d9dc7.js} +1 -1
  248. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-9fe2d9d07c94e968.js +1 -0
  249. mage_ai/server/frontend_dist/_next/static/chunks/pages/{block-layout-14f952f66964022f.js → block-layout-7f4b735c67115df5.js} +1 -1
  250. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-e7d48e6b0c3068ac.js +1 -0
  251. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products-b943f31f050fc3a4.js +1 -0
  252. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-4bfc84ff07d7656f.js +1 -0
  253. mage_ai/server/frontend_dist/_next/static/chunks/pages/{overview-597b74828bf105db.js → overview-9f1ac4ec003884f3.js} +1 -1
  254. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-3edc6270c5b0e962.js → frontend_dist/_next/static/chunks/pages/pipeline-runs-6d183f91a2ff6668.js} +1 -1
  255. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-7e737f6fc7e83e9b.js +1 -0
  256. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-38e1fbcfbfc1014e.js +1 -0
  257. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-d94488e3f2eeef36.js +1 -0
  258. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-cc641a7fa8473796.js +1 -0
  259. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-a5c0362763a21fa8.js → block-runs-284309877f3c5a5a.js} +1 -1
  260. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-26250e5335194ade.js +1 -0
  261. 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
  262. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-4ebfc8e400315dda.js +1 -0
  263. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-e5e0150a256aadb3.js +1 -0
  264. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-eb11c5390c982b49.js +1 -0
  265. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{triggers-1bdfda8edc9cf4a8.js → triggers-4612d15a65c35912.js} +1 -1
  266. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/{profile-3f0df3decc856ee9.js → profile-3ae43c932537b254.js} +1 -1
  267. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-b603d7fe4b175256.js +1 -0
  268. 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
  269. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-47b64ced27c24985.js → [...slug]-5c360f72e4498855.js} +1 -1
  270. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{permissions-e5a4d3d815cec25d.js → permissions-fb29fa6c2bd90bb0.js} +1 -1
  271. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-3b76fa959ffa09d3.js +1 -0
  272. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-379e1ee292504842.js → [...slug]-3b787b42f1093b1f.js} +1 -1
  273. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-0b83fbdd39e85f5b.js +1 -0
  274. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-a1e6950974d643a8.js +1 -0
  275. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-2af9afbe727d88aa.js → [...slug]-0aa019d87db8b0b8.js} +1 -1
  276. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{users-a4db8710f703c729.js → users-88c694d19207f2ec.js} +1 -1
  277. mage_ai/server/frontend_dist/_next/static/chunks/pages/{triggers-9cba3211434a8966.js → triggers-a599c6ac89be8c8d.js} +1 -1
  278. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-31d0d50f7f30462b.js +1 -0
  279. mage_ai/server/frontend_dist/_next/static/chunks/{webpack-d079359c241db804.js → webpack-ac7fdc472bedf682.js} +1 -1
  280. mage_ai/server/frontend_dist/block-layout.html +3 -3
  281. mage_ai/server/frontend_dist/compute.html +6 -6
  282. mage_ai/server/frontend_dist/files.html +6 -6
  283. mage_ai/server/frontend_dist/global-data-products/[...slug].html +6 -6
  284. mage_ai/server/frontend_dist/global-data-products.html +6 -6
  285. mage_ai/server/frontend_dist/global-hooks/[...slug].html +6 -6
  286. mage_ai/server/frontend_dist/global-hooks.html +6 -6
  287. mage_ai/server/frontend_dist/index.html +3 -3
  288. mage_ai/server/frontend_dist/manage/files.html +6 -6
  289. mage_ai/server/frontend_dist/manage/settings.html +6 -6
  290. mage_ai/server/frontend_dist/manage/users/[user].html +6 -6
  291. mage_ai/server/frontend_dist/manage/users/new.html +6 -6
  292. mage_ai/server/frontend_dist/manage/users.html +6 -6
  293. mage_ai/server/frontend_dist/manage.html +6 -6
  294. mage_ai/server/frontend_dist/oauth.html +5 -5
  295. mage_ai/server/frontend_dist/overview.html +6 -6
  296. mage_ai/server/frontend_dist/pipeline-runs.html +6 -6
  297. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +6 -6
  298. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +6 -6
  299. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +6 -6
  300. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +3 -3
  301. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +6 -6
  302. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +6 -6
  303. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
  304. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +6 -6
  305. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +6 -6
  306. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +6 -6
  307. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +6 -6
  308. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +6 -6
  309. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +6 -6
  310. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +6 -6
  311. mage_ai/server/frontend_dist/pipelines/[pipeline].html +3 -3
  312. mage_ai/server/frontend_dist/pipelines.html +6 -6
  313. mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +6 -6
  314. mage_ai/server/frontend_dist/platform/global-hooks.html +6 -6
  315. mage_ai/server/frontend_dist/settings/account/profile.html +6 -6
  316. mage_ai/server/frontend_dist/settings/platform/preferences.html +6 -6
  317. mage_ai/server/frontend_dist/settings/platform/settings.html +6 -6
  318. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +6 -6
  319. mage_ai/server/frontend_dist/settings/workspace/permissions.html +6 -6
  320. mage_ai/server/frontend_dist/settings/workspace/preferences.html +6 -6
  321. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +6 -6
  322. mage_ai/server/frontend_dist/settings/workspace/roles.html +6 -6
  323. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +6 -6
  324. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +6 -6
  325. mage_ai/server/frontend_dist/settings/workspace/users.html +6 -6
  326. mage_ai/server/frontend_dist/settings.html +3 -3
  327. mage_ai/server/frontend_dist/sign-in.html +15 -15
  328. mage_ai/server/frontend_dist/templates/[...slug].html +6 -6
  329. mage_ai/server/frontend_dist/templates.html +6 -6
  330. mage_ai/server/frontend_dist/terminal.html +6 -6
  331. mage_ai/server/frontend_dist/test.html +3 -3
  332. mage_ai/server/frontend_dist/triggers.html +6 -6
  333. mage_ai/server/frontend_dist/version-control.html +6 -6
  334. mage_ai/server/frontend_dist_base_path_template/404.html +8 -8
  335. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1376-22de38b4ad008d8a.js +1 -0
  336. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-25a7d985d5564fd3.js +1 -0
  337. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1668-30b4619b9534519b.js +1 -0
  338. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1799-c42db95a015689ee.js +1 -0
  339. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2996-2108b53b9d371d8d.js +1 -0
  340. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{3548-fa0792ddb88f4646.js → 3548-9d26185b3fb663b1.js} +1 -1
  341. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{3763-61b542dafdbf5754.js → 3763-40780c6d1e4b261d.js} +1 -1
  342. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-129dd2a2448a2e36.js +1 -0
  343. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3958-bcdfa414ccfa1eb2.js +1 -0
  344. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4168-97fd1578d1a38315.js +1 -0
  345. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4982-fa5a238b139fbdd2.js +1 -0
  346. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-176f445e1313f001.js +1 -0
  347. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7162-7dd03f0f605de721.js +1 -0
  348. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7779-68d2b72a90c5f925.js +1 -0
  349. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-5446a8e43711e2f9.js +1 -0
  350. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8023-6c2f172f48dcb99b.js +1 -0
  351. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-c351b8a735d73e0c.js +1 -0
  352. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9624-8b8e100079ab69e1.js +1 -0
  353. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{main-70b78159c2bb3fe1.js → main-384298e9133cec76.js} +1 -1
  354. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-13a578bce3b7f30c.js +1 -0
  355. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{block-layout-14f952f66964022f.js → block-layout-7f4b735c67115df5.js} +1 -1
  356. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-e7d48e6b0c3068ac.js +1 -0
  357. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products-b943f31f050fc3a4.js +1 -0
  358. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-4bfc84ff07d7656f.js +1 -0
  359. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{overview-597b74828bf105db.js → overview-9f1ac4ec003884f3.js} +1 -1
  360. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipeline-runs-3edc6270c5b0e962.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-6d183f91a2ff6668.js} +1 -1
  361. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-7e737f6fc7e83e9b.js +1 -0
  362. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-38e1fbcfbfc1014e.js +1 -0
  363. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-d94488e3f2eeef36.js +1 -0
  364. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-cc641a7fa8473796.js +1 -0
  365. 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
  366. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-26250e5335194ade.js +1 -0
  367. 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
  368. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-4ebfc8e400315dda.js +1 -0
  369. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-e5e0150a256aadb3.js +1 -0
  370. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-eb11c5390c982b49.js +1 -0
  371. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{triggers-1bdfda8edc9cf4a8.js → triggers-4612d15a65c35912.js} +1 -1
  372. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/{profile-3f0df3decc856ee9.js → profile-3ae43c932537b254.js} +1 -1
  373. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-b603d7fe4b175256.js +1 -0
  374. 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
  375. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-47b64ced27c24985.js → [...slug]-5c360f72e4498855.js} +1 -1
  376. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{permissions-e5a4d3d815cec25d.js → permissions-fb29fa6c2bd90bb0.js} +1 -1
  377. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-3b76fa959ffa09d3.js +1 -0
  378. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-379e1ee292504842.js → [...slug]-3b787b42f1093b1f.js} +1 -1
  379. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-0b83fbdd39e85f5b.js +1 -0
  380. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-a1e6950974d643a8.js +1 -0
  381. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-2af9afbe727d88aa.js → [...slug]-0aa019d87db8b0b8.js} +1 -1
  382. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{users-a4db8710f703c729.js → users-88c694d19207f2ec.js} +1 -1
  383. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{triggers-9cba3211434a8966.js → triggers-a599c6ac89be8c8d.js} +1 -1
  384. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-31d0d50f7f30462b.js +1 -0
  385. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-68c003fb6a175cd7.js → webpack-481689d9989710cd.js} +1 -1
  386. mage_ai/server/frontend_dist_base_path_template/_next/static/kcptwoOU-JJJg6Vwpkfmx/_buildManifest.js +1 -0
  387. mage_ai/server/frontend_dist_base_path_template/block-layout.html +3 -3
  388. mage_ai/server/frontend_dist_base_path_template/compute.html +6 -6
  389. mage_ai/server/frontend_dist_base_path_template/files.html +6 -6
  390. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +6 -6
  391. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +6 -6
  392. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +6 -6
  393. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +6 -6
  394. mage_ai/server/frontend_dist_base_path_template/index.html +3 -3
  395. mage_ai/server/frontend_dist_base_path_template/manage/files.html +6 -6
  396. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +6 -6
  397. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +6 -6
  398. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +6 -6
  399. mage_ai/server/frontend_dist_base_path_template/manage/users.html +6 -6
  400. mage_ai/server/frontend_dist_base_path_template/manage.html +6 -6
  401. mage_ai/server/frontend_dist_base_path_template/oauth.html +5 -5
  402. mage_ai/server/frontend_dist_base_path_template/overview.html +6 -6
  403. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +6 -6
  404. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +6 -6
  405. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +6 -6
  406. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +6 -6
  407. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +3 -3
  408. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +6 -6
  409. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +6 -6
  410. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
  411. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +6 -6
  412. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +6 -6
  413. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +6 -6
  414. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +6 -6
  415. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +6 -6
  416. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +6 -6
  417. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +6 -6
  418. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +3 -3
  419. mage_ai/server/frontend_dist_base_path_template/pipelines.html +6 -6
  420. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +6 -6
  421. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +6 -6
  422. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +6 -6
  423. mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +6 -6
  424. mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +6 -6
  425. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +6 -6
  426. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +6 -6
  427. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +6 -6
  428. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +6 -6
  429. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +6 -6
  430. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +6 -6
  431. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +6 -6
  432. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +6 -6
  433. mage_ai/server/frontend_dist_base_path_template/settings.html +3 -3
  434. mage_ai/server/frontend_dist_base_path_template/sign-in.html +15 -15
  435. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +6 -6
  436. mage_ai/server/frontend_dist_base_path_template/templates.html +6 -6
  437. mage_ai/server/frontend_dist_base_path_template/terminal.html +6 -6
  438. mage_ai/server/frontend_dist_base_path_template/test.html +3 -3
  439. mage_ai/server/frontend_dist_base_path_template/triggers.html +6 -6
  440. mage_ai/server/frontend_dist_base_path_template/version-control.html +6 -6
  441. mage_ai/server/kernel_output_parser.py +4 -1
  442. mage_ai/server/scheduler_manager.py +12 -1
  443. mage_ai/server/server.py +69 -42
  444. mage_ai/server/utils/custom_output.py +284 -0
  445. mage_ai/server/utils/execute_custom_code.py +245 -0
  446. mage_ai/server/utils/output_display.py +123 -289
  447. mage_ai/server/websocket_server.py +116 -69
  448. mage_ai/services/aws/ecs/ecs.py +1 -0
  449. mage_ai/services/k8s/config.py +27 -4
  450. mage_ai/services/k8s/job_manager.py +6 -1
  451. mage_ai/services/k8s/utils.py +97 -0
  452. mage_ai/services/ssh/aws/emr/utils.py +8 -8
  453. mage_ai/settings/keys/auth.py +1 -0
  454. mage_ai/settings/platform/__init__.py +159 -38
  455. mage_ai/settings/platform/constants.py +5 -0
  456. mage_ai/settings/platform/utils.py +53 -10
  457. mage_ai/settings/repo.py +26 -12
  458. mage_ai/settings/server.py +128 -37
  459. mage_ai/shared/array.py +24 -1
  460. mage_ai/shared/complex.py +45 -0
  461. mage_ai/shared/config.py +2 -1
  462. mage_ai/shared/custom_logger.py +11 -0
  463. mage_ai/shared/dates.py +10 -6
  464. mage_ai/shared/files.py +63 -8
  465. mage_ai/shared/hash.py +33 -9
  466. mage_ai/shared/io.py +9 -5
  467. mage_ai/shared/models.py +82 -24
  468. mage_ai/shared/outputs.py +87 -0
  469. mage_ai/shared/parsers.py +144 -13
  470. mage_ai/shared/path_fixer.py +11 -7
  471. mage_ai/shared/singletons/__init__.py +0 -0
  472. mage_ai/shared/singletons/base.py +47 -0
  473. mage_ai/shared/singletons/memory.py +38 -0
  474. mage_ai/shared/strings.py +34 -1
  475. mage_ai/shared/yaml.py +24 -0
  476. mage_ai/streaming/sinks/oracledb.py +57 -0
  477. mage_ai/streaming/sinks/sink_factory.py +4 -0
  478. mage_ai/system/__init__.py +0 -0
  479. mage_ai/system/constants.py +14 -0
  480. mage_ai/system/memory/__init__.py +0 -0
  481. mage_ai/system/memory/constants.py +1 -0
  482. mage_ai/system/memory/manager.py +174 -0
  483. mage_ai/system/memory/presenters.py +158 -0
  484. mage_ai/system/memory/process.py +216 -0
  485. mage_ai/system/memory/samples.py +13 -0
  486. mage_ai/system/memory/utils.py +656 -0
  487. mage_ai/system/memory/wrappers.py +177 -0
  488. mage_ai/system/models.py +58 -0
  489. mage_ai/system/storage/__init__.py +0 -0
  490. mage_ai/system/storage/utils.py +29 -0
  491. mage_ai/tests/api/endpoints/mixins.py +2 -2
  492. mage_ai/tests/api/endpoints/test_blocks.py +2 -1
  493. mage_ai/tests/api/endpoints/test_custom_designs.py +4 -4
  494. mage_ai/tests/api/endpoints/test_pipeline_runs.py +2 -2
  495. mage_ai/tests/api/endpoints/test_projects.py +2 -1
  496. mage_ai/tests/api/operations/base/mixins.py +1 -1
  497. mage_ai/tests/api/operations/base/test_base.py +27 -27
  498. mage_ai/tests/api/operations/base/test_base_with_user_authentication.py +27 -27
  499. mage_ai/tests/api/operations/base/test_base_with_user_permissions.py +23 -23
  500. mage_ai/tests/api/operations/test_syncs.py +6 -4
  501. mage_ai/tests/api/resources/test_pipeline_resource.py +11 -4
  502. mage_ai/tests/authentication/oauth/test_utils.py +1 -1
  503. mage_ai/tests/authentication/providers/test_oidc.py +59 -0
  504. mage_ai/tests/base_test.py +2 -2
  505. mage_ai/tests/data/__init__.py +0 -0
  506. mage_ai/tests/data/models/__init__.py +0 -0
  507. mage_ai/tests/data_preparation/executors/test_block_executor.py +23 -16
  508. mage_ai/tests/data_preparation/git/test_git.py +4 -1
  509. mage_ai/tests/data_preparation/models/block/dynamic/test_combos.py +305 -0
  510. mage_ai/tests/data_preparation/models/block/dynamic/test_counter.py +212 -0
  511. mage_ai/tests/data_preparation/models/block/dynamic/test_factory.py +360 -0
  512. mage_ai/tests/data_preparation/models/block/dynamic/test_variables.py +332 -0
  513. mage_ai/tests/data_preparation/models/block/hook/test_hook_block.py +2 -2
  514. mage_ai/tests/data_preparation/models/block/platform/test_mixins.py +1 -1
  515. mage_ai/tests/data_preparation/models/block/sql/utils/test_shared.py +26 -1
  516. mage_ai/tests/data_preparation/models/block/test_global_data_product.py +5 -2
  517. mage_ai/tests/data_preparation/models/custom_templates/test_utils.py +5 -4
  518. mage_ai/tests/data_preparation/models/global_hooks/test_hook.py +3 -0
  519. mage_ai/tests/data_preparation/models/global_hooks/test_predicates.py +9 -3
  520. mage_ai/tests/data_preparation/models/test_block.py +115 -120
  521. mage_ai/tests/data_preparation/models/test_blocks_helper.py +114 -0
  522. mage_ai/tests/data_preparation/models/test_global_data_product.py +41 -24
  523. mage_ai/tests/data_preparation/models/test_pipeline.py +9 -6
  524. mage_ai/tests/data_preparation/models/test_project.py +4 -1
  525. mage_ai/tests/data_preparation/models/test_utils.py +80 -0
  526. mage_ai/tests/data_preparation/models/test_variable.py +242 -69
  527. mage_ai/tests/data_preparation/models/variables/__init__.py +0 -0
  528. mage_ai/tests/data_preparation/models/variables/test_summarizer.py +481 -0
  529. mage_ai/tests/data_preparation/storage/shared/__init__.py +0 -0
  530. mage_ai/tests/data_preparation/test_repo_manager.py +6 -7
  531. mage_ai/tests/data_preparation/test_variable_manager.py +57 -48
  532. mage_ai/tests/factory.py +64 -43
  533. mage_ai/tests/orchestration/db/models/test_schedules.py +3 -3
  534. mage_ai/tests/orchestration/db/models/test_schedules_dynamic_blocks.py +279 -0
  535. mage_ai/tests/orchestration/test_pipeline_scheduler.py +1 -0
  536. mage_ai/tests/orchestration/triggers/test_global_data_product.py +141 -138
  537. mage_ai/tests/orchestration/triggers/test_utils.py +3 -2
  538. mage_ai/tests/server/test_server.py +19 -0
  539. mage_ai/tests/services/k8s/test_job_manager.py +27 -6
  540. mage_ai/tests/streaming/sinks/test_oracledb.py +38 -0
  541. mage_ai/tests/test_shared.py +61 -0
  542. mage_ai/usage_statistics/logger.py +7 -2
  543. mage_ai/utils/code.py +33 -19
  544. mage_ai/version_control/branch/utils.py +2 -1
  545. mage_ai/version_control/models.py +3 -2
  546. {mage_ai-0.9.69.dist-info → mage_ai-0.9.71.dist-info}/METADATA +6 -3
  547. {mage_ai-0.9.69.dist-info → mage_ai-0.9.71.dist-info}/RECORD +555 -454
  548. mage_ai/data_preparation/models/global_data_product/constants.py +0 -6
  549. mage_ai/server/frontend_dist/_next/static/_krrrgup_C-dPOpX36S8I/_buildManifest.js +0 -1
  550. mage_ai/server/frontend_dist/_next/static/chunks/1557-df144fbd8b2208c3.js +0 -1
  551. mage_ai/server/frontend_dist/_next/static/chunks/2631-b9f9bea3f1cf906d.js +0 -1
  552. mage_ai/server/frontend_dist/_next/static/chunks/3782-ef4cd4f0b52072d0.js +0 -1
  553. mage_ai/server/frontend_dist/_next/static/chunks/4783-422429203610c318.js +0 -1
  554. mage_ai/server/frontend_dist/_next/static/chunks/5699-6d708c6b2153ea08.js +0 -1
  555. mage_ai/server/frontend_dist/_next/static/chunks/635-0d6b7c8804bcd2dc.js +0 -1
  556. mage_ai/server/frontend_dist/_next/static/chunks/7022-0d52dd8868621fb0.js +0 -1
  557. mage_ai/server/frontend_dist/_next/static/chunks/7361-8a23dd8360593e7a.js +0 -1
  558. mage_ai/server/frontend_dist/_next/static/chunks/7966-f07b2913f7326b50.js +0 -1
  559. mage_ai/server/frontend_dist/_next/static/chunks/8095-bdce03896ef9639a.js +0 -1
  560. mage_ai/server/frontend_dist/_next/static/chunks/8146-6bed4e7401e067e6.js +0 -1
  561. mage_ai/server/frontend_dist/_next/static/chunks/9265-d2a1aaec75ec69b8.js +0 -1
  562. mage_ai/server/frontend_dist/_next/static/chunks/9440-4069842b90d4b801.js +0 -1
  563. mage_ai/server/frontend_dist/_next/static/chunks/9624-59b2f803f9c88cd6.js +0 -1
  564. mage_ai/server/frontend_dist/_next/static/chunks/9832-67896490f6e8a014.js +0 -1
  565. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-d9c89527266296f7.js +0 -1
  566. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-591abd392dc50ed4.js +0 -1
  567. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products-78e8e88f2a757a18.js +0 -1
  568. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-852d403c7bda21b3.js +0 -1
  569. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-ff4bd7a8ec3bab40.js +0 -1
  570. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-a8b61d8d239fd16f.js +0 -1
  571. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-95ffcd3e2b27e567.js +0 -1
  572. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-e1dd1ed71d26c10d.js +0 -1
  573. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-1ed9045b2f1dfd65.js +0 -1
  574. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.js +0 -1
  575. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +0 -1
  576. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-f028ef3880ed856c.js +0 -1
  577. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-503049734a8b082f.js +0 -1
  578. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-5b26eeda8aed8a7b.js +0 -1
  579. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-36fa165a48af586b.js +0 -1
  580. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-8b793b3b696a2cd3.js +0 -1
  581. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-5753fac7c1bfdc88.js +0 -1
  582. mage_ai/server/frontend_dist_base_path_template/_next/static/KLL5mirre9d7_ZeEpaw3s/_buildManifest.js +0 -1
  583. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-df144fbd8b2208c3.js +0 -1
  584. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2631-b9f9bea3f1cf906d.js +0 -1
  585. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-ef4cd4f0b52072d0.js +0 -1
  586. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4783-422429203610c318.js +0 -1
  587. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-6d708c6b2153ea08.js +0 -1
  588. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/635-0d6b7c8804bcd2dc.js +0 -1
  589. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-0d52dd8868621fb0.js +0 -1
  590. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-8a23dd8360593e7a.js +0 -1
  591. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-f07b2913f7326b50.js +0 -1
  592. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-bdce03896ef9639a.js +0 -1
  593. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-6bed4e7401e067e6.js +0 -1
  594. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9265-d2a1aaec75ec69b8.js +0 -1
  595. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-4069842b90d4b801.js +0 -1
  596. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9624-59b2f803f9c88cd6.js +0 -1
  597. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9832-67896490f6e8a014.js +0 -1
  598. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-d9c89527266296f7.js +0 -1
  599. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-591abd392dc50ed4.js +0 -1
  600. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products-78e8e88f2a757a18.js +0 -1
  601. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-852d403c7bda21b3.js +0 -1
  602. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-ff4bd7a8ec3bab40.js +0 -1
  603. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-a8b61d8d239fd16f.js +0 -1
  604. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-95ffcd3e2b27e567.js +0 -1
  605. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-e1dd1ed71d26c10d.js +0 -1
  606. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-1ed9045b2f1dfd65.js +0 -1
  607. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.js +0 -1
  608. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +0 -1
  609. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-f028ef3880ed856c.js +0 -1
  610. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-503049734a8b082f.js +0 -1
  611. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-5b26eeda8aed8a7b.js +0 -1
  612. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-36fa165a48af586b.js +0 -1
  613. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-8b793b3b696a2cd3.js +0 -1
  614. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-5753fac7c1bfdc88.js +0 -1
  615. mage_ai/shared/memory.py +0 -90
  616. mage_ai/tests/data_preparation/models/block/dynamic/test_dynamic_helpers.py +0 -48
  617. /mage_ai/{tests/data_preparation/shared → ai/utils}/__init__.py +0 -0
  618. /mage_ai/server/frontend_dist/_next/static/{_krrrgup_C-dPOpX36S8I → UZLabyPgcxtZvp0O0EUUS}/_ssgManifest.js +0 -0
  619. /mage_ai/server/frontend_dist_base_path_template/_next/static/{KLL5mirre9d7_ZeEpaw3s → kcptwoOU-JJJg6Vwpkfmx}/_ssgManifest.js +0 -0
  620. /mage_ai/tests/data_preparation/{shared → storage/shared}/test_secrets.py +0 -0
  621. {mage_ai-0.9.69.dist-info → mage_ai-0.9.71.dist-info}/LICENSE +0 -0
  622. {mage_ai-0.9.69.dist-info → mage_ai-0.9.71.dist-info}/WHEEL +0 -0
  623. {mage_ai-0.9.69.dist-info → mage_ai-0.9.71.dist-info}/entry_points.txt +0 -0
  624. {mage_ai-0.9.69.dist-info → mage_ai-0.9.71.dist-info}/top_level.txt +0 -0
@@ -39,13 +39,22 @@ class PipelineScheduleProjectPlatformMixin:
39
39
  def repo_query_project_platform(cls):
40
40
  repo_paths = []
41
41
 
42
- queries = Project().repo_path_for_database_query('pipeline_schedules')
42
+ context_data = dict()
43
+ queries = Project(
44
+ context_data=context_data,
45
+ ).repo_path_for_database_query('pipeline_schedules')
43
46
  if queries:
44
47
  repo_paths.extend(queries)
45
48
 
46
- repo_paths.extend([d.get(
47
- 'full_path',
48
- ) for d in build_repo_path_for_all_projects(mage_projects_only=True).values()])
49
+ repo_paths.extend([
50
+ d.get(
51
+ 'full_path',
52
+ )
53
+ for d in build_repo_path_for_all_projects(
54
+ context_data=context_data,
55
+ mage_projects_only=True,
56
+ ).values()
57
+ ])
49
58
 
50
59
  return cls.query.filter(
51
60
  or_(
@@ -149,14 +158,11 @@ class PipelineScheduleProjectPlatformMixin:
149
158
 
150
159
  pipeline_use = pipeline or self.pipeline
151
160
  if not pipeline_use:
152
- try:
153
- Pipeline.get(self.pipeline_uuid)
154
- except Exception:
155
- print(
156
- f'[WARNING] Pipeline {self.pipeline_uuid} cannot be found '
157
- + f'for pipeline schedule ID {self.id}.',
158
- )
159
- return False
161
+ print(
162
+ f'[WARNING] Pipeline {self.pipeline_uuid} cannot be found '
163
+ + f'for pipeline schedule ID {self.id}.',
164
+ )
165
+ return False
160
166
 
161
167
  if self.schedule_interval == ScheduleInterval.ONCE:
162
168
  pipeline_run_count = self.pipeline_runs_count
@@ -1,13 +1,14 @@
1
1
  from mage_ai.orchestration.db import db_connection, safe_db_query
2
- from mage_ai.orchestration.db.models.schedules import (
3
- Backfill,
4
- PipelineRun,
5
- PipelineSchedule,
6
- )
7
2
 
8
3
 
9
4
  @safe_db_query
10
5
  def transfer_related_models_for_pipeline(old_uuid: str, new_uuid: str):
6
+ from mage_ai.orchestration.db.models.schedules import (
7
+ Backfill,
8
+ PipelineRun,
9
+ PipelineSchedule,
10
+ )
11
+
11
12
  # Migrate pipeline schedules
12
13
  PipelineSchedule.query.filter(PipelineSchedule.pipeline_uuid == old_uuid).update({
13
14
  PipelineSchedule.pipeline_uuid: new_uuid
@@ -21,3 +22,43 @@ def transfer_related_models_for_pipeline(old_uuid: str, new_uuid: str):
21
22
  Backfill.pipeline_uuid: new_uuid
22
23
  }, synchronize_session=False)
23
24
  db_connection.session.commit()
25
+
26
+
27
+ @safe_db_query
28
+ def get_active_project_for_user(user, root_project_uuid: str) -> str:
29
+ from mage_ai.orchestration.db.models.projects import UserProject
30
+ return UserProject.query.filter(
31
+ UserProject.user_id == user.id,
32
+ UserProject.root_project_uuid == root_project_uuid,
33
+ UserProject.active.is_(True),
34
+ ).one_or_none()
35
+
36
+
37
+ @safe_db_query
38
+ def activate_project_for_user(user, root_project_uuid: str, project_name: str):
39
+ from mage_ai.orchestration.db.models.projects import UserProject
40
+ projects = UserProject.query.filter(
41
+ UserProject.user_id == user.id,
42
+ UserProject.root_project_uuid == root_project_uuid,
43
+ )
44
+
45
+ projects.update({
46
+ UserProject.active: False
47
+ }, synchronize_session=False)
48
+
49
+ project_updated = False
50
+ for project in projects:
51
+ if project.project_name == project_name:
52
+ project.update(active=True, commit=False)
53
+ project_updated = True
54
+
55
+ if not project_updated:
56
+ UserProject.create(
57
+ user_id=user.id,
58
+ root_project_uuid=root_project_uuid,
59
+ project_name=project_name,
60
+ active=True,
61
+ commit=False,
62
+ )
63
+
64
+ db_connection.session.commit()
@@ -4,9 +4,6 @@ from copy import deepcopy
4
4
  from typing import Dict, List, Tuple
5
5
 
6
6
  from mage_ai.data_preparation.models.constants import PipelineType
7
- from mage_ai.data_preparation.models.pipelines.integration_pipeline import (
8
- IntegrationPipeline,
9
- )
10
7
  from mage_ai.orchestration.db.models.schedules import BlockRun, PipelineRun
11
8
  from mage_ai.shared.hash import merge_dict
12
9
 
@@ -40,6 +37,7 @@ KEY_TO_METRICS = {
40
37
 
41
38
  def calculate_pipeline_run_metrics(
42
39
  pipeline_run: PipelineRun,
40
+ pipeline,
43
41
  logger=None,
44
42
  logging_tags: Dict = None,
45
43
  ) -> Dict:
@@ -54,7 +52,7 @@ def calculate_pipeline_run_metrics(
54
52
  **logging_tags,
55
53
  )
56
54
  try:
57
- __calculate_metrics(pipeline_run)
55
+ __calculate_metrics(pipeline_run, pipeline)
58
56
  if logger:
59
57
  logger.info(
60
58
  f'Calculate metrics for pipeline run {pipeline_run.id} completed.',
@@ -72,6 +70,7 @@ def calculate_pipeline_run_metrics(
72
70
  def calculate_source_metrics(
73
71
  pipeline_run: PipelineRun,
74
72
  block_run: BlockRun,
73
+ pipeline,
75
74
  stream: str,
76
75
  logger=None,
77
76
  logging_tags: Dict = None,
@@ -79,6 +78,7 @@ def calculate_source_metrics(
79
78
  return __calculate_block_metrics(
80
79
  pipeline_run,
81
80
  block_run,
81
+ pipeline,
82
82
  stream,
83
83
  KEY_SOURCE,
84
84
  logger=logger,
@@ -89,6 +89,7 @@ def calculate_source_metrics(
89
89
  def calculate_destination_metrics(
90
90
  pipeline_run: PipelineRun,
91
91
  block_run: BlockRun,
92
+ pipeline,
92
93
  stream: str,
93
94
  logger=None,
94
95
  logging_tags: Dict = None,
@@ -96,6 +97,7 @@ def calculate_destination_metrics(
96
97
  return __calculate_block_metrics(
97
98
  pipeline_run,
98
99
  block_run,
100
+ pipeline,
99
101
  stream,
100
102
  KEY_DESTINATION,
101
103
  logger=logger,
@@ -106,6 +108,7 @@ def calculate_destination_metrics(
106
108
  def __calculate_block_metrics(
107
109
  pipeline_run: PipelineRun,
108
110
  block_run: BlockRun,
111
+ pipeline,
109
112
  stream: str,
110
113
  key: str,
111
114
  logger=None,
@@ -135,8 +138,6 @@ def __calculate_block_metrics(
135
138
  **logging_tags,
136
139
  )
137
140
  try:
138
- pipeline = IntegrationPipeline.get(pipeline_run.pipeline_uuid)
139
-
140
141
  logs_arr = block_run.logs['content'].split('\n')
141
142
  logs_by_uuid = {key: [logs_arr]}
142
143
  metrics = get_metrics(
@@ -192,7 +193,7 @@ def __calculate_block_metrics(
192
193
  )
193
194
 
194
195
 
195
- def __calculate_metrics(pipeline_run: PipelineRun) -> Dict:
196
+ def __calculate_metrics(pipeline_run: PipelineRun, pipeline) -> Dict:
196
197
  """
197
198
  Calculate metrics for an integration pipeline run. Only the "pipeline" field
198
199
  in the metrics will be updated by calling this method.
@@ -205,8 +206,6 @@ def __calculate_metrics(pipeline_run: PipelineRun) -> Dict:
205
206
  Returns:
206
207
  Dict: The calculated metrics.
207
208
  """
208
- pipeline = IntegrationPipeline.get(pipeline_run.pipeline_uuid)
209
-
210
209
  if PipelineType.INTEGRATION != pipeline.type:
211
210
  return
212
211
 
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import traceback
2
3
  from typing import Dict
3
4
 
4
5
  from mage_ai.orchestration.notification.config import (
@@ -61,33 +62,54 @@ class NotificationSender:
61
62
  if summary is None:
62
63
  return
63
64
  if self.config.slack_config is not None and self.config.slack_config.is_valid:
64
- send_slack_message(self.config.slack_config, details or summary, title)
65
+ try:
66
+ send_slack_message(self.config.slack_config, details or summary, title)
67
+ except Exception:
68
+ traceback.print_exc()
65
69
 
66
70
  if self.config.teams_config is not None and self.config.teams_config.is_valid:
67
- send_teams_message(self.config.teams_config, summary)
71
+ try:
72
+ send_teams_message(self.config.teams_config, summary)
73
+ except Exception:
74
+ traceback.print_exc()
68
75
 
69
76
  if self.config.discord_config is not None and self.config.discord_config.is_valid:
70
- send_discord_message(self.config.discord_config, summary, title)
77
+ try:
78
+ send_discord_message(self.config.discord_config, summary, title)
79
+ except Exception:
80
+ traceback.print_exc()
71
81
 
72
82
  if self.config.telegram_config is not None and self.config.telegram_config.is_valid:
73
- send_telegram_message(self.config.telegram_config, summary, title)
83
+ try:
84
+ send_telegram_message(self.config.telegram_config, summary, title)
85
+ except Exception:
86
+ traceback.print_exc()
74
87
 
75
88
  if self.config.google_chat_config is not None and self.config.google_chat_config.is_valid:
76
- send_google_chat_message(self.config.google_chat_config, summary)
89
+ try:
90
+ send_google_chat_message(self.config.google_chat_config, summary)
91
+ except Exception:
92
+ traceback.print_exc()
77
93
 
78
94
  if self.config.email_config is not None and title is not None:
79
- send_email(
80
- self.config.email_config,
81
- subject=title,
82
- message=details or summary,
83
- )
95
+ try:
96
+ send_email(
97
+ self.config.email_config,
98
+ subject=title,
99
+ message=details or summary,
100
+ )
101
+ except Exception:
102
+ traceback.print_exc()
84
103
 
85
104
  if self.config.opsgenie_config is not None and self.config.opsgenie_config.is_valid:
86
- send_opsgenie_alert(
87
- self.config.opsgenie_config,
88
- message=title,
89
- description=details or summary,
90
- )
105
+ try:
106
+ send_opsgenie_alert(
107
+ self.config.opsgenie_config,
108
+ message=title,
109
+ description=details or summary,
110
+ )
111
+ except Exception:
112
+ traceback.print_exc()
91
113
 
92
114
  def send_pipeline_run_success_message(self, pipeline, pipeline_run) -> None:
93
115
  if AlertOn.PIPELINE_RUN_SUCCESS in self.config.alert_on:
@@ -157,6 +179,7 @@ class NotificationSender:
157
179
  pipeline_run_url=self.__pipeline_run_url(pipeline, pipeline_run),
158
180
  pipeline_schedule_id=pipeline_run.pipeline_schedule.id,
159
181
  pipeline_schedule_name=pipeline_run.pipeline_schedule.name,
182
+ pipeline_schedule_description=pipeline_run.pipeline_schedule.description,
160
183
  pipeline_uuid=pipeline.uuid,
161
184
  stacktrace=stacktrace,
162
185
  )
@@ -23,7 +23,7 @@ from mage_ai.data_preparation.models.triggers import (
23
23
  ScheduleInterval,
24
24
  ScheduleStatus,
25
25
  ScheduleType,
26
- get_triggers_by_pipeline,
26
+ get_triggers_by_pipeline_with_cache,
27
27
  )
28
28
  from mage_ai.data_preparation.repo_manager import get_repo_config
29
29
  from mage_ai.data_preparation.sync.git_sync import get_sync_config
@@ -155,10 +155,12 @@ class PipelineScheduler:
155
155
  if is_integration:
156
156
  clear_source_output_files(
157
157
  self.pipeline_run,
158
+ self.pipeline,
158
159
  self.logger,
159
160
  )
160
161
  initialize_state_and_runs(
161
162
  self.pipeline_run,
163
+ self.pipeline,
162
164
  self.logger,
163
165
  self.pipeline_run.get_variables(),
164
166
  )
@@ -228,6 +230,7 @@ class PipelineScheduler:
228
230
  tags = self.build_tags()
229
231
  calculate_pipeline_run_metrics(
230
232
  self.pipeline_run,
233
+ self.pipeline,
231
234
  logger=self.logger,
232
235
  logging_tags=tags,
233
236
  )
@@ -284,8 +287,7 @@ class PipelineScheduler:
284
287
  or PipelineRun.PipelineRunStatus.FAILED
285
288
  )
286
289
  self.pipeline_run.update(status=status)
287
-
288
- self.on_pipeline_run_failure('Pipeline run timed out.')
290
+ self.on_pipeline_run_failure('Pipeline run timed out.', status=status)
289
291
  elif self.pipeline_run.any_blocks_failed() and not self.allow_blocks_to_fail:
290
292
  self.pipeline_run.update(
291
293
  status=PipelineRun.PipelineRunStatus.FAILED)
@@ -318,30 +320,38 @@ class PipelineScheduler:
318
320
  self.__schedule_blocks(block_runs)
319
321
 
320
322
  @safe_db_query
321
- def on_pipeline_run_failure(self, error_msg: str) -> None:
322
- failed_block_runs = self.pipeline_run.failed_block_runs
323
- stacktrace = None
324
- for br in failed_block_runs:
325
- if br.metrics:
326
- message = br.metrics.get('error', {}).get('message')
327
- if message:
328
- message_split = message.split('\n')
329
- # Truncate the error message if it has too many lines, set max
330
- # lines at 50
331
- if len(message_split) > 50:
332
- message_split = message_split[-50:]
333
- message_split.insert(0, '... (error truncated)')
334
- message = '\n'.join(message_split)
335
- stacktrace = f'Error for block {br.block_uuid}:\n{message}'
336
- break
337
-
323
+ def on_pipeline_run_failure(
324
+ self,
325
+ error_msg: str,
326
+ status=PipelineRun.PipelineRunStatus.FAILED,
327
+ ) -> None:
338
328
  asyncio.run(UsageStatisticLogger().pipeline_run_ended(self.pipeline_run))
339
- self.notification_sender.send_pipeline_run_failure_message(
340
- pipeline=self.pipeline,
341
- pipeline_run=self.pipeline_run,
342
- error=error_msg,
343
- stacktrace=stacktrace,
344
- )
329
+
330
+ if status == PipelineRun.PipelineRunStatus.FAILED:
331
+ # Only send notification when pipeline run status is FAILED
332
+ failed_block_runs = self.pipeline_run.failed_block_runs
333
+ stacktrace = None
334
+ for br in failed_block_runs:
335
+ if br.metrics:
336
+ message = br.metrics.get('error', {}).get('message')
337
+ if message:
338
+ message_split = message.split('\n')
339
+ # Truncate the error message if it has too many lines, set max
340
+ # lines at 50
341
+ if len(message_split) > 50:
342
+ message_split = message_split[-50:]
343
+ message_split.insert(0, '... (error truncated)')
344
+ message = '\n'.join(message_split)
345
+ stacktrace = f'Error for block {br.block_uuid}:\n{message}'
346
+ break
347
+
348
+ self.notification_sender.send_pipeline_run_failure_message(
349
+ pipeline=self.pipeline,
350
+ pipeline_run=self.pipeline_run,
351
+ error=error_msg,
352
+ stacktrace=stacktrace,
353
+ )
354
+
345
355
  # Cancel block runs that are still in progress for the pipeline run.
346
356
  cancel_block_runs_and_jobs(self.pipeline_run, self.pipeline)
347
357
 
@@ -456,6 +466,7 @@ class PipelineScheduler:
456
466
 
457
467
  calculate_pipeline_run_metrics(
458
468
  self.pipeline_run,
469
+ self.pipeline,
459
470
  logger=self.logger,
460
471
  logging_tags=tags,
461
472
  )
@@ -478,6 +489,7 @@ class PipelineScheduler:
478
489
  if PipelineType.INTEGRATION == self.pipeline.type:
479
490
  calculate_pipeline_run_metrics(
480
491
  self.pipeline_run,
492
+ self.pipeline,
481
493
  logger=self.logger,
482
494
  logging_tags=tags,
483
495
  )
@@ -1062,6 +1074,7 @@ def run_integration_stream(
1062
1074
  calculate_source_metrics(
1063
1075
  pipeline_run,
1064
1076
  block_run,
1077
+ pipeline,
1065
1078
  stream=tap_stream_id,
1066
1079
  logger=pipeline_scheduler.logger,
1067
1080
  logging_tags=merge_dict(tags_updated, dict(tags=tags2)),
@@ -1070,6 +1083,7 @@ def run_integration_stream(
1070
1083
  calculate_destination_metrics(
1071
1084
  pipeline_run,
1072
1085
  block_run,
1086
+ pipeline,
1073
1087
  stream=tap_stream_id,
1074
1088
  logger=pipeline_scheduler.logger,
1075
1089
  logging_tags=merge_dict(tags_updated, dict(tags=tags2)),
@@ -1156,7 +1170,7 @@ def run_block(
1156
1170
  else:
1157
1171
  repo_path = get_repo_path()
1158
1172
  retry_config = merge_dict(
1159
- get_repo_config(repo_path).retry_config or dict(),
1173
+ get_repo_config(repo_path=repo_path).retry_config or dict(),
1160
1174
  block.retry_config or dict(),
1161
1175
  )
1162
1176
 
@@ -1246,9 +1260,10 @@ def configure_pipeline_run_payload(
1246
1260
  @safe_db_query
1247
1261
  def retry_pipeline_run(
1248
1262
  pipeline_run: Dict,
1263
+ repo_path: str,
1249
1264
  ) -> 'PipelineRun':
1250
1265
  pipeline_uuid = pipeline_run['pipeline_uuid']
1251
- pipeline = Pipeline.get(pipeline_uuid, check_if_exists=True)
1266
+ pipeline = Pipeline.get(pipeline_uuid, check_if_exists=True, repo_path=repo_path)
1252
1267
  if pipeline is None or not pipeline.is_valid_pipeline(pipeline.dir_path):
1253
1268
  raise Exception(f'Pipeline {pipeline_uuid} is not a valid pipeline.')
1254
1269
 
@@ -1392,7 +1407,7 @@ def check_sla():
1392
1407
  else pipeline_run.created_at
1393
1408
  if compare(start_date + timedelta(seconds=sla), current_time) == -1:
1394
1409
  # passed SLA for pipeline_run
1395
- pipeline = Pipeline.get(pipeline_schedule.pipeline_uuid)
1410
+ pipeline = pipeline_schedule.pipeline
1396
1411
  notification_sender = NotificationSender(
1397
1412
  NotificationConfig.load(
1398
1413
  config=merge_dict(
@@ -1429,7 +1444,7 @@ def schedule_all():
1429
1444
  schedules, so that needs to be addressed at some point.
1430
1445
  """
1431
1446
  db_connection.session.expire_all()
1432
-
1447
+ repo_config = get_repo_config()
1433
1448
  repo_pipelines = set(Pipeline.get_all_pipelines_all_projects(
1434
1449
  get_repo_path(),
1435
1450
  disable_pipelines_folder_creation=True,
@@ -1494,6 +1509,7 @@ def schedule_all():
1494
1509
 
1495
1510
  for pipeline_uuid, pipeline, active_schedules in gen_pipeline_with_schedules(
1496
1511
  active_pipeline_schedules,
1512
+ repo_config=repo_config,
1497
1513
  ):
1498
1514
  concurrency_config = ConcurrencyConfig.load(config=pipeline.concurrency_config)
1499
1515
  pipeline_runs_to_start = []
@@ -1524,6 +1540,7 @@ def schedule_all():
1524
1540
  should_schedule = pipeline_schedule.should_schedule(
1525
1541
  previous_runtimes=previous_runtimes,
1526
1542
  pipeline=pipeline,
1543
+ repo_config=repo_config,
1527
1544
  )
1528
1545
  initial_pipeline_runs = [
1529
1546
  r for r in pipeline_schedule.pipeline_runs
@@ -1661,6 +1678,7 @@ def schedule_all():
1661
1678
 
1662
1679
  def gen_pipeline_with_schedules_single_project(
1663
1680
  active_pipeline_schedules: List[PipelineSchedule],
1681
+ repo_config=None,
1664
1682
  ) -> Generator[Tuple[str, Pipeline, List[PipelineSchedule]], None, None]:
1665
1683
  """
1666
1684
  Generate pipelines with associated schedules for a single project.
@@ -1674,6 +1692,8 @@ def gen_pipeline_with_schedules_single_project(
1674
1692
  - The pipeline object.
1675
1693
  - A list of active schedules associated with the pipeline.
1676
1694
  """
1695
+ # Avoid calling get_repo_config repeatedly in Pipeline init method.
1696
+ repo_config = repo_config or get_repo_config()
1677
1697
  pipeline_schedules_by_pipeline = collections.defaultdict(list)
1678
1698
  for schedule in active_pipeline_schedules:
1679
1699
  pipeline_schedules_by_pipeline[schedule.pipeline_uuid].append(schedule)
@@ -1682,15 +1702,21 @@ def gen_pipeline_with_schedules_single_project(
1682
1702
  # each pipeline.
1683
1703
  for pipeline_uuid, active_schedules in pipeline_schedules_by_pipeline.items():
1684
1704
  try:
1685
- pipeline = Pipeline.get(pipeline_uuid)
1705
+ pipeline = Pipeline.get(
1706
+ pipeline_uuid,
1707
+ repo_path=get_repo_path(),
1708
+ repo_config=repo_config,
1709
+ )
1686
1710
  except Exception as e:
1687
1711
  print(f'Error fetching pipeline {pipeline_uuid}: {e}')
1712
+ traceback.print_exc()
1688
1713
  continue
1689
1714
  yield pipeline_uuid, pipeline, active_schedules
1690
1715
 
1691
1716
 
1692
1717
  def gen_pipeline_with_schedules_project_platform(
1693
1718
  active_pipeline_schedules: List[PipelineSchedule],
1719
+ repo_config=None,
1694
1720
  ) -> Generator[Tuple[str, Pipeline, List[PipelineSchedule]], None, None]:
1695
1721
  """
1696
1722
  Generate pipelines with associated schedules for project platform.
@@ -1754,6 +1780,7 @@ def gen_pipeline_with_schedules_project_platform(
1754
1780
  )
1755
1781
  except Exception as e:
1756
1782
  print(f'Error fetching pipeline {pipeline_uuid}: {e}')
1783
+ traceback.print_exc()
1757
1784
  continue
1758
1785
  yield pipeline_uuid, pipeline, active_schedules
1759
1786
 
@@ -1805,8 +1832,12 @@ def sync_schedules(pipeline_uuids: List[str]):
1805
1832
 
1806
1833
  # Sync schedule configs from triggers.yaml to DB
1807
1834
  for pipeline_uuid in pipeline_uuids:
1808
- pipeline_triggers = get_triggers_by_pipeline(pipeline_uuid)
1809
- logger.debug(f'Sync pipeline trigger configs for {pipeline_uuid}: {pipeline_triggers}.')
1835
+ pipeline_triggers, from_cache = get_triggers_by_pipeline_with_cache(pipeline_uuid)
1836
+ logger.debug(f'Sync pipeline trigger configs for {pipeline_uuid}: {pipeline_triggers}.'
1837
+ f'From cache: {from_cache}')
1838
+ if from_cache:
1839
+ # No updates need to be made to database
1840
+ continue
1810
1841
  for pipeline_trigger in pipeline_triggers:
1811
1842
  if pipeline_trigger.envs and get_env() not in pipeline_trigger.envs:
1812
1843
  continue
@@ -1120,7 +1120,7 @@ def run_block(
1120
1120
  repo_path = get_repo_path()
1121
1121
 
1122
1122
  retry_config = merge_dict(
1123
- get_repo_config(repo_path).retry_config or dict(),
1123
+ get_repo_config(repo_path=repo_path).retry_config or dict(),
1124
1124
  block.retry_config or dict(),
1125
1125
  )
1126
1126
 
@@ -1,6 +1,7 @@
1
1
  from datetime import datetime, timedelta, timezone
2
2
 
3
3
  from mage_ai.data_preparation.models.pipeline import Pipeline
4
+ from mage_ai.data_preparation.models.utils import warn_for_repo_path
4
5
  from mage_ai.orchestration.db.models.schedules import (
5
6
  BlockRun,
6
7
  PipelineRun,
@@ -23,10 +24,11 @@ BLOCK_FAILURE_STATUSES = [
23
24
  def check_status(
24
25
  pipeline_uuid: str,
25
26
  execution_date: datetime,
27
+ repo_path: str = None,
26
28
  block_uuid: str = None,
27
29
  hours: int = 24,
28
30
  ) -> bool:
29
- __validate_pipeline_and_block(pipeline_uuid, block_uuid)
31
+ __validate_pipeline_and_block(pipeline_uuid, block_uuid, repo_path=repo_path)
30
32
 
31
33
  execution_date = execution_date.replace(tzinfo=timezone.utc)
32
34
  pipeline_run = (
@@ -62,11 +64,16 @@ def check_status(
62
64
  return pipeline_run.status == PipelineRun.PipelineRunStatus.COMPLETED
63
65
 
64
66
 
65
- def __validate_pipeline_and_block(pipeline_uuid, block_uuid):
66
- if pipeline_uuid not in Pipeline.get_all_pipelines(get_repo_path()):
67
+ def __validate_pipeline_and_block(pipeline_uuid: str, block_uuid: str, repo_path: str = None):
68
+ warn_for_repo_path(repo_path=repo_path)
69
+
70
+ if repo_path is None:
71
+ repo_path = get_repo_path()
72
+
73
+ if pipeline_uuid not in Pipeline.get_all_pipelines(repo_path=repo_path):
67
74
  raise Exception('Pipeline not found, stopping sensor...')
68
75
 
69
- pipeline = Pipeline(pipeline_uuid, get_repo_path())
76
+ pipeline = Pipeline.get(pipeline_uuid, repo_path=repo_path)
70
77
 
71
78
  if block_uuid is not None:
72
79
  block = pipeline.get_block(block_uuid)
@@ -1,9 +1,11 @@
1
1
  from datetime import datetime
2
- from typing import Dict, Optional
2
+ from typing import Dict, List, Optional, Union
3
3
 
4
4
  from mage_ai.api.resources.PipelineScheduleResource import PipelineScheduleResource
5
+ from mage_ai.data_preparation.models.block.remote.models import RemoteBlock
5
6
  from mage_ai.data_preparation.models.pipeline import Pipeline
6
7
  from mage_ai.data_preparation.models.triggers import ScheduleStatus, ScheduleType
8
+ from mage_ai.data_preparation.models.utils import warn_for_repo_path
7
9
  from mage_ai.orchestration.db.models.schedules import PipelineRun, PipelineSchedule
8
10
  from mage_ai.orchestration.triggers.constants import (
9
11
  DEFAULT_POLL_INTERVAL,
@@ -14,10 +16,12 @@ from mage_ai.orchestration.triggers.utils import (
14
16
  create_and_start_pipeline_run,
15
17
  )
16
18
  from mage_ai.settings.platform import project_platform_activated
19
+ from mage_ai.settings.repo import get_repo_path
17
20
 
18
21
 
19
22
  def trigger_pipeline(
20
23
  pipeline_uuid: str,
24
+ repo_path: str = None,
21
25
  variables: Dict = None,
22
26
  check_status: bool = False,
23
27
  error_on_failure: bool = False,
@@ -25,12 +29,30 @@ def trigger_pipeline(
25
29
  poll_timeout: Optional[float] = None,
26
30
  schedule_name: str = None,
27
31
  verbose: bool = True,
32
+ remote_blocks: List[Union[Dict, RemoteBlock]] = None,
33
+ return_remote_blocks: bool = False,
28
34
  _should_schedule: bool = False, # For internal use only (e.g. running hooks from notebook).
29
35
  ) -> PipelineRun:
30
36
  if variables is None:
31
37
  variables = {}
32
38
 
33
- pipeline = Pipeline.get(pipeline_uuid, all_projects=project_platform_activated())
39
+ warn_for_repo_path(repo_path)
40
+
41
+ if remote_blocks:
42
+ arr = []
43
+ for remote_block in remote_blocks:
44
+ if isinstance(remote_block, dict):
45
+ remote_block = RemoteBlock.load(**remote_block)
46
+ arr.append(remote_block.to_dict())
47
+ variables['remote_blocks'] = arr
48
+
49
+ repo_path_use = repo_path or get_repo_path()
50
+ pipeline = Pipeline.get(
51
+ pipeline_uuid,
52
+ all_projects=project_platform_activated(),
53
+ repo_path=repo_path_use,
54
+ use_repo_path=repo_path is not None,
55
+ )
34
56
 
35
57
  pipeline_schedule = __fetch_or_create_pipeline_schedule(pipeline, schedule_name=schedule_name)
36
58
 
@@ -50,6 +72,23 @@ def trigger_pipeline(
50
72
  verbose=verbose,
51
73
  )
52
74
 
75
+ if return_remote_blocks and pipeline_run and pipeline_run.pipeline:
76
+ pipeline = pipeline_run.pipeline
77
+
78
+ return [
79
+ dict(
80
+ remote_blocks=[
81
+ RemoteBlock.load(
82
+ block_uuid=block.uuid,
83
+ execution_partition=pipeline_run.execution_partition,
84
+ pipeline_uuid=pipeline.uuid,
85
+ repo_path=pipeline.repo_path,
86
+ )
87
+ for block in pipeline.blocks_by_uuid.values()
88
+ ],
89
+ ),
90
+ ]
91
+
53
92
  return pipeline_run
54
93
 
55
94