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
@@ -1,8 +1,11 @@
1
1
  import os
2
2
  import shutil
3
- import yaml
4
3
  from dataclasses import dataclass, field
4
+ from typing import Dict, List
5
+
6
+ import yaml
5
7
  from jinja2 import Template
8
+
6
9
  from mage_ai.data_preparation.models.block import Block
7
10
  from mage_ai.data_preparation.models.constants import (
8
11
  BLOCK_LANGUAGE_TO_FILE_EXTENSION,
@@ -10,18 +13,18 @@ from mage_ai.data_preparation.models.constants import (
10
13
  BlockLanguage,
11
14
  BlockType,
12
15
  )
13
- from mage_ai.data_preparation.models.file import File
14
- from mage_ai.data_preparation.models.pipeline import Pipeline
15
16
  from mage_ai.data_preparation.models.custom_templates.constants import (
16
17
  DIRECTORY_FOR_BLOCK_TEMPLATES,
17
18
  METADATA_FILENAME_WITH_EXTENSION,
18
19
  )
19
- from mage_ai.data_preparation.models.custom_templates.utils import custom_templates_directory
20
- from mage_ai.settings.repo import get_repo_path
20
+ from mage_ai.data_preparation.models.custom_templates.utils import (
21
+ custom_templates_directory,
22
+ )
23
+ from mage_ai.data_preparation.models.file import File
24
+ from mage_ai.data_preparation.models.pipeline import Pipeline
21
25
  from mage_ai.shared.config import BaseConfig
22
26
  from mage_ai.shared.hash import merge_dict
23
27
  from mage_ai.shared.io import safe_write
24
- from typing import Dict, List
25
28
 
26
29
 
27
30
  @dataclass
@@ -34,12 +37,13 @@ class CustomBlockTemplate(BaseConfig):
34
37
  language: BlockLanguage = None
35
38
  name: str = None
36
39
  pipeline: Dict = field(default_factory=dict)
40
+ repo_path: str = None
37
41
  tags: List = field(default_factory=list)
38
42
  template_uuid: str = None
39
43
  user: Dict = field(default_factory=dict)
40
44
 
41
45
  @classmethod
42
- def load(self, template_uuid: str = None, uuid: str = None):
46
+ def load(self, repo_path, template_uuid: str = None, uuid: str = None):
43
47
  uuid_use = uuid
44
48
  template_uuid_use = template_uuid
45
49
 
@@ -55,12 +59,13 @@ class CustomBlockTemplate(BaseConfig):
55
59
 
56
60
  try:
57
61
  config_path_metadata = os.path.join(
58
- get_repo_path(),
62
+ repo_path,
59
63
  uuid_use,
60
64
  METADATA_FILENAME_WITH_EXTENSION,
61
65
  )
62
66
  custom_template = super().load(config_path_metadata)
63
67
  custom_template.template_uuid = template_uuid_use
68
+ custom_template.repo_path = repo_path
64
69
 
65
70
  return custom_template
66
71
  except Exception as err:
@@ -77,7 +82,7 @@ class CustomBlockTemplate(BaseConfig):
77
82
  @property
78
83
  def metadata_file_path(self) -> str:
79
84
  return os.path.join(
80
- get_repo_path(),
85
+ self.repo_path,
81
86
  self.uuid,
82
87
  METADATA_FILENAME_WITH_EXTENSION,
83
88
  )
@@ -98,7 +103,7 @@ class CustomBlockTemplate(BaseConfig):
98
103
  return Block.create(
99
104
  block_name,
100
105
  self.block_type,
101
- get_repo_path(),
106
+ self.repo_path,
102
107
  color=self.color,
103
108
  configuration=configuration,
104
109
  extension_uuid=extension_uuid,
@@ -118,7 +123,7 @@ class CustomBlockTemplate(BaseConfig):
118
123
  return File(
119
124
  dir_path=self.uuid,
120
125
  filename=filename,
121
- repo_path=get_repo_path(),
126
+ repo_path=self.repo_path,
122
127
  ).content()
123
128
 
124
129
  def render_template(
@@ -170,8 +175,8 @@ class CustomBlockTemplate(BaseConfig):
170
175
  filename,
171
176
  self.uuid,
172
177
  self.content,
173
- get_repo_path(),
178
+ self.repo_path,
174
179
  )
175
180
 
176
181
  def delete(self) -> None:
177
- shutil.rmtree(os.path.join(get_repo_path(), self.uuid))
182
+ shutil.rmtree(os.path.join(self.repo_path, self.uuid))
@@ -1,13 +1,18 @@
1
1
  import os
2
2
  import shutil
3
- import yaml
4
3
  from dataclasses import dataclass, field
5
- from mage_ai.data_preparation.models.pipeline import Pipeline
4
+ from typing import Dict, List
5
+
6
+ import yaml
7
+
6
8
  from mage_ai.data_preparation.models.custom_templates.constants import (
7
9
  DIRECTORY_FOR_PIPELINE_TEMPLATES,
8
10
  METADATA_FILENAME_WITH_EXTENSION,
9
11
  )
10
- from mage_ai.data_preparation.models.custom_templates.utils import custom_templates_directory
12
+ from mage_ai.data_preparation.models.custom_templates.utils import (
13
+ custom_templates_directory,
14
+ )
15
+ from mage_ai.data_preparation.models.pipeline import Pipeline
11
16
  from mage_ai.data_preparation.models.triggers import (
12
17
  TRIGGER_FILE_NAME,
13
18
  Trigger,
@@ -16,12 +21,10 @@ from mage_ai.data_preparation.models.triggers import (
16
21
  load_trigger_configs,
17
22
  )
18
23
  from mage_ai.orchestration.db.models.schedules import PipelineSchedule
19
- from mage_ai.settings.repo import get_repo_path
20
24
  from mage_ai.shared.config import BaseConfig
21
25
  from mage_ai.shared.hash import merge_dict
22
26
  from mage_ai.shared.io import safe_write
23
27
  from mage_ai.shared.utils import clean_name
24
- from typing import Dict, List
25
28
 
26
29
 
27
30
  @dataclass
@@ -29,12 +32,13 @@ class CustomPipelineTemplate(BaseConfig):
29
32
  description: str = None
30
33
  name: str = None
31
34
  pipeline: Dict = field(default_factory=dict)
35
+ repo_path: str = None
32
36
  tags: List = field(default_factory=list)
33
37
  template_uuid: str = None
34
38
  user: Dict = field(default_factory=dict)
35
39
 
36
40
  @classmethod
37
- def load(self, template_uuid: str = None, uuid: str = None):
41
+ def load(self, repo_path: str, template_uuid: str = None, uuid: str = None):
38
42
  uuid_use = uuid
39
43
  template_uuid_use = template_uuid
40
44
 
@@ -50,12 +54,13 @@ class CustomPipelineTemplate(BaseConfig):
50
54
 
51
55
  try:
52
56
  config_path_metadata = os.path.join(
53
- get_repo_path(),
57
+ repo_path,
54
58
  uuid_use,
55
59
  METADATA_FILENAME_WITH_EXTENSION,
56
60
  )
57
61
  custom_template = super().load(config_path_metadata)
58
62
  custom_template.template_uuid = template_uuid_use
63
+ custom_template.repo_path = repo_path
59
64
 
60
65
  return custom_template
61
66
  except Exception as err:
@@ -78,6 +83,7 @@ class CustomPipelineTemplate(BaseConfig):
78
83
  description=description,
79
84
  name=name,
80
85
  pipeline=pipeline_dict,
86
+ repo_path=pipeline.repo_path,
81
87
  template_uuid=clean_name(template_uuid, [os.sep]) if template_uuid else template_uuid,
82
88
  )
83
89
 
@@ -118,7 +124,7 @@ class CustomPipelineTemplate(BaseConfig):
118
124
  @property
119
125
  def metadata_file_path(self) -> str:
120
126
  return os.path.join(
121
- get_repo_path(),
127
+ self.repo_path,
122
128
  self.uuid,
123
129
  METADATA_FILENAME_WITH_EXTENSION,
124
130
  )
@@ -126,16 +132,24 @@ class CustomPipelineTemplate(BaseConfig):
126
132
  @property
127
133
  def triggers_file_path(self) -> str:
128
134
  return os.path.join(
129
- get_repo_path(),
135
+ self.repo_path,
130
136
  self.uuid,
131
137
  TRIGGER_FILE_NAME,
132
138
  )
133
139
 
134
140
  def build_pipeline(self) -> Pipeline:
135
- return Pipeline(clean_name(self.template_uuid), config=self.pipeline)
141
+ return Pipeline(
142
+ clean_name(self.template_uuid),
143
+ config=self.pipeline,
144
+ repo_path=self.repo_path,
145
+ )
136
146
 
137
147
  def create_pipeline(self, name: str) -> Pipeline:
138
- pipeline = Pipeline(clean_name(name), config=self.pipeline)
148
+ pipeline = Pipeline(
149
+ clean_name(name),
150
+ repo_path=self.repo_path,
151
+ config=self.pipeline,
152
+ )
139
153
  os.makedirs(os.path.dirname(pipeline.config_path), exist_ok=True)
140
154
  pipeline.save()
141
155
 
@@ -151,10 +165,13 @@ class CustomPipelineTemplate(BaseConfig):
151
165
  return pipeline
152
166
 
153
167
  def to_dict(self) -> Dict:
154
- return merge_dict(self.to_dict_base(), dict(
155
- template_uuid=self.template_uuid,
156
- uuid=self.uuid,
157
- ))
168
+ return merge_dict(
169
+ self.to_dict_base(),
170
+ dict(
171
+ template_uuid=self.template_uuid,
172
+ uuid=self.uuid,
173
+ ),
174
+ )
158
175
 
159
176
  def to_dict_base(self) -> Dict:
160
177
  return dict(
@@ -178,4 +195,4 @@ class CustomPipelineTemplate(BaseConfig):
178
195
  safe_write(file_path, content)
179
196
 
180
197
  def delete(self) -> None:
181
- shutil.rmtree(os.path.join(get_repo_path(), self.uuid))
198
+ shutil.rmtree(os.path.join(self.repo_path, self.uuid))
@@ -71,7 +71,7 @@ def group_and_hydrate_files(
71
71
  custom_templates = []
72
72
 
73
73
  for template_uuid, _ in groups.items():
74
- custom_template = custom_template_class.load(template_uuid=template_uuid)
74
+ custom_template = custom_template_class.load(get_repo_path(), template_uuid=template_uuid)
75
75
  if custom_template:
76
76
  custom_templates.append(custom_template)
77
77
 
@@ -145,6 +145,7 @@ class File:
145
145
  file_selector = None
146
146
 
147
147
  if exclude_pattern is not None or pattern is not None:
148
+
148
149
  def __select(x: Dict, check_file_path=check_file_path, pattern=pattern):
149
150
  filename = x.get('path') if check_file_path else x.get('name')
150
151
  checks = []
@@ -157,6 +158,7 @@ class File:
157
158
  file_selector = __select
158
159
 
159
160
  if exclude_dir_pattern is not None:
161
+
160
162
  def __select(x: Dict, pattern=pattern):
161
163
  filename = x.get('name')
162
164
  checks = []
@@ -169,6 +171,7 @@ class File:
169
171
  pipeline_count_mapping = None
170
172
  if include_pipeline_count:
171
173
  from mage_ai.cache.block import BlockCache
174
+
172
175
  pipeline_count_mapping = BlockCache().get_pipeline_count_mapping()
173
176
 
174
177
  return traverse(
@@ -200,7 +203,7 @@ class File:
200
203
  if dir_path.startswith(PIPELINES_FOLDER_PREFIX) and filename == 'triggers.yaml':
201
204
  from mage_ai.data_preparation.models.triggers import load_trigger_configs
202
205
 
203
- pipeline_uuid = dir_path[len(PIPELINES_FOLDER_PREFIX):]
206
+ pipeline_uuid = dir_path[len(PIPELINES_FOLDER_PREFIX) :]
204
207
  load_trigger_configs(content, pipeline_uuid=pipeline_uuid, raise_exception=True)
205
208
 
206
209
  @classmethod
@@ -239,8 +242,9 @@ class File:
239
242
  number_of_file_versions = len(file_versions)
240
243
 
241
244
  if number_of_file_versions >= MAX_NUMBER_OF_FILE_VERSIONS:
242
- number_of_file_versions_to_delete = 1 + \
243
- (number_of_file_versions - MAX_NUMBER_OF_FILE_VERSIONS)
245
+ number_of_file_versions_to_delete = 1 + (
246
+ number_of_file_versions - MAX_NUMBER_OF_FILE_VERSIONS
247
+ )
244
248
  for fn in sorted(file_versions)[:number_of_file_versions_to_delete]:
245
249
  fn_path = os.path.join(file_path_versions_dir, fn)
246
250
  os.remove(fn_path)
@@ -339,8 +343,9 @@ class File:
339
343
  file_content = fp.read()
340
344
  return file_content
341
345
  except FileNotFoundError as err:
342
- print('file.content')
343
- print(err)
346
+ print(f'[ERROR] File.content: {err}')
347
+ if is_debug():
348
+ raise err
344
349
  return ''
345
350
 
346
351
  async def content_async(self):
@@ -370,11 +375,14 @@ class File:
370
375
  os.path.join(self.repo_path, ''),
371
376
  '',
372
377
  )
373
- return [File(
374
- v,
375
- file_path_versions_dir_without_repo,
376
- self.repo_path,
377
- ) for v in sorted(file_versions, reverse=True)]
378
+ return [
379
+ File(
380
+ v,
381
+ file_path_versions_dir_without_repo,
382
+ self.repo_path,
383
+ )
384
+ for v in sorted(file_versions, reverse=True)
385
+ ]
378
386
 
379
387
  def update_content(self, content: str):
380
388
  self.write(
@@ -464,8 +472,7 @@ def ensure_file_is_in_project(file_path: str) -> None:
464
472
  full_file_path = get_absolute_path(file_path)
465
473
  full_repo_path = get_absolute_path(get_repo_path(file_path=file_path))
466
474
  if full_repo_path != os.path.commonpath([full_file_path, full_repo_path]):
467
- raise FileNotInProjectError(
468
- f'File at path: {file_path} is not in the project directory.')
475
+ raise FileNotInProjectError(f'File at path: {file_path} is not in the project directory.')
469
476
 
470
477
 
471
478
  def traverse(
@@ -508,17 +515,25 @@ def traverse(
508
515
 
509
516
  entry_path = entry.path
510
517
  if entry.is_dir(follow_symlinks=False) or os.path.isdir(entry_path):
511
- return True if dir_selector is None else dir_selector(dict(
512
- depth=depth + 1,
513
- name=str(entry.name),
514
- path=entry.path,
515
- ))
518
+ return (
519
+ True
520
+ if dir_selector is None
521
+ else dir_selector(
522
+ dict(
523
+ depth=depth + 1,
524
+ name=str(entry.name),
525
+ path=entry.path,
526
+ )
527
+ )
528
+ )
516
529
  else:
517
- return file_selector(dict(
518
- depth=depth + 1,
519
- name=str(entry.name),
520
- path=entry.path,
521
- ))
530
+ return file_selector(
531
+ dict(
532
+ depth=depth + 1,
533
+ name=str(entry.name),
534
+ path=entry.path,
535
+ )
536
+ )
522
537
 
523
538
  return True
524
539
 
@@ -533,7 +548,8 @@ def traverse(
533
548
  file_selector=file_selector,
534
549
  include_pipeline_count=include_pipeline_count,
535
550
  pipeline_count_mapping=pipeline_count_mapping,
536
- ) for entry in sorted(
551
+ )
552
+ for entry in sorted(
537
553
  filter(__filter, os.scandir(path)),
538
554
  key=lambda entry: entry.name,
539
555
  )
@@ -546,11 +562,7 @@ def __should_update_dbt_cache(dir_path: str, filename: str) -> bool:
546
562
  project_model = Project(root_project=True)
547
563
  if project_model and project_model.is_feature_enabled(FeatureUUID.DBT_V2) and dir_path:
548
564
  # If the file is a SQL or YAML file
549
- if (
550
- filename.endswith('.sql') or
551
- filename.endswith('.yml') or
552
- filename.endswith('.yaml')
553
- ):
565
+ if filename.endswith('.sql') or filename.endswith('.yml') or filename.endswith('.yaml'):
554
566
  base_dir_path = Path(dir_path).parts[0].lower()
555
567
  # If the file doesn’t exist in a block’s folder (e.g. data_loaders/, pipelines/)
556
568
  if base_dir_path not in IGNORE_DIRECTORY_NAMES:
@@ -595,4 +607,5 @@ def update_file_cache() -> None:
595
607
  project_model = Project(root_project=True)
596
608
  if project_model and project_model.is_feature_enabled(FeatureUUID.COMMAND_CENTER):
597
609
  from mage_ai.cache.file import FileCache
610
+
598
611
  FileCache().invalidate()
@@ -1,21 +1,22 @@
1
1
  import os
2
2
  from dataclasses import dataclass, field
3
3
  from datetime import datetime, timezone
4
- from typing import Dict, List
4
+ from typing import Dict, List, Optional
5
5
 
6
6
  import yaml
7
7
  from dateutil.relativedelta import relativedelta
8
8
 
9
- from mage_ai.data_preparation.models.global_data_product.constants import (
9
+ from mage_ai.data_preparation.models.block.settings.global_data_products.models import (
10
10
  GlobalDataProductObjectType,
11
11
  )
12
12
  from mage_ai.data_preparation.models.pipeline import Pipeline
13
13
  from mage_ai.orchestration.db.models.schedules import PipelineRun, PipelineSchedule
14
- from mage_ai.settings.repo import get_repo_path
14
+ from mage_ai.settings.platform.utils import full_paths_for_all_projects
15
15
  from mage_ai.shared.array import find
16
16
  from mage_ai.shared.dates import week_of_month
17
17
  from mage_ai.shared.hash import extract, index_by
18
18
  from mage_ai.shared.io import safe_write
19
+ from mage_ai.shared.path_fixer import add_absolute_path, get_path_parts
19
20
  from mage_ai.shared.utils import clean_name
20
21
 
21
22
 
@@ -26,6 +27,7 @@ class GlobalDataProduct:
26
27
  object_uuid: str = None
27
28
  outdated_after: Dict = field(default_factory=dict)
28
29
  outdated_starting_at: Dict = field(default_factory=dict)
30
+ repo_path: str = None
29
31
  settings: Dict = field(default_factory=dict)
30
32
 
31
33
  def __init__(self, uuid: str, **kwargs):
@@ -33,37 +35,50 @@ class GlobalDataProduct:
33
35
  self.object_uuid = kwargs.get('object_uuid')
34
36
  self.outdated_after = kwargs.get('outdated_after')
35
37
  self.outdated_starting_at = kwargs.get('outdated_starting_at')
38
+ self.repo_path = kwargs.get('repo_path')
36
39
  self.settings = kwargs.get('settings')
37
40
  self.uuid = clean_name(uuid) if uuid else uuid
38
41
  self._object = None
39
42
 
40
43
  @classmethod
41
- def file_path(self) -> str:
42
- return os.path.join(get_repo_path(), 'global_data_products.yaml')
44
+ def file_path(cls, repo_path: str) -> str:
45
+ return os.path.join(repo_path, 'global_data_products.yaml')
43
46
 
44
47
  @classmethod
45
- def load_all(self, file_path: str = None) -> List['GlobalDataProduct']:
46
- file_path_to_use = file_path or self.file_path()
47
- arr = []
48
+ def load_all(cls, repo_path: Optional[str] = None) -> List['GlobalDataProduct']:
49
+ paths = []
50
+ if repo_path:
51
+ paths.append(repo_path)
52
+ else:
53
+ paths += full_paths_for_all_projects()
48
54
 
49
- if not os.path.exists(file_path_to_use):
50
- return []
55
+ arr = []
51
56
 
52
- with open(file_path_to_use) as fp:
53
- content = fp.read()
54
- if content:
55
- yaml_config = yaml.safe_load(content) or {}
56
- for uuid, config_attributes in yaml_config.items():
57
- arr.append(self(
58
- uuid,
59
- **config_attributes,
60
- ))
57
+ for file_path in paths:
58
+ file_path_to_use = cls.file_path(file_path)
59
+ if not os.path.exists(file_path_to_use):
60
+ continue
61
+
62
+ with open(file_path_to_use) as fp:
63
+ content = fp.read()
64
+ if content:
65
+ yaml_config = yaml.safe_load(content) or {}
66
+ for uuid, config_attributes in yaml_config.items():
67
+ arr.append(
68
+ cls(
69
+ uuid,
70
+ **config_attributes,
71
+ )
72
+ )
61
73
 
62
74
  return arr
63
75
 
64
76
  @classmethod
65
- def get(self, uuid: str, file_path: str = None):
66
- return find(lambda x: x.uuid == uuid, self.load_all(file_path=file_path))
77
+ def get(cls, uuid: str, repo_path: Optional[str] = None, project: Optional[str] = None):
78
+ if project:
79
+ repo_path = add_absolute_path(project)
80
+
81
+ return find(lambda x: x.uuid == uuid, cls.load_all(repo_path))
67
82
 
68
83
  @property
69
84
  def pipeline(self) -> Pipeline:
@@ -71,10 +86,22 @@ class GlobalDataProduct:
71
86
  if self._object:
72
87
  return self._object
73
88
  else:
74
- self._object = Pipeline.get(self.object_uuid)
89
+ self._object = Pipeline.get(self.object_uuid, repo_path=self.repo_path)
75
90
 
76
91
  return self._object
77
92
 
93
+ def get_blocks(self) -> List:
94
+ arr = []
95
+
96
+ if not self.settings or len(self.settings) == 0:
97
+ return arr
98
+
99
+ if GlobalDataProductObjectType.PIPELINE == self.object_type:
100
+ for block_uuid in self.settings.keys():
101
+ arr.append(self.pipeline.get_block(block_uuid))
102
+
103
+ return arr
104
+
78
105
  def get_outputs(self, from_notebook: bool = False, global_vars: Dict = None, **kwargs) -> Dict:
79
106
  data = {}
80
107
 
@@ -125,12 +152,15 @@ class GlobalDataProduct:
125
152
 
126
153
  def get_outdated_at_delta(self, in_seconds: bool = False) -> relativedelta:
127
154
  outdated_after = self.outdated_after or {}
128
- delta = extract(outdated_after, [
129
- 'months',
130
- 'seconds',
131
- 'weeks',
132
- 'years',
133
- ])
155
+ delta = extract(
156
+ outdated_after,
157
+ [
158
+ 'months',
159
+ 'seconds',
160
+ 'weeks',
161
+ 'years',
162
+ ],
163
+ )
134
164
 
135
165
  if len(delta) >= 1:
136
166
  d = relativedelta(**delta)
@@ -220,8 +250,7 @@ class GlobalDataProduct:
220
250
  status: PipelineRun.PipelineRunStatus = None,
221
251
  ) -> List[PipelineRun]:
222
252
  pipeline_runs = (
223
- PipelineRun.
224
- select(
253
+ PipelineRun.select(
225
254
  PipelineRun.backfill_id,
226
255
  PipelineRun.completed_at,
227
256
  PipelineRun.created_at,
@@ -237,20 +266,20 @@ class GlobalDataProduct:
237
266
  PipelineRun.updated_at,
238
267
  PipelineRun.variables,
239
268
  PipelineSchedule.global_data_product_uuid,
240
- ).
241
- join(PipelineSchedule, PipelineRun.pipeline_schedule_id == PipelineSchedule.id).
242
- filter(
269
+ )
270
+ .join(
271
+ PipelineSchedule,
272
+ PipelineRun.pipeline_schedule_id == PipelineSchedule.id,
273
+ )
274
+ .filter(
243
275
  PipelineRun.pipeline_uuid == self.object_uuid,
244
276
  PipelineSchedule.global_data_product_uuid == self.uuid,
245
277
  )
246
278
  )
247
279
 
248
280
  if status:
249
- pipeline_runs = (
250
- pipeline_runs.
251
- filter(
252
- PipelineRun.status == status,
253
- )
281
+ pipeline_runs = pipeline_runs.filter(
282
+ PipelineRun.status == status,
254
283
  )
255
284
 
256
285
  pipeline_runs = pipeline_runs.order_by(PipelineRun.execution_date.desc())
@@ -258,23 +287,33 @@ class GlobalDataProduct:
258
287
  if limit is not None:
259
288
  pipeline_runs = pipeline_runs.limit(limit)
260
289
 
261
- return [PipelineRun(
262
- backfill_id=row.backfill_id,
263
- completed_at=row.completed_at,
264
- created_at=row.created_at,
265
- event_variables=row.event_variables,
266
- execution_date=row.execution_date,
267
- executor_type=row.executor_type,
268
- global_data_product_uuid=row.global_data_product_uuid,
269
- id=row.id,
270
- metrics=row.metrics,
271
- passed_sla=row.passed_sla,
272
- pipeline_schedule_id=row.pipeline_schedule_id,
273
- pipeline_uuid=row.pipeline_uuid,
274
- status=row.status,
275
- updated_at=row.updated_at,
276
- variables=row.variables,
277
- ) for row in pipeline_runs.all()]
290
+ return [
291
+ PipelineRun(
292
+ backfill_id=row.backfill_id,
293
+ completed_at=row.completed_at,
294
+ created_at=row.created_at,
295
+ event_variables=row.event_variables,
296
+ execution_date=row.execution_date,
297
+ executor_type=row.executor_type,
298
+ global_data_product_uuid=row.global_data_product_uuid,
299
+ id=row.id,
300
+ metrics=row.metrics,
301
+ passed_sla=row.passed_sla,
302
+ pipeline_schedule_id=row.pipeline_schedule_id,
303
+ pipeline_uuid=row.pipeline_uuid,
304
+ status=row.status,
305
+ updated_at=row.updated_at,
306
+ variables=row.variables,
307
+ )
308
+ for row in pipeline_runs.all()
309
+ ]
310
+
311
+ @property
312
+ def project_name(self) -> Optional[str]:
313
+ if self.repo_path:
314
+ parts = get_path_parts(self.repo_path)
315
+ if parts and len(parts) >= 3:
316
+ return parts[1]
278
317
 
279
318
  def to_dict(self, include_uuid: bool = False) -> Dict:
280
319
  data = dict(
@@ -282,6 +321,8 @@ class GlobalDataProduct:
282
321
  object_uuid=self.object_uuid,
283
322
  outdated_after=self.outdated_after,
284
323
  outdated_starting_at=self.outdated_starting_at,
324
+ project=self.project_name,
325
+ repo_path=self.repo_path,
285
326
  settings=self.settings,
286
327
  )
287
328
 
@@ -293,8 +334,8 @@ class GlobalDataProduct:
293
334
  def delete(self) -> None:
294
335
  self.save(delete=True)
295
336
 
296
- def save(self, delete: bool = False, file_path: str = None) -> None:
297
- mapping = index_by(lambda x: x.uuid, self.load_all())
337
+ def save(self, delete: bool = False) -> None:
338
+ mapping = index_by(lambda x: x.uuid, self.load_all(self.repo_path))
298
339
 
299
340
  if delete:
300
341
  mapping.pop(self.uuid, None)
@@ -312,7 +353,7 @@ class GlobalDataProduct:
312
353
  mapping_new[uuid][k] = v
313
354
 
314
355
  content = yaml.safe_dump(mapping_new)
315
- safe_write(file_path or self.file_path(), content)
356
+ safe_write(self.file_path(self.repo_path), content)
316
357
 
317
358
  def update(self, payload: Dict) -> None:
318
359
  for key in [
@@ -320,6 +361,7 @@ class GlobalDataProduct:
320
361
  'object_uuid',
321
362
  'outdated_after',
322
363
  'outdated_starting_at',
364
+ 'repo_path',
323
365
  'settings',
324
366
  ]:
325
367
  value = payload.get(key)
@@ -421,6 +421,7 @@ class Hook(BaseDataClass):
421
421
  if with_trigger or (self.run_settings and self.run_settings.with_trigger):
422
422
  pipeline_run = trigger_pipeline(
423
423
  self.pipeline.uuid,
424
+ repo_path=self.pipeline.repo_path,
424
425
  variables=variables,
425
426
  check_status=check_status and not asynchronous,
426
427
  error_on_failure=error_on_failure,