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
mage_ai/api/views.py CHANGED
@@ -34,8 +34,7 @@ async def execute_operation(
34
34
  if request.error:
35
35
  return __render_error(handler, request.error, **tags)
36
36
 
37
- action, options = __determine_action(
38
- request, child=child, child_pk=child_pk, pk=pk)
37
+ action, options = __determine_action(request, child=child, child_pk=child_pk, pk=pk)
39
38
  try:
40
39
  base_operation = BaseOperation(
41
40
  action=action,
@@ -68,13 +67,15 @@ async def execute_operation(
68
67
  if error_response:
69
68
  return __render_error(handler, error_response, **tags)
70
69
 
71
- info('Action: {} {} {} {} {}'.format(
72
- action,
73
- child or resource,
74
- child_pk or pk,
75
- resource if child else '',
76
- pk if child else '',
77
- ))
70
+ info(
71
+ 'Action: {} {} {} {} {}'.format(
72
+ action,
73
+ child or resource,
74
+ child_pk or pk,
75
+ resource if child else '',
76
+ pk if child else '',
77
+ )
78
+ )
78
79
  api_time = end_time.timestamp() - start_time.timestamp()
79
80
  info(f'Latency: {api_time:.4f} seconds')
80
81
  tags = dict(
@@ -87,11 +88,13 @@ async def execute_operation(
87
88
  timing('api.time', api_time, tags)
88
89
  timing('sql.time', api_time, tags)
89
90
 
90
- handler.write(simplejson.dumps(
91
- response,
92
- default=encode_complex,
93
- ignore_nan=True,
94
- ))
91
+ handler.write(
92
+ simplejson.dumps(
93
+ response,
94
+ default=encode_complex,
95
+ ignore_nan=True,
96
+ )
97
+ )
95
98
 
96
99
 
97
100
  def __determine_action(
@@ -148,19 +151,15 @@ def __meta(request) -> Dict:
148
151
 
149
152
 
150
153
  def __meta_keys(request) -> List[str]:
151
- return list(
152
- filter(
153
- lambda x: x[0] == '_', [
154
- k for k in request.query_arguments.keys()]))
154
+ return list(filter(lambda x: x[0] == '_', [k for k in request.query_arguments.keys()]))
155
155
 
156
156
 
157
157
  def __payload(request) -> Dict:
158
- if 'Content-Type' in request.headers and \
159
- 'multipart/form-data' in request.headers.get('Content-Type'):
160
-
158
+ if 'Content-Type' in request.headers and 'multipart/form-data' in request.headers.get(
159
+ 'Content-Type'
160
+ ):
161
161
  parts = request.body.decode('utf-8', 'ignore').split('\r\n')
162
- idx = parts.index(
163
- 'Content-Disposition: form-data; name="json_root_body"')
162
+ idx = parts.index('Content-Disposition: form-data; name="json_root_body"')
164
163
  json_root_body = parts[idx + 2]
165
164
 
166
165
  return json.loads(json_root_body)
@@ -193,15 +192,18 @@ def __query(request) -> Dict:
193
192
  else:
194
193
  obj[key] = value
195
194
  return obj
195
+
196
196
  return reduce(_build, request.query_arguments.keys() - meta_keys, {})
197
197
 
198
198
 
199
199
  def __render_error(handler, error: Dict, **kwargs):
200
200
  __log_error(handler.request, error, **kwargs)
201
- handler.write(dict(
202
- error=error,
203
- status=200,
204
- ))
201
+ handler.write(
202
+ dict(
203
+ error=error,
204
+ status=200,
205
+ )
206
+ )
205
207
 
206
208
 
207
209
  def __log_error(
@@ -225,16 +227,21 @@ def __log_error(
225
227
  if child_pk:
226
228
  endpoint += '/{}'.format(child_pk)
227
229
 
228
- error('[{}] [ERROR] {} /{} [user: {}]: {}'.format(
229
- datetime.utcnow(),
230
- request.method,
231
- endpoint,
232
- user_id,
233
- err,
234
- ))
235
-
236
- increment('api.error', tags=dict(
237
- endpoint=endpoint,
238
- error=err['type'] if isinstance(err, dict) else type(err).__name__,
239
- resource=resource,
240
- ))
230
+ error(
231
+ '[{}] [ERROR] {} /{} [user: {}]: {}'.format(
232
+ datetime.utcnow(),
233
+ request.method,
234
+ endpoint,
235
+ user_id,
236
+ err,
237
+ )
238
+ )
239
+
240
+ increment(
241
+ 'api.error',
242
+ tags=dict(
243
+ endpoint=endpoint,
244
+ error=err['type'] if isinstance(err, dict) else type(err).__name__,
245
+ resource=resource,
246
+ ),
247
+ )
@@ -1,5 +1,7 @@
1
+ import asyncio
1
2
  import importlib
2
3
  import inspect
4
+ import logging
3
5
  import os
4
6
 
5
7
  from mage_ai.api import policies
@@ -11,7 +13,7 @@ from mage_ai.authentication.permissions.constants import (
11
13
  PermissionAccess,
12
14
  PermissionCondition,
13
15
  )
14
- from mage_ai.orchestration.db import db_connection
16
+ from mage_ai.orchestration.db import db_connection, safe_db_query
15
17
  from mage_ai.orchestration.db.models.oauth import Permission, Role, RolePermission, User
16
18
 
17
19
  KEY_ADMIN = 'admin'
@@ -32,6 +34,9 @@ ROLE_NAME_TO_KEY = {
32
34
  }
33
35
 
34
36
 
37
+ logger = logging.getLogger(__name__)
38
+
39
+
35
40
  async def evaluate_condition(condition):
36
41
  if condition and inspect.isawaitable(condition):
37
42
  condition = await condition
@@ -224,6 +229,15 @@ async def attribute_rules(policy_class, rules):
224
229
  return mapping
225
230
 
226
231
 
232
+ def bootstrap_permissions_sync(policy_names: str = None):
233
+ loop = asyncio.get_event_loop()
234
+ if loop is not None:
235
+ loop.create_task(bootstrap_permissions(policy_names))
236
+ else:
237
+ asyncio.run(bootstrap_permissions(policy_names))
238
+
239
+
240
+ @safe_db_query
227
241
  async def bootstrap_permissions(policy_names: str = None):
228
242
  action_rules_mapping = {}
229
243
  query_rules_mapping = {}
@@ -248,7 +262,7 @@ async def bootstrap_permissions(policy_names: str = None):
248
262
  )
249
263
 
250
264
  model_name = policy_class.model_name()
251
- print(f'Processing {model_name}...')
265
+ logger.info(f'Processing {model_name}...')
252
266
  action_rules_mapping[model_name] = await action_rules(policy_class)
253
267
  query_rules_mapping[model_name] = await attribute_rules(
254
268
  policy_class,
@@ -1,3 +1,4 @@
1
+ import json
1
2
  import urllib.parse
2
3
  import uuid
3
4
  from typing import Awaitable, Dict
@@ -11,7 +12,12 @@ from mage_ai.authentication.providers.sso import SsoProvider
11
12
  from mage_ai.authentication.providers.utils import get_base_url
12
13
  from mage_ai.server.logger import Logger
13
14
  from mage_ai.settings import get_settings_value
14
- from mage_ai.settings.keys import OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC_DISCOVERY_URL
15
+ from mage_ai.settings.keys import (
16
+ OIDC_CLIENT_ID,
17
+ OIDC_CLIENT_SECRET,
18
+ OIDC_DISCOVERY_URL,
19
+ OIDC_ROLES_MAPPING,
20
+ )
15
21
 
16
22
  logger = Logger().new_server_logger(__name__)
17
23
 
@@ -25,6 +31,12 @@ class OidcProvider(OauthProvider, SsoProvider):
25
31
  self.client_secret = get_settings_value(OIDC_CLIENT_SECRET)
26
32
  self.__validate()
27
33
 
34
+ roles_mapping = get_settings_value(OIDC_ROLES_MAPPING)
35
+ if roles_mapping:
36
+ try:
37
+ self.roles_mapping = json.loads(roles_mapping)
38
+ except Exception:
39
+ logger.exception('Failed to parse OIDC roles mapping.')
28
40
  self.discover()
29
41
 
30
42
  def __validate(self):
@@ -115,6 +127,7 @@ class OidcProvider(OauthProvider, SsoProvider):
115
127
  async def get_user_info(self, access_token: str = None, **kwargs) -> Awaitable[Dict]:
116
128
  if access_token is None:
117
129
  raise Exception('Access token is required to fetch user info.')
130
+ mage_roles = []
118
131
  async with aiohttp.ClientSession() as session:
119
132
  async with session.get(
120
133
  self.userinfo_endpoint,
@@ -127,8 +140,15 @@ class OidcProvider(OauthProvider, SsoProvider):
127
140
  userinfo_resp = await response.json()
128
141
 
129
142
  email = userinfo_resp.get('email')
143
+ if hasattr(self, 'roles_mapping'):
144
+ for group in userinfo_resp.get('user_roles', []):
145
+ if group in self.roles_mapping:
146
+ mage_roles.append(self.roles_mapping[group])
147
+ else:
148
+ mage_roles.extend(userinfo_resp.get('user_roles', []))
130
149
 
131
150
  return dict(
132
151
  email=email,
133
152
  username=userinfo_resp.get('preferred_username', email),
153
+ user_roles=mage_roles,
134
154
  )
@@ -1,11 +1,12 @@
1
- from functools import reduce
2
- from mage_ai.shared.utils import files_in_path
3
- import aiofiles
4
1
  import importlib
5
2
  import os
6
3
  import pathlib
7
4
  import re
5
+ from functools import reduce
8
6
 
7
+ import aiofiles
8
+
9
+ from mage_ai.shared.utils import files_in_path
9
10
 
10
11
  root_path = '/'.join(str(pathlib.Path(__file__).parent.resolve()).split('/')[:-2])
11
12
 
@@ -27,7 +28,7 @@ def add_file(acc, path):
27
28
 
28
29
  def __should_include(file_name):
29
30
  tup = os.path.splitext(file_name)
30
- if (len(tup) >= 2):
31
+ if len(tup) >= 2:
31
32
  file_extension = tup[1]
32
33
  return file_extension in FILE_EXTENSIONS_TO_INCLUDE
33
34
 
@@ -60,6 +61,7 @@ def extract_all_imports(file_content, ignore_nesting=False):
60
61
  r'import [\w.]+',
61
62
  r'from [\w.]+ import [\w.]+ as [\w.]+',
62
63
  r'from [\w.]+ import [\w.]+',
64
+ r'from [\w.]+ import \(',
63
65
  ]
64
66
  regexes = []
65
67
 
@@ -89,7 +91,7 @@ async def build_file_content_mapping(paths, files):
89
91
  module_name = '.'.join(parts).replace('.py', '')
90
92
 
91
93
  if '__init__.py' == parts[-1]:
92
- path_sub = '/'.join(parts[:len(parts) - 1])
94
+ path_sub = '/'.join(parts[: len(parts) - 1])
93
95
  files += [fn for fn in reduce(add_file, [path_sub], []) if fn != file_name]
94
96
  module_name = module_name.replace('.__init__', '')
95
97
 
@@ -101,10 +103,12 @@ async def build_file_content_mapping(paths, files):
101
103
  importlib.import_module(module_name),
102
104
  class_name,
103
105
  )
104
- methods_for_class[class_name] = list(filter(
105
- lambda x: not re.match('^_', x),
106
- dir(klass),
107
- ))
106
+ methods_for_class[class_name] = list(
107
+ filter(
108
+ lambda x: not re.match('^_', x),
109
+ dir(klass),
110
+ )
111
+ )
108
112
  except ImportError as err:
109
113
  print(err)
110
114
 
mage_ai/cache/base.py CHANGED
@@ -69,7 +69,7 @@ class BaseCache():
69
69
 
70
70
  def build_path(self, key: str) -> str:
71
71
  dir_path = os.getenv(MAGE_CACHE_DIRECTORY_ENVIRONMENT_VARIABLE_NAME) or os.path.join(
72
- get_variables_dir(repo_path=self.repo_path),
72
+ get_variables_dir(repo_path=self.repo_path, root_project=self.root_project),
73
73
  MAGE_CACHE_DIRECTORY_DEFAULT,
74
74
  )
75
75
 
mage_ai/cache/block.py CHANGED
@@ -12,6 +12,7 @@ from mage_ai.data_preparation.models.constants import (
12
12
  BLOCK_LANGUAGE_TO_FILE_EXTENSION,
13
13
  BlockType,
14
14
  )
15
+ from mage_ai.data_preparation.models.utils import warn_for_repo_path
15
16
  from mage_ai.settings.repo import get_repo_path
16
17
  from mage_ai.shared.path_fixer import remove_base_repo_path_or_name
17
18
 
@@ -50,7 +51,10 @@ class BlockCache(BaseCache):
50
51
  block_language = ''
51
52
  configuration = None
52
53
  file_path = None
53
- repo_path = repo_path or get_repo_path(root_project=False)
54
+
55
+ warn_for_repo_path(repo_path)
56
+
57
+ repo_path = repo_path or get_repo_path()
54
58
 
55
59
  if isinstance(block, dict):
56
60
  block_type = block.get('type')
@@ -83,12 +87,12 @@ class BlockCache(BaseCache):
83
87
 
84
88
  return remove_base_repo_path_or_name(file_path)
85
89
 
86
- def get_pipelines(self, block) -> List[Dict]:
90
+ def get_pipelines(self, block, repo_path: str) -> List[Dict]:
87
91
  pipelines = []
88
92
 
89
93
  mapping = self.get(self.cache_key)
90
94
  if mapping is not None:
91
- key = self.build_key(block)
95
+ key = self.build_key(block, repo_path=repo_path)
92
96
  if key:
93
97
  return (mapping.get(key) or {}).get('pipelines', [])
94
98
 
@@ -105,15 +109,15 @@ class BlockCache(BaseCache):
105
109
 
106
110
  return pipeline_count_mapping
107
111
 
108
- def add_pipeline(self, block, pipeline) -> None:
109
- self.update_pipeline(block, pipeline, added_at=datetime.utcnow().timestamp())
112
+ def add_pipeline(self, block, pipeline, repo_path: str) -> None:
113
+ self.update_pipeline(block, pipeline, repo_path, added_at=datetime.utcnow().timestamp())
110
114
 
111
- def move_pipelines(self, new_block, old_block) -> None:
112
- new_key = self.build_key(new_block)
115
+ def move_pipelines(self, new_block, old_block, repo_path: str) -> None:
116
+ new_key = self.build_key(new_block, repo_path=repo_path)
113
117
  if not new_key:
114
118
  return
115
119
 
116
- old_key = self.build_key(old_block)
120
+ old_key = self.build_key(old_block, repo_path=repo_path)
117
121
  if not old_key:
118
122
  return
119
123
 
@@ -131,17 +135,19 @@ class BlockCache(BaseCache):
131
135
  self,
132
136
  block,
133
137
  pipeline,
138
+ repo_path: str,
134
139
  added_at: str = None,
135
140
  ) -> None:
136
- self.update_pipelines(block, [pipeline], added_at)
141
+ self.update_pipelines(block, [pipeline], repo_path, added_at)
137
142
 
138
143
  def update_pipelines(
139
144
  self,
140
145
  block,
141
146
  pipelines,
147
+ repo_path: str,
142
148
  added_at: str = None,
143
149
  ) -> None:
144
- key = self.build_key(block)
150
+ key = self.build_key(block, repo_path=repo_path)
145
151
  if not key:
146
152
  return
147
153
 
@@ -191,8 +197,8 @@ class BlockCache(BaseCache):
191
197
 
192
198
  self.set(self.cache_key, mapping)
193
199
 
194
- def remove_block(self, block) -> None:
195
- key = self.build_key(block)
200
+ def remove_block(self, block, repo_path: str) -> None:
201
+ key = self.build_key(block, repo_path=repo_path)
196
202
  if not key:
197
203
  return
198
204
 
@@ -84,10 +84,14 @@ class BlockActionObjectCache(BaseCache):
84
84
  cache_key = CACHE_KEY_BLOCK_ACTION_OBJECTS_MAPPING
85
85
 
86
86
  @classmethod
87
- async def initialize_cache(self, replace: bool = False) -> 'BlockActionObjectCache':
87
+ async def initialize_cache(
88
+ self,
89
+ project: Project = None,
90
+ replace: bool = False,
91
+ ) -> 'BlockActionObjectCache':
88
92
  cache = self()
89
93
  if replace or not cache.exists():
90
- await cache.initialize_cache_for_all_objects()
94
+ await cache.initialize_cache_for_all_objects(project=project)
91
95
 
92
96
  return cache
93
97
 
@@ -233,21 +237,43 @@ class BlockActionObjectCache(BaseCache):
233
237
 
234
238
  self.set(self.cache_key, mapping)
235
239
 
236
- async def initialize_cache_for_all_objects(self) -> None:
240
+ async def initialize_cache_for_all_objects(self, project=None) -> None:
241
+ """
242
+ Initializes a cache for various types of objects across all projects.
243
+
244
+ This method populates a mapping dictionary with cached data for different types of objects,
245
+ including mage templates, custom block templates, and block files, from all projects.
246
+
247
+ - `OBJECT_TYPE_BLOCK_FILE`: Cache for block files.
248
+ - `OBJECT_TYPE_CUSTOM_BLOCK_TEMPLATE`: Cache for custom block templates.
249
+ - `OBJECT_TYPE_MAGE_TEMPLATE`: Cache for mage templates.
250
+
251
+ The caching process includes fetching templates relevant to all projects,
252
+ processing custom block templates from a directory,
253
+ and gathering data for block files from all projects' directories.
254
+
255
+ The cache is constructed and stored using the `set` method.
256
+
257
+ Returns:
258
+ None: This method does not return any value, it updates the cache for all objects.
259
+ """
237
260
  mapping = {
238
261
  OBJECT_TYPE_BLOCK_FILE: {},
239
262
  OBJECT_TYPE_CUSTOM_BLOCK_TEMPLATE: {},
240
263
  OBJECT_TYPE_MAGE_TEMPLATE: {},
241
264
  }
242
265
 
266
+ # Cache Mage templates
243
267
  mage_templates = TEMPLATES + TEMPLATES_ONLY_FOR_V2
244
- if Project().is_feature_enabled(FeatureUUID.DATA_INTEGRATION_IN_BATCH_PIPELINE):
268
+ project = project or Project()
269
+ if project.is_feature_enabled(FeatureUUID.DATA_INTEGRATION_IN_BATCH_PIPELINE):
245
270
  mage_templates += get_templates_for_data_integrations()
246
271
 
247
272
  for block_action_object in mage_templates:
248
273
  key = self.build_key_for_mage_template(block_action_object)
249
274
  mapping[OBJECT_TYPE_MAGE_TEMPLATE][key] = block_action_object
250
275
 
276
+ # Cache custom block templates
251
277
  file_dicts = get_templates(DIRECTORY_FOR_BLOCK_TEMPLATES)
252
278
  file_dicts_flat = flatten_files(file_dicts)
253
279
  custom_block_templates = group_and_hydrate_files(file_dicts_flat, CustomBlockTemplate)
@@ -258,9 +284,11 @@ class BlockActionObjectCache(BaseCache):
258
284
  include_content=True,
259
285
  )
260
286
 
287
+ # Cache block files
261
288
  paths_to_traverse = [dict(full_path=base_repo_path())]
262
289
  if project_platform_activated():
263
290
  paths_to_traverse = build_repo_path_for_all_projects(mage_projects_only=True).values()
291
+
264
292
  for path_dict in paths_to_traverse:
265
293
  repo_path = path_dict['full_path']
266
294
 
@@ -294,7 +322,7 @@ class BlockActionObjectCache(BaseCache):
294
322
  )
295
323
 
296
324
  content = None
297
- with open(block_file_absolute_path, 'r') as f:
325
+ with open(block_file_absolute_path, 'r', encoding='utf-8') as f:
298
326
  content = f.read()
299
327
 
300
328
  mapping[OBJECT_TYPE_BLOCK_FILE][key] = dict(
mage_ai/cache/file.py CHANGED
@@ -12,7 +12,7 @@ from mage_ai.settings.utils import base_repo_path
12
12
  from mage_ai.shared.files import get_absolute_paths_from_all_files
13
13
  from mage_ai.shared.strings import size_of_string
14
14
 
15
- FILENAME_DELIMITER = '\t'
15
+ FILENAME_DELIMITER = "\t"
16
16
 
17
17
 
18
18
  class FileCache(BaseCache):
@@ -23,7 +23,7 @@ class FileCache(BaseCache):
23
23
  self,
24
24
  absolute_paths: List[str],
25
25
  replace: bool = False,
26
- ) -> 'FileCache':
26
+ ) -> "FileCache":
27
27
  repo_path = get_repo_path(root_project=True)
28
28
  cache = self(repo_path=repo_path)
29
29
 
@@ -33,7 +33,7 @@ class FileCache(BaseCache):
33
33
  return cache
34
34
 
35
35
  @classmethod
36
- def initialize_cache_with_settings(self, replace: bool = False) -> 'FileCache':
36
+ def initialize_cache_with_settings(self, replace: bool = False) -> "FileCache":
37
37
  # Include all projects from platform
38
38
  # Relative to the base repo path
39
39
  base_path = base_repo_path()
@@ -45,10 +45,7 @@ class FileCache(BaseCache):
45
45
 
46
46
  # Include directories listed in command center settings and exclude those listed.
47
47
  settings = CommandCenterSettings.load_from_file_path()
48
- if settings and \
49
- settings.cache and \
50
- settings.cache.files:
51
-
48
+ if settings and settings.cache and settings.cache.files:
52
49
  if settings.cache.files.directories:
53
50
  paths.extend(settings.cache.files.directories.includes or [])
54
51
  paths_excludes.extend(settings.cache.files.directories.excludes or [])
@@ -60,11 +57,12 @@ class FileCache(BaseCache):
60
57
  for project_name, path_dict in build_repo_path_for_all_projects(
61
58
  mage_projects_only=True,
62
59
  ).items():
63
- path = path_dict.get('path')
64
- if path and \
65
- project_name not in projects_excludes and \
66
- all([not path.startswith(ex) for ex in paths_excludes]):
67
-
60
+ path = path_dict.get("path")
61
+ if (
62
+ path
63
+ and project_name not in projects_excludes
64
+ and all([not path.startswith(ex) for ex in paths_excludes])
65
+ ):
68
66
  paths.append(path)
69
67
 
70
68
  paths = [os.path.join(base_path, path) for path in paths]
@@ -89,17 +87,20 @@ class FileCache(BaseCache):
89
87
  try:
90
88
  diff = Path(file_path).relative_to(base_path)
91
89
  except Exception as err:
92
- print(f'[ERROR] FileCache.build_cache: {err}.')
90
+ print(f"[ERROR] FileCache.build_cache: {err}.")
93
91
  diff = file_path
94
92
 
95
- return f'{diff},{file_size},{file_modified_time}'
93
+ return f"{diff},{file_size},{file_modified_time}"
96
94
 
97
95
  arr_init = []
98
96
  for absolute_path in absolute_paths:
99
- arr_init.extend(get_absolute_paths_from_all_files(
100
- absolute_path,
101
- parse_values=__parse_values,
102
- ))
97
+ arr_init.extend(
98
+ get_absolute_paths_from_all_files(
99
+ absolute_path,
100
+ comparator=lambda absolute_path: not absolute_path.endswith(".pyc"),
101
+ parse_values=__parse_values,
102
+ )
103
+ )
103
104
 
104
105
  if arr_init and len(arr_init) >= 1:
105
106
  arr_init.sort()
@@ -117,7 +118,9 @@ class FileCache(BaseCache):
117
118
 
118
119
  self.set(self.cache_key, FILENAME_DELIMITER.join(arr))
119
120
  else:
120
- print('[WARNING] FileCache.build_cache: 0 files cached, this may be a mistake.')
121
+ print(
122
+ "[WARNING] FileCache.build_cache: 0 files cached, this may be a mistake."
123
+ )
121
124
 
122
125
  return arr
123
126
 
mage_ai/cache/pipeline.py CHANGED
@@ -5,6 +5,7 @@ from typing import Any, Dict, List, Union
5
5
  from mage_ai.cache.base import BaseCache
6
6
  from mage_ai.cache.constants import CACHE_KEY_PIPELINE_DETAILS_MAPPING
7
7
  from mage_ai.cache.utils import build_pipeline_dict, group_models_by_keys
8
+ from mage_ai.data_preparation.models.utils import warn_for_repo_path
8
9
  from mage_ai.settings.repo import get_repo_path
9
10
  from mage_ai.shared.path_fixer import remove_base_repo_path_or_name
10
11
 
@@ -63,16 +64,17 @@ class PipelineCache(BaseCache):
63
64
  return pipeline_uuid
64
65
 
65
66
  if not repo_path:
66
- repo_path = get_repo_path(root_project=False)
67
+ warn_for_repo_path(repo_path)
68
+ repo_path = get_repo_path()
67
69
 
68
70
  return ':'.join([remove_base_repo_path_or_name(repo_path), pipeline_uuid])
69
71
 
70
- def get_model(self, model) -> Dict:
72
+ def get_model(self, model, repo_path: str = None) -> Dict:
71
73
  model_dict = {}
72
74
 
73
75
  mapping = self.get(self.cache_key)
74
76
  if mapping is not None:
75
- key = self.build_key(model)
77
+ key = self.build_key(model, repo_path=repo_path)
76
78
  if key:
77
79
  model_dict = mapping.get(key, {})
78
80
 
@@ -93,13 +95,14 @@ class PipelineCache(BaseCache):
93
95
  self,
94
96
  pipelines,
95
97
  added_at: str = None,
98
+ repo_path: str = None,
96
99
  ) -> None:
97
100
  mapping = self.get(self.cache_key)
98
101
  if mapping is None:
99
102
  mapping = {}
100
103
 
101
104
  for pipeline in pipelines:
102
- key = self.build_key(pipeline)
105
+ key = self.build_key(pipeline, repo_path=repo_path)
103
106
  if not key:
104
107
  continue
105
108
 
@@ -115,18 +118,21 @@ class PipelineCache(BaseCache):
115
118
  self,
116
119
  pipeline,
117
120
  added_at: str = None,
121
+ repo_path: str = None,
118
122
  ) -> None:
119
- self.update_models([pipeline], added_at)
123
+ self.update_models([pipeline], added_at=added_at, repo_path=repo_path)
120
124
 
121
- def add_model(self, model) -> None:
122
- self.update_model(model, added_at=datetime.utcnow().timestamp())
125
+ def add_model(self, model, repo_path: str = None) -> None:
126
+ self.update_model(
127
+ model, added_at=datetime.utcnow().timestamp(), repo_path=repo_path
128
+ )
123
129
 
124
- def move_model(self, new_model, old_model) -> None:
125
- new_key = self.build_key(new_model)
130
+ def move_model(self, new_model, old_model, repo_path: str = None) -> None:
131
+ new_key = self.build_key(new_model, repo_path=repo_path)
126
132
  if not new_key:
127
133
  return
128
134
 
129
- old_key = self.build_key(old_model)
135
+ old_key = self.build_key(old_model, repo_path=repo_path)
130
136
  if not old_key:
131
137
  return
132
138
 
@@ -140,8 +146,8 @@ class PipelineCache(BaseCache):
140
146
 
141
147
  self.set(self.cache_key, mapping)
142
148
 
143
- def remove_model(self, model) -> None:
144
- key = self.build_key(model)
149
+ def remove_model(self, model, repo_path: str = None) -> None:
150
+ key = self.build_key(model, repo_path=repo_path)
145
151
  if not key:
146
152
  return
147
153
 
mage_ai/cli/main.py CHANGED
@@ -22,6 +22,7 @@ class OrderCommands(TyperGroup):
22
22
 
23
23
  app = typer.Typer(
24
24
  cls=OrderCommands,
25
+ pretty_exceptions_show_locals=False,
25
26
  )
26
27
 
27
28
  # Defaults