mage-ai 0.9.70__py3-none-any.whl → 0.9.71__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (568) hide show
  1. mage_ai/ai/utils/xgboost.py +222 -0
  2. mage_ai/api/errors.py +37 -25
  3. mage_ai/api/operations/base.py +13 -1
  4. mage_ai/api/parsers/PipelineScheduleParser.py +1 -1
  5. mage_ai/api/policies/BlockOutputPolicy.py +40 -17
  6. mage_ai/api/policies/GlobalDataProductPolicy.py +91 -41
  7. mage_ai/api/policies/KernelPolicy.py +55 -32
  8. mage_ai/api/policies/KernelProcessPolicy.py +56 -0
  9. mage_ai/api/policies/OutputPolicy.py +73 -41
  10. mage_ai/api/policies/PipelinePolicy.py +206 -138
  11. mage_ai/api/presenters/BlockLayoutItemPresenter.py +9 -7
  12. mage_ai/api/presenters/BlockPresenter.py +1 -1
  13. mage_ai/api/presenters/GlobalDataProductPresenter.py +6 -1
  14. mage_ai/api/presenters/KernelPresenter.py +5 -26
  15. mage_ai/api/presenters/KernelProcessPresenter.py +28 -0
  16. mage_ai/api/presenters/PipelinePresenter.py +18 -5
  17. mage_ai/api/presenters/StatusPresenter.py +2 -0
  18. mage_ai/api/presenters/SyncPresenter.py +25 -0
  19. mage_ai/api/resources/AutocompleteItemResource.py +1 -1
  20. mage_ai/api/resources/BlockLayoutItemResource.py +90 -44
  21. mage_ai/api/resources/BlockOutputResource.py +42 -9
  22. mage_ai/api/resources/BlockResource.py +4 -3
  23. mage_ai/api/resources/BlockRunResource.py +27 -22
  24. mage_ai/api/resources/ClusterResource.py +4 -1
  25. mage_ai/api/resources/CustomTemplateResource.py +34 -14
  26. mage_ai/api/resources/DataProviderResource.py +1 -1
  27. mage_ai/api/resources/ExecutionStateResource.py +3 -1
  28. mage_ai/api/resources/FileContentResource.py +8 -2
  29. mage_ai/api/resources/FileResource.py +10 -4
  30. mage_ai/api/resources/FileVersionResource.py +3 -1
  31. mage_ai/api/resources/GitBranchResource.py +46 -9
  32. mage_ai/api/resources/GlobalDataProductResource.py +44 -7
  33. mage_ai/api/resources/GlobalHookResource.py +4 -1
  34. mage_ai/api/resources/IntegrationDestinationResource.py +6 -2
  35. mage_ai/api/resources/IntegrationSourceResource.py +8 -4
  36. mage_ai/api/resources/IntegrationSourceStreamResource.py +6 -2
  37. mage_ai/api/resources/KernelProcessResource.py +44 -0
  38. mage_ai/api/resources/KernelResource.py +25 -3
  39. mage_ai/api/resources/OutputResource.py +33 -11
  40. mage_ai/api/resources/PageBlockLayoutResource.py +34 -23
  41. mage_ai/api/resources/PipelineInteractionResource.py +31 -15
  42. mage_ai/api/resources/PipelineResource.py +250 -123
  43. mage_ai/api/resources/PipelineRunResource.py +11 -3
  44. mage_ai/api/resources/PipelineScheduleResource.py +7 -2
  45. mage_ai/api/resources/PipelineTriggerResource.py +6 -1
  46. mage_ai/api/resources/ProjectResource.py +18 -7
  47. mage_ai/api/resources/SecretResource.py +1 -1
  48. mage_ai/api/resources/SeedResource.py +8 -1
  49. mage_ai/api/resources/StatusResource.py +21 -6
  50. mage_ai/api/resources/SyncResource.py +6 -8
  51. mage_ai/api/resources/VariableResource.py +46 -26
  52. mage_ai/api/resources/VersionControlProjectResource.py +9 -2
  53. mage_ai/api/resources/WidgetResource.py +1 -1
  54. mage_ai/api/resources/WorkspaceResource.py +1 -1
  55. mage_ai/api/views.py +47 -40
  56. mage_ai/authentication/permissions/seed.py +16 -2
  57. mage_ai/authentication/providers/oidc.py +21 -1
  58. mage_ai/autocomplete/utils.py +13 -9
  59. mage_ai/cache/base.py +1 -1
  60. mage_ai/cache/block.py +18 -12
  61. mage_ai/cache/block_action_object/__init__.py +32 -4
  62. mage_ai/cache/file.py +22 -19
  63. mage_ai/cache/pipeline.py +18 -12
  64. mage_ai/cli/main.py +1 -0
  65. mage_ai/cluster_manager/aws/emr_cluster_manager.py +9 -5
  66. mage_ai/cluster_manager/config.py +2 -2
  67. mage_ai/cluster_manager/manage.py +1 -1
  68. mage_ai/cluster_manager/workspace/base.py +1 -1
  69. mage_ai/command_center/applications/factory.py +10 -7
  70. mage_ai/command_center/files/factory.py +17 -15
  71. mage_ai/command_center/utils.py +25 -13
  72. mage_ai/data/__init__.py +0 -0
  73. mage_ai/data/constants.py +45 -0
  74. mage_ai/data/models/__init__.py +0 -0
  75. mage_ai/data/models/base.py +119 -0
  76. mage_ai/data/models/constants.py +1 -0
  77. mage_ai/data/models/generator.py +115 -0
  78. mage_ai/data/models/manager.py +168 -0
  79. mage_ai/data/models/pyarrow/__init__.py +0 -0
  80. mage_ai/data/models/pyarrow/record_batch.py +55 -0
  81. mage_ai/data/models/pyarrow/shared.py +21 -0
  82. mage_ai/data/models/pyarrow/table.py +8 -0
  83. mage_ai/data/models/reader.py +103 -0
  84. mage_ai/data/models/utils.py +59 -0
  85. mage_ai/data/models/writer.py +91 -0
  86. mage_ai/data/tabular/__init__.py +0 -0
  87. mage_ai/data/tabular/constants.py +23 -0
  88. mage_ai/data/tabular/mocks.py +19 -0
  89. mage_ai/data/tabular/models.py +126 -0
  90. mage_ai/data/tabular/reader.py +602 -0
  91. mage_ai/data/tabular/utils.py +102 -0
  92. mage_ai/data/tabular/writer.py +266 -0
  93. mage_ai/data/variables/__init__.py +0 -0
  94. mage_ai/data/variables/wrapper.py +54 -0
  95. mage_ai/data_cleaner/analysis/charts.py +61 -39
  96. mage_ai/data_cleaner/column_types/column_type_detector.py +53 -31
  97. mage_ai/data_cleaner/estimators/encoders.py +5 -2
  98. mage_ai/data_integrations/utils/scheduler.py +16 -11
  99. mage_ai/data_preparation/decorators.py +1 -0
  100. mage_ai/data_preparation/executors/block_executor.py +237 -155
  101. mage_ai/data_preparation/executors/streaming_pipeline_executor.py +1 -1
  102. mage_ai/data_preparation/git/__init__.py +27 -7
  103. mage_ai/data_preparation/git/api.py +7 -1
  104. mage_ai/data_preparation/git/utils.py +22 -16
  105. mage_ai/data_preparation/logging/logger_manager.py +4 -3
  106. mage_ai/data_preparation/models/block/__init__.py +1542 -878
  107. mage_ai/data_preparation/models/block/data_integration/mixins.py +4 -3
  108. mage_ai/data_preparation/models/block/dynamic/__init__.py +17 -6
  109. mage_ai/data_preparation/models/block/dynamic/child.py +41 -102
  110. mage_ai/data_preparation/models/block/dynamic/constants.py +1 -0
  111. mage_ai/data_preparation/models/block/dynamic/counter.py +296 -0
  112. mage_ai/data_preparation/models/block/dynamic/data.py +16 -0
  113. mage_ai/data_preparation/models/block/dynamic/factory.py +163 -0
  114. mage_ai/data_preparation/models/block/dynamic/models.py +19 -0
  115. mage_ai/data_preparation/models/block/dynamic/shared.py +92 -0
  116. mage_ai/data_preparation/models/block/dynamic/utils.py +291 -168
  117. mage_ai/data_preparation/models/block/dynamic/variables.py +384 -144
  118. mage_ai/data_preparation/models/block/dynamic/wrappers.py +77 -0
  119. mage_ai/data_preparation/models/block/extension/utils.py +10 -1
  120. mage_ai/data_preparation/models/block/global_data_product/__init__.py +10 -1
  121. mage_ai/data_preparation/models/block/integration/__init__.py +6 -2
  122. mage_ai/data_preparation/models/block/outputs.py +722 -0
  123. mage_ai/data_preparation/models/block/platform/mixins.py +7 -8
  124. mage_ai/data_preparation/models/block/r/__init__.py +56 -38
  125. mage_ai/data_preparation/models/block/settings/__init__.py +0 -0
  126. mage_ai/data_preparation/models/block/settings/dynamic/__init__.py +0 -0
  127. mage_ai/data_preparation/models/block/settings/dynamic/constants.py +7 -0
  128. mage_ai/data_preparation/models/block/settings/dynamic/mixins.py +118 -0
  129. mage_ai/data_preparation/models/block/settings/dynamic/models.py +31 -0
  130. mage_ai/data_preparation/models/block/settings/global_data_products/__init__.py +0 -0
  131. mage_ai/data_preparation/models/block/settings/global_data_products/mixins.py +20 -0
  132. mage_ai/data_preparation/models/block/settings/global_data_products/models.py +46 -0
  133. mage_ai/data_preparation/models/block/settings/variables/__init__.py +0 -0
  134. mage_ai/data_preparation/models/block/settings/variables/mixins.py +74 -0
  135. mage_ai/data_preparation/models/block/settings/variables/models.py +49 -0
  136. mage_ai/data_preparation/models/block/spark/mixins.py +2 -1
  137. mage_ai/data_preparation/models/block/sql/__init__.py +30 -5
  138. mage_ai/data_preparation/models/block/sql/utils/shared.py +21 -3
  139. mage_ai/data_preparation/models/block/utils.py +127 -70
  140. mage_ai/data_preparation/models/constants.py +19 -14
  141. mage_ai/data_preparation/models/custom_templates/custom_block_template.py +18 -13
  142. mage_ai/data_preparation/models/custom_templates/custom_pipeline_template.py +33 -16
  143. mage_ai/data_preparation/models/custom_templates/utils.py +1 -1
  144. mage_ai/data_preparation/models/file.py +41 -28
  145. mage_ai/data_preparation/models/global_data_product/__init__.py +88 -58
  146. mage_ai/data_preparation/models/global_hooks/models.py +1 -0
  147. mage_ai/data_preparation/models/interfaces.py +29 -0
  148. mage_ai/data_preparation/models/pipeline.py +365 -180
  149. mage_ai/data_preparation/models/pipelines/integration_pipeline.py +1 -2
  150. mage_ai/data_preparation/models/pipelines/seed.py +1 -1
  151. mage_ai/data_preparation/models/project/__init__.py +66 -18
  152. mage_ai/data_preparation/models/project/constants.py +2 -0
  153. mage_ai/data_preparation/models/triggers/__init__.py +120 -24
  154. mage_ai/data_preparation/models/utils.py +467 -17
  155. mage_ai/data_preparation/models/variable.py +1028 -137
  156. mage_ai/data_preparation/models/variables/__init__.py +0 -0
  157. mage_ai/data_preparation/models/variables/cache.py +149 -0
  158. mage_ai/data_preparation/models/variables/constants.py +72 -0
  159. mage_ai/data_preparation/models/variables/summarizer.py +336 -0
  160. mage_ai/data_preparation/models/variables/utils.py +77 -0
  161. mage_ai/data_preparation/models/widget/__init__.py +63 -41
  162. mage_ai/data_preparation/models/widget/charts.py +40 -27
  163. mage_ai/data_preparation/models/widget/constants.py +2 -0
  164. mage_ai/data_preparation/models/widget/utils.py +3 -3
  165. mage_ai/data_preparation/preferences.py +3 -3
  166. mage_ai/data_preparation/repo_manager.py +55 -21
  167. mage_ai/data_preparation/storage/base_storage.py +2 -2
  168. mage_ai/data_preparation/storage/gcs_storage.py +7 -4
  169. mage_ai/data_preparation/storage/local_storage.py +6 -3
  170. mage_ai/data_preparation/storage/s3_storage.py +5 -2
  171. mage_ai/data_preparation/templates/data_exporters/streaming/oracledb.yaml +8 -0
  172. mage_ai/data_preparation/variable_manager.py +281 -76
  173. mage_ai/io/base.py +3 -2
  174. mage_ai/io/bigquery.py +1 -0
  175. mage_ai/io/redshift.py +7 -5
  176. mage_ai/kernels/__init__.py +0 -0
  177. mage_ai/kernels/models.py +188 -0
  178. mage_ai/kernels/utils.py +169 -0
  179. mage_ai/orchestration/concurrency.py +6 -2
  180. mage_ai/orchestration/db/__init__.py +1 -0
  181. mage_ai/orchestration/db/migrations/versions/0227396a216c_add_userproject_table.py +38 -0
  182. mage_ai/orchestration/db/models/dynamic/__init__.py +0 -0
  183. mage_ai/orchestration/db/models/dynamic/controller.py +67 -0
  184. mage_ai/orchestration/db/models/oauth.py +2 -9
  185. mage_ai/orchestration/db/models/projects.py +10 -0
  186. mage_ai/orchestration/db/models/schedules.py +204 -187
  187. mage_ai/orchestration/db/models/schedules_project_platform.py +18 -12
  188. mage_ai/orchestration/db/models/utils.py +46 -5
  189. mage_ai/orchestration/metrics/pipeline_run.py +8 -9
  190. mage_ai/orchestration/notification/sender.py +1 -0
  191. mage_ai/orchestration/pipeline_scheduler_original.py +32 -8
  192. mage_ai/orchestration/pipeline_scheduler_project_platform.py +1 -1
  193. mage_ai/orchestration/run_status_checker.py +11 -4
  194. mage_ai/orchestration/triggers/api.py +12 -1
  195. mage_ai/presenters/charts/data_sources/base.py +4 -2
  196. mage_ai/presenters/charts/data_sources/block.py +15 -9
  197. mage_ai/presenters/charts/data_sources/chart_code.py +8 -5
  198. mage_ai/presenters/charts/data_sources/constants.py +1 -0
  199. mage_ai/presenters/charts/data_sources/system_metrics.py +22 -0
  200. mage_ai/presenters/interactions/models.py +11 -7
  201. mage_ai/presenters/pages/loaders/pipelines.py +5 -3
  202. mage_ai/presenters/pages/models/page_components/pipeline_schedules.py +3 -1
  203. mage_ai/presenters/utils.py +2 -0
  204. mage_ai/server/api/blocks.py +2 -1
  205. mage_ai/server/api/downloads.py +5 -1
  206. mage_ai/server/api/triggers.py +3 -1
  207. mage_ai/server/constants.py +1 -1
  208. mage_ai/server/frontend_dist/404.html +5 -5
  209. mage_ai/server/frontend_dist/_next/static/UZLabyPgcxtZvp0O0EUUS/_buildManifest.js +1 -0
  210. mage_ai/server/frontend_dist/_next/static/chunks/1376-22de38b4ad008d8a.js +1 -0
  211. mage_ai/server/frontend_dist/_next/static/chunks/{1557-b3502f3f1aa92ac7.js → 1557-25a7d985d5564fd3.js} +1 -1
  212. mage_ai/server/frontend_dist/_next/static/chunks/1668-30b4619b9534519b.js +1 -0
  213. mage_ai/server/frontend_dist/_next/static/chunks/1799-c42db95a015689ee.js +1 -0
  214. mage_ai/server/frontend_dist/_next/static/chunks/2996-2108b53b9d371d8d.js +1 -0
  215. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/3763-61b542dafdbf5754.js → frontend_dist/_next/static/chunks/3763-40780c6d1e4b261d.js} +1 -1
  216. mage_ai/server/frontend_dist/_next/static/chunks/3782-129dd2a2448a2e36.js +1 -0
  217. mage_ai/server/frontend_dist/_next/static/chunks/3958-bcdfa414ccfa1eb2.js +1 -0
  218. mage_ai/server/frontend_dist/_next/static/chunks/4168-97fd1578d1a38315.js +1 -0
  219. mage_ai/server/frontend_dist/_next/static/chunks/4982-fa5a238b139fbdd2.js +1 -0
  220. mage_ai/server/frontend_dist/_next/static/chunks/5699-176f445e1313f001.js +1 -0
  221. mage_ai/server/frontend_dist/_next/static/chunks/7162-7dd03f0f605de721.js +1 -0
  222. mage_ai/server/frontend_dist/_next/static/chunks/7779-68d2b72a90c5f925.js +1 -0
  223. mage_ai/server/frontend_dist/_next/static/chunks/7966-5446a8e43711e2f9.js +1 -0
  224. mage_ai/server/frontend_dist/_next/static/chunks/8023-6c2f172f48dcb99b.js +1 -0
  225. mage_ai/server/frontend_dist/_next/static/chunks/8095-c351b8a735d73e0c.js +1 -0
  226. mage_ai/server/frontend_dist/_next/static/chunks/{main-77fe248a6fbd12d8.js → main-b99d4e30a88d9dc7.js} +1 -1
  227. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-9fe2d9d07c94e968.js +1 -0
  228. mage_ai/server/frontend_dist/_next/static/chunks/pages/{block-layout-14f952f66964022f.js → block-layout-7f4b735c67115df5.js} +1 -1
  229. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-e7d48e6b0c3068ac.js +1 -0
  230. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products-b943f31f050fc3a4.js +1 -0
  231. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/overview-597b74828bf105db.js → frontend_dist/_next/static/chunks/pages/overview-9f1ac4ec003884f3.js} +1 -1
  232. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/{[...slug]-7181b086c93784d2.js → [...slug]-7e737f6fc7e83e9b.js} +1 -1
  233. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-d94488e3f2eeef36.js +1 -0
  234. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-cc641a7fa8473796.js +1 -0
  235. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-a5c0362763a21fa8.js → block-runs-284309877f3c5a5a.js} +1 -1
  236. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-26250e5335194ade.js +1 -0
  237. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-7acc7afc00df17c2.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-5f4c8128b2413fd8.js} +1 -1
  238. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-4ebfc8e400315dda.js +1 -0
  239. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-e5e0150a256aadb3.js +1 -0
  240. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/{profile-3f0df3decc856ee9.js → profile-3ae43c932537b254.js} +1 -1
  241. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-32985f3f7c7dd3ab.js → frontend_dist/_next/static/chunks/pages/settings/platform/preferences-b603d7fe4b175256.js} +1 -1
  242. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-c2e9ef989c8bfa73.js → frontend_dist/_next/static/chunks/pages/settings/platform/settings-319ddbabc239e91b.js} +1 -1
  243. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-47b64ced27c24985.js → [...slug]-5c360f72e4498855.js} +1 -1
  244. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{permissions-e5a4d3d815cec25d.js → permissions-fb29fa6c2bd90bb0.js} +1 -1
  245. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-3b76fa959ffa09d3.js +1 -0
  246. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-379e1ee292504842.js → [...slug]-3b787b42f1093b1f.js} +1 -1
  247. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-0b83fbdd39e85f5b.js +1 -0
  248. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-a1e6950974d643a8.js +1 -0
  249. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-2af9afbe727d88aa.js → [...slug]-0aa019d87db8b0b8.js} +1 -1
  250. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{users-a4db8710f703c729.js → users-88c694d19207f2ec.js} +1 -1
  251. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-31d0d50f7f30462b.js +1 -0
  252. mage_ai/server/frontend_dist/_next/static/chunks/{webpack-d079359c241db804.js → webpack-ac7fdc472bedf682.js} +1 -1
  253. mage_ai/server/frontend_dist/block-layout.html +3 -3
  254. mage_ai/server/frontend_dist/compute.html +6 -6
  255. mage_ai/server/frontend_dist/files.html +6 -6
  256. mage_ai/server/frontend_dist/global-data-products/[...slug].html +6 -6
  257. mage_ai/server/frontend_dist/global-data-products.html +6 -6
  258. mage_ai/server/frontend_dist/global-hooks/[...slug].html +6 -6
  259. mage_ai/server/frontend_dist/global-hooks.html +6 -6
  260. mage_ai/server/frontend_dist/index.html +3 -3
  261. mage_ai/server/frontend_dist/manage/files.html +6 -6
  262. mage_ai/server/frontend_dist/manage/settings.html +6 -6
  263. mage_ai/server/frontend_dist/manage/users/[user].html +6 -6
  264. mage_ai/server/frontend_dist/manage/users/new.html +6 -6
  265. mage_ai/server/frontend_dist/manage/users.html +6 -6
  266. mage_ai/server/frontend_dist/manage.html +6 -6
  267. mage_ai/server/frontend_dist/oauth.html +5 -5
  268. mage_ai/server/frontend_dist/overview.html +6 -6
  269. mage_ai/server/frontend_dist/pipeline-runs.html +6 -6
  270. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +6 -6
  271. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +6 -6
  272. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +6 -6
  273. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +3 -3
  274. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +6 -6
  275. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +6 -6
  276. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
  277. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +6 -6
  278. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +6 -6
  279. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +6 -6
  280. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +6 -6
  281. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +6 -6
  282. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +6 -6
  283. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +6 -6
  284. mage_ai/server/frontend_dist/pipelines/[pipeline].html +3 -3
  285. mage_ai/server/frontend_dist/pipelines.html +6 -6
  286. mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +6 -6
  287. mage_ai/server/frontend_dist/platform/global-hooks.html +6 -6
  288. mage_ai/server/frontend_dist/settings/account/profile.html +6 -6
  289. mage_ai/server/frontend_dist/settings/platform/preferences.html +6 -6
  290. mage_ai/server/frontend_dist/settings/platform/settings.html +6 -6
  291. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +6 -6
  292. mage_ai/server/frontend_dist/settings/workspace/permissions.html +6 -6
  293. mage_ai/server/frontend_dist/settings/workspace/preferences.html +6 -6
  294. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +6 -6
  295. mage_ai/server/frontend_dist/settings/workspace/roles.html +6 -6
  296. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +6 -6
  297. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +6 -6
  298. mage_ai/server/frontend_dist/settings/workspace/users.html +6 -6
  299. mage_ai/server/frontend_dist/settings.html +3 -3
  300. mage_ai/server/frontend_dist/sign-in.html +12 -12
  301. mage_ai/server/frontend_dist/templates/[...slug].html +6 -6
  302. mage_ai/server/frontend_dist/templates.html +6 -6
  303. mage_ai/server/frontend_dist/terminal.html +6 -6
  304. mage_ai/server/frontend_dist/test.html +3 -3
  305. mage_ai/server/frontend_dist/triggers.html +6 -6
  306. mage_ai/server/frontend_dist/version-control.html +6 -6
  307. mage_ai/server/frontend_dist_base_path_template/404.html +5 -5
  308. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1376-22de38b4ad008d8a.js +1 -0
  309. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{1557-b3502f3f1aa92ac7.js → 1557-25a7d985d5564fd3.js} +1 -1
  310. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1668-30b4619b9534519b.js +1 -0
  311. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1799-c42db95a015689ee.js +1 -0
  312. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2996-2108b53b9d371d8d.js +1 -0
  313. mage_ai/server/{frontend_dist/_next/static/chunks/3763-61b542dafdbf5754.js → frontend_dist_base_path_template/_next/static/chunks/3763-40780c6d1e4b261d.js} +1 -1
  314. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-129dd2a2448a2e36.js +1 -0
  315. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3958-bcdfa414ccfa1eb2.js +1 -0
  316. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4168-97fd1578d1a38315.js +1 -0
  317. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4982-fa5a238b139fbdd2.js +1 -0
  318. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-176f445e1313f001.js +1 -0
  319. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7162-7dd03f0f605de721.js +1 -0
  320. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7779-68d2b72a90c5f925.js +1 -0
  321. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-5446a8e43711e2f9.js +1 -0
  322. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8023-6c2f172f48dcb99b.js +1 -0
  323. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-c351b8a735d73e0c.js +1 -0
  324. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{main-70b78159c2bb3fe1.js → main-384298e9133cec76.js} +1 -1
  325. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-13a578bce3b7f30c.js +1 -0
  326. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{block-layout-14f952f66964022f.js → block-layout-7f4b735c67115df5.js} +1 -1
  327. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-e7d48e6b0c3068ac.js +1 -0
  328. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products-b943f31f050fc3a4.js +1 -0
  329. mage_ai/server/{frontend_dist/_next/static/chunks/pages/overview-597b74828bf105db.js → frontend_dist_base_path_template/_next/static/chunks/pages/overview-9f1ac4ec003884f3.js} +1 -1
  330. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/{[...slug]-7181b086c93784d2.js → [...slug]-7e737f6fc7e83e9b.js} +1 -1
  331. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-d94488e3f2eeef36.js +1 -0
  332. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-cc641a7fa8473796.js +1 -0
  333. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-a5c0362763a21fa8.js → block-runs-284309877f3c5a5a.js} +1 -1
  334. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-26250e5335194ade.js +1 -0
  335. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-7acc7afc00df17c2.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-5f4c8128b2413fd8.js} +1 -1
  336. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-4ebfc8e400315dda.js +1 -0
  337. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-e5e0150a256aadb3.js +1 -0
  338. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/{profile-3f0df3decc856ee9.js → profile-3ae43c932537b254.js} +1 -1
  339. mage_ai/server/{frontend_dist/_next/static/chunks/pages/settings/platform/preferences-32985f3f7c7dd3ab.js → frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-b603d7fe4b175256.js} +1 -1
  340. mage_ai/server/{frontend_dist/_next/static/chunks/pages/settings/platform/settings-c2e9ef989c8bfa73.js → frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-319ddbabc239e91b.js} +1 -1
  341. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-47b64ced27c24985.js → [...slug]-5c360f72e4498855.js} +1 -1
  342. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{permissions-e5a4d3d815cec25d.js → permissions-fb29fa6c2bd90bb0.js} +1 -1
  343. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-3b76fa959ffa09d3.js +1 -0
  344. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-379e1ee292504842.js → [...slug]-3b787b42f1093b1f.js} +1 -1
  345. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-0b83fbdd39e85f5b.js +1 -0
  346. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-a1e6950974d643a8.js +1 -0
  347. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-2af9afbe727d88aa.js → [...slug]-0aa019d87db8b0b8.js} +1 -1
  348. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{users-a4db8710f703c729.js → users-88c694d19207f2ec.js} +1 -1
  349. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-31d0d50f7f30462b.js +1 -0
  350. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-68c003fb6a175cd7.js → webpack-481689d9989710cd.js} +1 -1
  351. mage_ai/server/frontend_dist_base_path_template/_next/static/kcptwoOU-JJJg6Vwpkfmx/_buildManifest.js +1 -0
  352. mage_ai/server/frontend_dist_base_path_template/block-layout.html +3 -3
  353. mage_ai/server/frontend_dist_base_path_template/compute.html +6 -6
  354. mage_ai/server/frontend_dist_base_path_template/files.html +6 -6
  355. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +6 -6
  356. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +6 -6
  357. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +6 -6
  358. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +6 -6
  359. mage_ai/server/frontend_dist_base_path_template/index.html +3 -3
  360. mage_ai/server/frontend_dist_base_path_template/manage/files.html +6 -6
  361. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +6 -6
  362. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +6 -6
  363. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +6 -6
  364. mage_ai/server/frontend_dist_base_path_template/manage/users.html +6 -6
  365. mage_ai/server/frontend_dist_base_path_template/manage.html +6 -6
  366. mage_ai/server/frontend_dist_base_path_template/oauth.html +5 -5
  367. mage_ai/server/frontend_dist_base_path_template/overview.html +6 -6
  368. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +6 -6
  369. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +6 -6
  370. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +6 -6
  371. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +6 -6
  372. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +3 -3
  373. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +6 -6
  374. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +6 -6
  375. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
  376. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +6 -6
  377. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +6 -6
  378. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +6 -6
  379. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +6 -6
  380. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +6 -6
  381. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +6 -6
  382. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +6 -6
  383. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +3 -3
  384. mage_ai/server/frontend_dist_base_path_template/pipelines.html +6 -6
  385. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +6 -6
  386. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +6 -6
  387. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +6 -6
  388. mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +6 -6
  389. mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +6 -6
  390. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +6 -6
  391. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +6 -6
  392. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +6 -6
  393. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +6 -6
  394. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +6 -6
  395. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +6 -6
  396. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +6 -6
  397. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +6 -6
  398. mage_ai/server/frontend_dist_base_path_template/settings.html +3 -3
  399. mage_ai/server/frontend_dist_base_path_template/sign-in.html +12 -12
  400. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +6 -6
  401. mage_ai/server/frontend_dist_base_path_template/templates.html +6 -6
  402. mage_ai/server/frontend_dist_base_path_template/terminal.html +6 -6
  403. mage_ai/server/frontend_dist_base_path_template/test.html +3 -3
  404. mage_ai/server/frontend_dist_base_path_template/triggers.html +6 -6
  405. mage_ai/server/frontend_dist_base_path_template/version-control.html +6 -6
  406. mage_ai/server/kernel_output_parser.py +4 -1
  407. mage_ai/server/scheduler_manager.py +9 -0
  408. mage_ai/server/server.py +35 -31
  409. mage_ai/server/utils/custom_output.py +284 -0
  410. mage_ai/server/utils/execute_custom_code.py +245 -0
  411. mage_ai/server/utils/output_display.py +123 -289
  412. mage_ai/server/websocket_server.py +116 -69
  413. mage_ai/services/k8s/config.py +23 -0
  414. mage_ai/services/k8s/job_manager.py +6 -1
  415. mage_ai/services/ssh/aws/emr/utils.py +8 -8
  416. mage_ai/settings/keys/auth.py +1 -0
  417. mage_ai/settings/platform/__init__.py +159 -38
  418. mage_ai/settings/platform/constants.py +5 -0
  419. mage_ai/settings/platform/utils.py +53 -10
  420. mage_ai/settings/repo.py +26 -12
  421. mage_ai/settings/server.py +128 -37
  422. mage_ai/shared/array.py +24 -1
  423. mage_ai/shared/complex.py +45 -0
  424. mage_ai/shared/config.py +2 -1
  425. mage_ai/shared/custom_logger.py +11 -0
  426. mage_ai/shared/dates.py +10 -6
  427. mage_ai/shared/files.py +63 -8
  428. mage_ai/shared/hash.py +33 -9
  429. mage_ai/shared/io.py +9 -5
  430. mage_ai/shared/models.py +82 -24
  431. mage_ai/shared/outputs.py +87 -0
  432. mage_ai/shared/parsers.py +141 -15
  433. mage_ai/shared/path_fixer.py +11 -7
  434. mage_ai/shared/singletons/__init__.py +0 -0
  435. mage_ai/shared/singletons/base.py +47 -0
  436. mage_ai/shared/singletons/memory.py +38 -0
  437. mage_ai/shared/strings.py +34 -1
  438. mage_ai/shared/yaml.py +24 -0
  439. mage_ai/streaming/sinks/oracledb.py +57 -0
  440. mage_ai/streaming/sinks/sink_factory.py +4 -0
  441. mage_ai/system/__init__.py +0 -0
  442. mage_ai/system/constants.py +14 -0
  443. mage_ai/system/memory/__init__.py +0 -0
  444. mage_ai/system/memory/constants.py +1 -0
  445. mage_ai/system/memory/manager.py +174 -0
  446. mage_ai/system/memory/presenters.py +158 -0
  447. mage_ai/system/memory/process.py +216 -0
  448. mage_ai/system/memory/samples.py +13 -0
  449. mage_ai/system/memory/utils.py +656 -0
  450. mage_ai/system/memory/wrappers.py +177 -0
  451. mage_ai/system/models.py +58 -0
  452. mage_ai/system/storage/__init__.py +0 -0
  453. mage_ai/system/storage/utils.py +29 -0
  454. mage_ai/tests/api/endpoints/mixins.py +2 -2
  455. mage_ai/tests/api/endpoints/test_blocks.py +2 -1
  456. mage_ai/tests/api/endpoints/test_custom_designs.py +4 -4
  457. mage_ai/tests/api/endpoints/test_pipeline_runs.py +2 -2
  458. mage_ai/tests/api/endpoints/test_projects.py +2 -1
  459. mage_ai/tests/api/operations/base/test_base.py +27 -27
  460. mage_ai/tests/api/operations/base/test_base_with_user_authentication.py +27 -27
  461. mage_ai/tests/api/operations/base/test_base_with_user_permissions.py +23 -23
  462. mage_ai/tests/api/operations/test_syncs.py +6 -4
  463. mage_ai/tests/api/resources/test_pipeline_resource.py +9 -2
  464. mage_ai/tests/authentication/providers/test_oidc.py +59 -0
  465. mage_ai/tests/base_test.py +2 -2
  466. mage_ai/tests/data/__init__.py +0 -0
  467. mage_ai/tests/data/models/__init__.py +0 -0
  468. mage_ai/tests/data_preparation/executors/test_block_executor.py +23 -16
  469. mage_ai/tests/data_preparation/git/test_git.py +4 -1
  470. mage_ai/tests/data_preparation/models/block/dynamic/test_combos.py +305 -0
  471. mage_ai/tests/data_preparation/models/block/dynamic/test_counter.py +212 -0
  472. mage_ai/tests/data_preparation/models/block/dynamic/test_factory.py +360 -0
  473. mage_ai/tests/data_preparation/models/block/dynamic/test_variables.py +332 -0
  474. mage_ai/tests/data_preparation/models/block/hook/test_hook_block.py +2 -2
  475. mage_ai/tests/data_preparation/models/block/platform/test_mixins.py +1 -1
  476. mage_ai/tests/data_preparation/models/block/sql/utils/test_shared.py +26 -1
  477. mage_ai/tests/data_preparation/models/block/test_global_data_product.py +3 -2
  478. mage_ai/tests/data_preparation/models/custom_templates/test_utils.py +5 -4
  479. mage_ai/tests/data_preparation/models/global_hooks/test_hook.py +3 -0
  480. mage_ai/tests/data_preparation/models/global_hooks/test_predicates.py +9 -3
  481. mage_ai/tests/data_preparation/models/test_block.py +115 -120
  482. mage_ai/tests/data_preparation/models/test_blocks_helper.py +114 -0
  483. mage_ai/tests/data_preparation/models/test_global_data_product.py +41 -24
  484. mage_ai/tests/data_preparation/models/test_pipeline.py +9 -6
  485. mage_ai/tests/data_preparation/models/test_project.py +4 -1
  486. mage_ai/tests/data_preparation/models/test_utils.py +80 -0
  487. mage_ai/tests/data_preparation/models/test_variable.py +242 -69
  488. mage_ai/tests/data_preparation/models/variables/__init__.py +0 -0
  489. mage_ai/tests/data_preparation/models/variables/test_summarizer.py +481 -0
  490. mage_ai/tests/data_preparation/storage/shared/__init__.py +0 -0
  491. mage_ai/tests/data_preparation/test_repo_manager.py +6 -7
  492. mage_ai/tests/data_preparation/test_variable_manager.py +57 -48
  493. mage_ai/tests/factory.py +64 -43
  494. mage_ai/tests/orchestration/db/models/test_schedules.py +3 -3
  495. mage_ai/tests/orchestration/db/models/test_schedules_dynamic_blocks.py +279 -0
  496. mage_ai/tests/orchestration/test_pipeline_scheduler.py +1 -0
  497. mage_ai/tests/orchestration/triggers/test_global_data_product.py +3 -2
  498. mage_ai/tests/orchestration/triggers/test_utils.py +3 -2
  499. mage_ai/tests/services/k8s/test_job_manager.py +18 -0
  500. mage_ai/tests/streaming/sinks/test_oracledb.py +38 -0
  501. mage_ai/tests/test_shared.py +61 -0
  502. mage_ai/usage_statistics/logger.py +7 -2
  503. mage_ai/utils/code.py +33 -19
  504. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/METADATA +5 -2
  505. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/RECORD +513 -417
  506. mage_ai/data_preparation/models/global_data_product/constants.py +0 -6
  507. mage_ai/server/frontend_dist/_next/static/RhDiJSkcjCsh4xxX4BFBk/_buildManifest.js +0 -1
  508. mage_ai/server/frontend_dist/_next/static/chunks/2631-b9f9bea3f1cf906d.js +0 -1
  509. mage_ai/server/frontend_dist/_next/static/chunks/3782-ef4cd4f0b52072d0.js +0 -1
  510. mage_ai/server/frontend_dist/_next/static/chunks/4783-422429203610c318.js +0 -1
  511. mage_ai/server/frontend_dist/_next/static/chunks/5699-6d708c6b2153ea08.js +0 -1
  512. mage_ai/server/frontend_dist/_next/static/chunks/635-0d6b7c8804bcd2dc.js +0 -1
  513. mage_ai/server/frontend_dist/_next/static/chunks/7022-0d52dd8868621fb0.js +0 -1
  514. mage_ai/server/frontend_dist/_next/static/chunks/7361-8a23dd8360593e7a.js +0 -1
  515. mage_ai/server/frontend_dist/_next/static/chunks/7966-b9b85ba10667e654.js +0 -1
  516. mage_ai/server/frontend_dist/_next/static/chunks/8095-bdce03896ef9639a.js +0 -1
  517. mage_ai/server/frontend_dist/_next/static/chunks/8146-6bed4e7401e067e6.js +0 -1
  518. mage_ai/server/frontend_dist/_next/static/chunks/9265-d2a1aaec75ec69b8.js +0 -1
  519. mage_ai/server/frontend_dist/_next/static/chunks/9440-4069842b90d4b801.js +0 -1
  520. mage_ai/server/frontend_dist/_next/static/chunks/9832-67896490f6e8a014.js +0 -1
  521. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-2a69553d8c6eeb53.js +0 -1
  522. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-591abd392dc50ed4.js +0 -1
  523. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products-78e8e88f2a757a18.js +0 -1
  524. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-95ffcd3e2b27e567.js +0 -1
  525. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-b645a6d13ab9fe3a.js +0 -1
  526. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-1ed9045b2f1dfd65.js +0 -1
  527. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.js +0 -1
  528. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +0 -1
  529. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-349af617d05f001b.js +0 -1
  530. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-36fa165a48af586b.js +0 -1
  531. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-60d01d3887e31136.js +0 -1
  532. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-3433c8b22e8342aa.js +0 -1
  533. mage_ai/server/frontend_dist_base_path_template/_next/static/TdpLLFome13qvM0gXvpHs/_buildManifest.js +0 -1
  534. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2631-b9f9bea3f1cf906d.js +0 -1
  535. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-ef4cd4f0b52072d0.js +0 -1
  536. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4783-422429203610c318.js +0 -1
  537. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-6d708c6b2153ea08.js +0 -1
  538. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/635-0d6b7c8804bcd2dc.js +0 -1
  539. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-0d52dd8868621fb0.js +0 -1
  540. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-8a23dd8360593e7a.js +0 -1
  541. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-b9b85ba10667e654.js +0 -1
  542. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-bdce03896ef9639a.js +0 -1
  543. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-6bed4e7401e067e6.js +0 -1
  544. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9265-d2a1aaec75ec69b8.js +0 -1
  545. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-4069842b90d4b801.js +0 -1
  546. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9832-67896490f6e8a014.js +0 -1
  547. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-2a69553d8c6eeb53.js +0 -1
  548. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-591abd392dc50ed4.js +0 -1
  549. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products-78e8e88f2a757a18.js +0 -1
  550. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-95ffcd3e2b27e567.js +0 -1
  551. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-b645a6d13ab9fe3a.js +0 -1
  552. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-1ed9045b2f1dfd65.js +0 -1
  553. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.js +0 -1
  554. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +0 -1
  555. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-349af617d05f001b.js +0 -1
  556. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-36fa165a48af586b.js +0 -1
  557. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-60d01d3887e31136.js +0 -1
  558. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-3433c8b22e8342aa.js +0 -1
  559. mage_ai/shared/memory.py +0 -90
  560. mage_ai/tests/data_preparation/models/block/dynamic/test_dynamic_helpers.py +0 -48
  561. /mage_ai/{tests/data_preparation/shared → ai/utils}/__init__.py +0 -0
  562. /mage_ai/server/frontend_dist/_next/static/{RhDiJSkcjCsh4xxX4BFBk → UZLabyPgcxtZvp0O0EUUS}/_ssgManifest.js +0 -0
  563. /mage_ai/server/frontend_dist_base_path_template/_next/static/{TdpLLFome13qvM0gXvpHs → kcptwoOU-JJJg6Vwpkfmx}/_ssgManifest.js +0 -0
  564. /mage_ai/tests/data_preparation/{shared → storage/shared}/test_secrets.py +0 -0
  565. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/LICENSE +0 -0
  566. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/WHEEL +0 -0
  567. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/entry_points.txt +0 -0
  568. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/top_level.txt +0 -0
@@ -148,7 +148,8 @@ class FileResource(GenericResource):
148
148
  pipeline_file, pipeline_config = Pipeline.import_from_zip(content, overwrite)
149
149
  tags = pipeline_config.get('tags', [])
150
150
  pipeline_uuid = pipeline_config.get('uuid')
151
- pipeline = Pipeline(pipeline_uuid, config=pipeline_config)
151
+ repo_path = get_repo_path(user=user)
152
+ pipeline = Pipeline(pipeline_uuid, config=pipeline_config, repo_path=repo_path)
152
153
  if tags:
153
154
  from mage_ai.cache.tag import TagCache
154
155
 
@@ -161,7 +162,7 @@ class FileResource(GenericResource):
161
162
 
162
163
  block_cache = await BlockCache.initialize_cache()
163
164
  for block in pipeline.blocks_by_uuid.values():
164
- block_cache.add_pipeline(block, pipeline)
165
+ block_cache.add_pipeline(block, pipeline, repo_path)
165
166
 
166
167
  return self(pipeline_file, user, **kwargs)
167
168
  else:
@@ -175,7 +176,9 @@ class FileResource(GenericResource):
175
176
  overwrite=overwrite,
176
177
  )
177
178
 
178
- block_type = Block.block_type_from_path(dir_path)
179
+ block_type = Block.block_type_from_path(
180
+ dir_path, repo_path=get_repo_path(user=user)
181
+ )
179
182
  if block_type:
180
183
  cache_block_action_object = await BlockActionObjectCache.initialize_cache()
181
184
  cache_block_action_object.update_block(block_file_absolute_path=file.file_path)
@@ -235,7 +238,10 @@ class FileResource(GenericResource):
235
238
 
236
239
  @safe_db_query
237
240
  async def update(self, payload, **kwargs):
238
- block_type = Block.block_type_from_path(self.model.dir_path)
241
+ block_type = Block.block_type_from_path(
242
+ self.model.dir_path,
243
+ repo_path=get_repo_path(user=self.current_user),
244
+ )
239
245
  cache_block_action_object = None
240
246
  if block_type:
241
247
  cache_block_action_object = await BlockActionObjectCache.initialize_cache()
@@ -4,6 +4,7 @@ from mage_ai.data_preparation.models.block import Block
4
4
  from mage_ai.data_preparation.models.file import File
5
5
  from mage_ai.data_preparation.models.pipeline import Pipeline
6
6
  from mage_ai.orchestration.db import safe_db_query
7
+ from mage_ai.settings.repo import get_repo_path
7
8
 
8
9
 
9
10
  class FileVersionResource(GenericResource):
@@ -21,7 +22,8 @@ class FileVersionResource(GenericResource):
21
22
  block_uuid = block_uuid[0]
22
23
 
23
24
  if pipeline_uuid and block_uuid:
24
- pipeline = Pipeline.get(pipeline_uuid)
25
+ repo_path = get_repo_path(user=user)
26
+ pipeline = Pipeline.get(pipeline_uuid, repo_path=repo_path)
25
27
  if pipeline:
26
28
  block = pipeline.get_block(block_uuid)
27
29
  if block:
@@ -12,6 +12,7 @@ from mage_ai.data_preparation.git.utils import (
12
12
  )
13
13
  from mage_ai.data_preparation.preferences import get_preferences
14
14
  from mage_ai.server.logger import Logger
15
+ from mage_ai.settings.repo import get_repo_path
15
16
  from mage_ai.shared.path_fixer import remove_base_repo_path
16
17
  from mage_ai.shared.strings import capitalize_remove_underscore_lower
17
18
 
@@ -35,9 +36,21 @@ def build_file_object(obj):
35
36
  class GitBranchResource(GenericResource):
36
37
  @classmethod
37
38
  def get_git_manager(
38
- self, user, setup_repo: bool = False, config_overwrite: Dict = None
39
+ self,
40
+ user=None,
41
+ context_data: Dict = None,
42
+ preferences=None,
43
+ repo_path: str = None,
44
+ setup_repo: bool = False,
45
+ config_overwrite: Dict = None,
39
46
  ) -> Git:
40
- return Git.get_manager(setup_repo=setup_repo, user=user)
47
+ return Git.get_manager(
48
+ context_data=context_data,
49
+ preferences=preferences,
50
+ repo_path=repo_path,
51
+ setup_repo=setup_repo,
52
+ user=user,
53
+ )
41
54
 
42
55
  @classmethod
43
56
  def collection(self, query, meta, user, **kwargs):
@@ -97,11 +110,22 @@ class GitBranchResource(GenericResource):
97
110
 
98
111
  @classmethod
99
112
  async def member(self, pk, user, **kwargs):
100
- preferences = get_preferences(user=user)
113
+ context_data = kwargs.get('context_data')
114
+ repo_path = get_repo_path(context_data=context_data, user=user)
115
+ preferences = get_preferences(
116
+ repo_path=repo_path,
117
+ user=user,
118
+ )
101
119
  setup_repo = False
102
120
  if preferences.is_git_integration_enabled():
103
121
  setup_repo = True
104
- git_manager = self.get_git_manager(user=user, setup_repo=setup_repo)
122
+ git_manager = self.get_git_manager(
123
+ user=user,
124
+ context_data=context_data,
125
+ preferences=preferences,
126
+ repo_path=repo_path,
127
+ setup_repo=setup_repo,
128
+ )
105
129
 
106
130
  display_format = kwargs.get('meta', {}).get('_format')
107
131
  if 'with_basic_details' == display_format:
@@ -112,7 +136,7 @@ class GitBranchResource(GenericResource):
112
136
  modified_files=[],
113
137
  name=git_manager.current_branch,
114
138
  staged_files=[],
115
- sync_config=get_preferences().sync_config,
139
+ sync_config=preferences.sync_config,
116
140
  untracked_files=[],
117
141
  ),
118
142
  user,
@@ -130,7 +154,7 @@ class GitBranchResource(GenericResource):
130
154
  modified_files=modified_files,
131
155
  name=git_manager.current_branch,
132
156
  staged_files=staged_files,
133
- sync_config=get_preferences().sync_config,
157
+ sync_config=preferences.sync_config,
134
158
  untracked_files=untracked_files,
135
159
  ),
136
160
  user,
@@ -167,9 +191,9 @@ class GitBranchResource(GenericResource):
167
191
  token = access_token.token
168
192
  user_from_api = api.get_user(token, provider=provider)
169
193
  # Default to mage user email if no email is returned from API
170
- email = user_from_api.get(
171
- 'email', user.email if user else None
172
- )
194
+ email = user_from_api.get('email')
195
+ if email is None and user:
196
+ email = user.email
173
197
  config_overwrite = dict(
174
198
  username=user_from_api.get('username'),
175
199
  email=email,
@@ -187,6 +211,13 @@ class GitBranchResource(GenericResource):
187
211
  action_payload = payload.get('action_payload', dict())
188
212
  action_remote = action_payload.get('remote', None)
189
213
  action_branch = action_payload.get('branch', None)
214
+ action_arg = action_payload.get('arg', None)
215
+
216
+ # Eventually we would want to give the user the ability to pass in multiple
217
+ # arguments to the action, but for now we will just pass in a single argument.
218
+ action_kwargs = dict()
219
+ if action_arg:
220
+ action_kwargs[action_arg] = True
190
221
 
191
222
  files = payload.get('files', None)
192
223
  message = payload.get('message', None)
@@ -239,6 +270,7 @@ class GitBranchResource(GenericResource):
239
270
  action_branch,
240
271
  token,
241
272
  config_overwrite=config_overwrite,
273
+ **action_kwargs,
242
274
  )
243
275
  if custom_progress.other_lines:
244
276
  lines = custom_progress.other_lines
@@ -269,6 +301,7 @@ class GitBranchResource(GenericResource):
269
301
  action_branch,
270
302
  token,
271
303
  config_overwrite=config_overwrite,
304
+ **action_kwargs,
272
305
  )
273
306
  else:
274
307
  custom_progress = api.fetch(
@@ -276,6 +309,7 @@ class GitBranchResource(GenericResource):
276
309
  url,
277
310
  token,
278
311
  config_overwrite=config_overwrite,
312
+ **action_kwargs,
279
313
  )
280
314
 
281
315
  if custom_progress and custom_progress.other_lines:
@@ -304,6 +338,7 @@ class GitBranchResource(GenericResource):
304
338
  url,
305
339
  token,
306
340
  config_overwrite=config_overwrite,
341
+ **action_kwargs,
307
342
  )
308
343
 
309
344
  if custom_progress and custom_progress.other_lines:
@@ -337,6 +372,7 @@ class GitBranchResource(GenericResource):
337
372
  action_branch,
338
373
  token,
339
374
  config_overwrite=config_overwrite,
375
+ **action_kwargs,
340
376
  )
341
377
  else:
342
378
  self.model[
@@ -357,6 +393,7 @@ class GitBranchResource(GenericResource):
357
393
  url,
358
394
  token,
359
395
  config_overwrite=config_overwrite,
396
+ **action_kwargs,
360
397
  )
361
398
  else:
362
399
  self.model[
@@ -1,43 +1,80 @@
1
1
  from mage_ai.api.errors import ApiError
2
2
  from mage_ai.api.resources.GenericResource import GenericResource
3
3
  from mage_ai.data_preparation.models.global_data_product import GlobalDataProduct
4
+ from mage_ai.settings.repo import get_repo_path
4
5
  from mage_ai.shared.hash import ignore_keys
5
6
 
6
7
 
7
8
  class GlobalDataProductResource(GenericResource):
8
9
  @classmethod
9
10
  def collection(self, query, meta, user, **kwargs):
11
+ repo_path = query.get('repo_path', [None])
12
+ if repo_path:
13
+ repo_path = repo_path[0]
14
+
15
+ current_project = query.get('current_project', [False])
16
+ if current_project:
17
+ current_project = current_project[0]
18
+
19
+ if current_project:
20
+ repo_path = get_repo_path(user=user)
21
+
10
22
  return self.build_result_set(
11
- sorted(GlobalDataProduct.load_all(), key=lambda x: x.uuid),
23
+ sorted(GlobalDataProduct.load_all(repo_path), key=lambda x: x.uuid),
12
24
  user,
13
25
  **kwargs,
14
26
  )
15
27
 
16
28
  @classmethod
17
29
  def create(self, payload, user, **kwargs):
30
+ repo_path = get_repo_path(user=user)
18
31
  uuid = payload.get('uuid')
19
- if GlobalDataProduct.get(uuid):
32
+ if GlobalDataProduct.get(uuid, repo_path):
20
33
  error = ApiError.RESOURCE_INVALID.copy()
21
- error.update(dict(message=f'A global data product with UUID {uuid} already exists.'))
34
+ error.update(
35
+ dict(message=f'A global data product with UUID {uuid} already exists.')
36
+ )
22
37
  raise ApiError(error)
23
38
 
24
- model = GlobalDataProduct(uuid, **ignore_keys(payload, ['uuid']))
39
+ model = GlobalDataProduct(
40
+ uuid,
41
+ repo_path=repo_path,
42
+ **ignore_keys(payload, ['uuid']),
43
+ )
25
44
  model.save()
26
45
 
27
46
  return self(model, user, **kwargs)
28
47
 
29
48
  @classmethod
30
49
  def member(self, pk, user, **kwargs):
31
- return self(GlobalDataProduct.get(pk), user, **kwargs)
50
+ query = kwargs.get('query', {})
51
+ project = query.get('project', [None])
52
+ if project:
53
+ project = project[0]
54
+ repo_path = get_repo_path(user=user)
55
+ return self(
56
+ GlobalDataProduct.get(
57
+ pk, repo_path=repo_path if not project else None, project=project
58
+ ),
59
+ user,
60
+ **kwargs,
61
+ )
32
62
 
33
63
  def delete(self, **kwargs):
34
64
  self.model.delete()
35
65
 
36
66
  def update(self, payload, **kwargs):
67
+ repo_path = get_repo_path(user=self.current_user)
37
68
  uuid = payload.get('uuid')
38
- if self.model and self.model.uuid != uuid and GlobalDataProduct.get(uuid):
69
+ if (
70
+ self.model
71
+ and self.model.uuid != uuid
72
+ and GlobalDataProduct.get(uuid, repo_path)
73
+ ):
39
74
  error = ApiError.RESOURCE_INVALID.copy()
40
- error.update(dict(message=f'A global data product with UUID {uuid} already exists.'))
75
+ error.update(
76
+ dict(message=f'A global data product with UUID {uuid} already exists.')
77
+ )
41
78
  raise ApiError(error)
42
79
 
43
80
  if self.model:
@@ -15,6 +15,7 @@ from mage_ai.data_preparation.models.global_hooks.models import (
15
15
  )
16
16
  from mage_ai.data_preparation.models.pipeline import Pipeline
17
17
  from mage_ai.orchestration.db.models.oauth import User
18
+ from mage_ai.settings.repo import get_repo_path
18
19
  from mage_ai.settings.utils import base_repo_path
19
20
  from mage_ai.shared.array import find
20
21
  from mage_ai.shared.hash import ignore_keys
@@ -190,6 +191,8 @@ class GlobalHookResource(AsyncBaseResource):
190
191
 
191
192
 
192
193
  async def __load_pipelines(resource: GlobalHookResource):
194
+ repo_path = get_repo_path(user=resource.current_user)
195
+
193
196
  pipeline_uuids = []
194
197
  for res in resource.result_set():
195
198
  if res.model.pipeline_settings and res.model.pipeline_settings.get('uuid'):
@@ -199,7 +202,7 @@ async def __load_pipelines(resource: GlobalHookResource):
199
202
 
200
203
  async def get_pipeline(uuid):
201
204
  try:
202
- return await Pipeline.get_async(uuid)
205
+ return await Pipeline.get_async(uuid, repo_path=repo_path)
203
206
  except Exception as err:
204
207
  err_message = f'Error loading pipeline {uuid}: {err}.'
205
208
  if err.__class__.__name__ == 'OSError' and 'Too many open files' in err.strerror:
@@ -1,9 +1,12 @@
1
1
  from mage_ai.api.resources.GenericResource import GenericResource
2
2
  from mage_ai.data_integrations.destinations.constants import DESTINATIONS
3
3
  from mage_ai.data_preparation.models.constants import BlockType
4
- from mage_ai.data_preparation.models.pipelines.integration_pipeline import IntegrationPipeline
4
+ from mage_ai.data_preparation.models.pipelines.integration_pipeline import (
5
+ IntegrationPipeline,
6
+ )
5
7
  from mage_ai.orchestration.db import safe_db_query
6
8
  from mage_ai.server.api.integration_sources import get_collection
9
+ from mage_ai.settings.repo import get_repo_path
7
10
 
8
11
 
9
12
  class IntegrationDestinationResource(GenericResource):
@@ -27,7 +30,8 @@ class IntegrationDestinationResource(GenericResource):
27
30
  action_type = payload['action_type']
28
31
  if 'test_connection' == action_type:
29
32
  pipeline_uuid = payload['pipeline_uuid']
30
- pipeline = IntegrationPipeline.get(pipeline_uuid)
33
+ repo_path = get_repo_path(user=user)
34
+ pipeline = IntegrationPipeline.get(pipeline_uuid, repo_path=repo_path)
31
35
  config = payload['config']
32
36
 
33
37
  try:
@@ -22,6 +22,7 @@ from mage_ai.data_preparation.models.pipelines.integration_pipeline import (
22
22
  from mage_ai.orchestration.db import safe_db_query
23
23
  from mage_ai.orchestration.db.models.schedules import PipelineRun
24
24
  from mage_ai.server.api.integration_sources import get_collection
25
+ from mage_ai.settings.repo import get_repo_path
25
26
 
26
27
 
27
28
  def get_state_data_for_blocks(
@@ -140,13 +141,14 @@ class IntegrationSourceResource(GenericResource):
140
141
  success = False
141
142
  streams = []
142
143
 
144
+ repo_path = get_repo_path(user=user)
143
145
  action_type = payload['action_type']
144
146
  if 'test_connection' == action_type:
145
147
  pipeline_uuid = payload['pipeline_uuid']
146
148
  block_uuid = payload.get('block_uuid')
147
149
 
148
150
  if block_uuid:
149
- pipeline = Pipeline.get(pipeline_uuid)
151
+ pipeline = Pipeline.get(pipeline_uuid, repo_path=repo_path)
150
152
  block = pipeline.get_block(block_uuid)
151
153
  try:
152
154
  test_connection(block)
@@ -155,7 +157,7 @@ class IntegrationSourceResource(GenericResource):
155
157
  traceback.print_exc()
156
158
  error_message = str(e)
157
159
  else:
158
- pipeline = IntegrationPipeline.get(pipeline_uuid)
160
+ pipeline = IntegrationPipeline.get(pipeline_uuid, repo_path=repo_path)
159
161
  config = payload['config']
160
162
 
161
163
  try:
@@ -166,7 +168,7 @@ class IntegrationSourceResource(GenericResource):
166
168
  error_message = str(e)
167
169
  elif 'sample_data' == action_type:
168
170
  pipeline_uuid = payload['pipeline_uuid']
169
- pipeline = IntegrationPipeline.get(pipeline_uuid)
171
+ pipeline = IntegrationPipeline.get(pipeline_uuid, repo_path=repo_path)
170
172
 
171
173
  streams_updated = pipeline.preview_data(
172
174
  BlockType.DATA_LOADER,
@@ -222,4 +224,6 @@ class IntegrationSourceResource(GenericResource):
222
224
 
223
225
  return self(state_data, user, **kwargs)
224
226
 
225
- return self(IntegrationPipeline.get(pk), user, **kwargs)
227
+ repo_path = get_repo_path(user=user)
228
+
229
+ return self(IntegrationPipeline.get(pk, repo_path=repo_path), user, **kwargs)
@@ -1,10 +1,14 @@
1
1
  from mage_ai.api.resources.GenericResource import GenericResource
2
- from mage_ai.data_preparation.models.pipelines.integration_pipeline import IntegrationPipeline
2
+ from mage_ai.data_preparation.models.pipelines.integration_pipeline import (
3
+ IntegrationPipeline,
4
+ )
3
5
  from mage_ai.orchestration.db import safe_db_query
6
+ from mage_ai.settings.repo import get_repo_path
4
7
 
5
8
 
6
9
  class IntegrationSourceStreamResource(GenericResource):
7
10
  @classmethod
8
11
  @safe_db_query
9
12
  def member(self, pk, user, **kwargs):
10
- return self(IntegrationPipeline.get(pk), user, **kwargs)
13
+ repo_path = get_repo_path(user=user)
14
+ return self(IntegrationPipeline.get(pk, repo_path=repo_path), user, **kwargs)
@@ -0,0 +1,44 @@
1
+ from mage_ai.api.errors import ApiError
2
+ from mage_ai.api.resources.GenericResource import GenericResource
3
+ from mage_ai.kernels.models import KernelProcess
4
+ from mage_ai.kernels.utils import get_process_info
5
+
6
+ TERMINATE_INACTIVE = '__terminate_inactive__'
7
+
8
+
9
+ class KernelProcessResource(GenericResource):
10
+ @classmethod
11
+ async def collection(cls, query, meta, user, **kwargs):
12
+ check_active_status = query.get('check_active_status', [False])
13
+ if check_active_status:
14
+ check_active_status = check_active_status[0]
15
+
16
+ return cls.build_result_set(
17
+ KernelProcess.load_all(check_active_status=check_active_status),
18
+ user,
19
+ **kwargs,
20
+ )
21
+
22
+ @classmethod
23
+ def member(self, pk, user, **kwargs):
24
+ if TERMINATE_INACTIVE == pk:
25
+ return self(KernelProcess.load(pid=TERMINATE_INACTIVE), user, **kwargs)
26
+
27
+ query = kwargs.get('query', {})
28
+ check_active_status = query.get('check_active_status', [False])
29
+ if check_active_status:
30
+ check_active_status = check_active_status[0]
31
+
32
+ info = get_process_info(pk, check_active_status=check_active_status)
33
+
34
+ if not info:
35
+ raise ApiError(ApiError.RESOURCE_NOT_FOUND)
36
+
37
+ kernel_process = KernelProcess.load(**info)
38
+ return self(kernel_process, user, **kwargs)
39
+
40
+ async def delete(self, **kwargs):
41
+ if self.model.pid == TERMINATE_INACTIVE:
42
+ KernelProcess.terminate_inactive()
43
+
44
+ self.model.terminate()
@@ -1,4 +1,10 @@
1
+ from datetime import datetime
2
+
1
3
  from mage_ai.api.resources.GenericResource import GenericResource
4
+ from mage_ai.data_preparation.models.project import Project
5
+ from mage_ai.data_preparation.models.project.constants import FeatureUUID
6
+ from mage_ai.kernels.models import KernelProcess, KernelWrapper
7
+ from mage_ai.kernels.utils import find_ipykernel_launchers_info_async
2
8
  from mage_ai.orchestration.db import safe_db_query
3
9
  from mage_ai.server.active_kernel import (
4
10
  interrupt_kernel,
@@ -8,18 +14,31 @@ from mage_ai.server.active_kernel import (
8
14
  )
9
15
  from mage_ai.server.kernels import DEFAULT_KERNEL_NAME, KernelName, kernel_managers
10
16
  from mage_ai.services.ssh.aws.emr.utils import tunnel
17
+ from mage_ai.shared.singletons.memory import get_memory_manager_controller
11
18
 
12
19
 
13
20
  class KernelResource(GenericResource):
14
21
  @classmethod
15
22
  @safe_db_query
16
- def collection(self, query, meta, user, **kwargs):
23
+ async def collection(self, query, meta, user, **kwargs):
17
24
  kernels = []
18
25
 
26
+ if Project().is_feature_enabled(FeatureUUID.AUTOMATIC_KERNEL_CLEANUP):
27
+ # Only do this every minute
28
+ if int(datetime.utcnow().timestamp()) % 60 == 0:
29
+ kill_count, memory_freed = KernelProcess.terminate_inactive(
30
+ await find_ipykernel_launchers_info_async(),
31
+ )
32
+ if kill_count >= 1:
33
+ print(
34
+ f'[KernelResource] Automatic kernel cleanup: {kill_count} '
35
+ f'kernels terminated, {(memory_freed / 1024**3):.3f} GBs if memory freed.'
36
+ )
37
+
19
38
  for kernel_name in KernelName:
20
39
  kernel = kernel_managers[kernel_name]
21
40
  if kernel.has_kernel:
22
- kernels.append(kernel)
41
+ kernels.append(KernelWrapper(kernel))
23
42
 
24
43
  return self.build_result_set(
25
44
  kernels,
@@ -47,7 +66,7 @@ class KernelResource(GenericResource):
47
66
  if not kernel:
48
67
  kernel = kernel_managers[DEFAULT_KERNEL_NAME]
49
68
 
50
- return self(kernel, user, **kwargs)
69
+ return self(KernelWrapper(kernel), user, **kwargs)
51
70
 
52
71
  @safe_db_query
53
72
  def update(self, payload, **kwargs):
@@ -56,13 +75,16 @@ class KernelResource(GenericResource):
56
75
  switch_active_kernel(self.model.kernel_name)
57
76
 
58
77
  if 'interrupt' == action_type:
78
+ get_memory_manager_controller().stop_all_events()
59
79
  interrupt_kernel()
60
80
  elif 'restart' == action_type:
61
81
  try:
82
+ get_memory_manager_controller().stop_all_events()
62
83
  restart_kernel()
63
84
  except RuntimeError as e:
64
85
  # RuntimeError: Cannot restart the kernel. No previous call to 'start_kernel'.
65
86
  if 'start_kernel' in str(e):
87
+ get_memory_manager_controller().stop_all_events()
66
88
  start_kernel()
67
89
 
68
90
  def _callback(*args, **kwargs):
@@ -9,20 +9,35 @@ from mage_ai.data_preparation.models.block.data_integration.utils import (
9
9
  read_data_from_cache,
10
10
  )
11
11
  from mage_ai.data_preparation.models.block.utils import serialize_output
12
+ from mage_ai.data_preparation.models.constants import DATAFRAME_SAMPLE_COUNT
12
13
  from mage_ai.data_preparation.models.pipeline import Pipeline
13
14
  from mage_ai.orchestration.db import safe_db_query
14
15
  from mage_ai.orchestration.db.models.schedules import BlockRun
16
+ from mage_ai.settings.repo import get_repo_path
15
17
 
16
18
 
17
19
  class OutputResource(GenericResource):
18
20
  @classmethod
19
21
  @safe_db_query
20
- def collection(self, query, meta, user, **kwargs):
22
+ def collection(self, query_arg, meta, user, **kwargs):
23
+ query = {}
24
+ for key in [
25
+ 'sample_count',
26
+ ]:
27
+ value = query_arg.get(key, [None])
28
+ if value:
29
+ value = value[0]
30
+ if value is not None:
31
+ query[key] = value
32
+
21
33
  parent_model = kwargs['parent_model']
22
34
 
23
35
  outputs = []
24
36
  if type(parent_model) is BlockRun:
25
- outputs = parent_model.get_outputs()
37
+ outputs = parent_model.get_outputs(
38
+ sample_count=query.get('sample_count', DATAFRAME_SAMPLE_COUNT),
39
+ exclude_blank_variable_uuids=True,
40
+ )
26
41
 
27
42
  return self.build_result_set(
28
43
  outputs,
@@ -45,7 +60,8 @@ class OutputResource(GenericResource):
45
60
  model = dict(outputs=[])
46
61
 
47
62
  if block_uuid and pipeline_uuid:
48
- pipeline = Pipeline.get(pipeline_uuid)
63
+ repo_path = get_repo_path(user=user)
64
+ pipeline = Pipeline.get(pipeline_uuid, repo_path=repo_path)
49
65
  block = pipeline.get_block(block_uuid)
50
66
 
51
67
  if block.is_data_integration():
@@ -98,10 +114,12 @@ class OutputResource(GenericResource):
98
114
  else:
99
115
  output_serialized = serialize_output(block, output)
100
116
 
101
- model['outputs'].append(dict(
102
- data=output_serialized,
103
- uuid=stream_id,
104
- ))
117
+ model['outputs'].append(
118
+ dict(
119
+ data=output_serialized,
120
+ uuid=stream_id,
121
+ )
122
+ )
105
123
 
106
124
  if refresh and persist:
107
125
  persist_data_for_stream(
@@ -134,6 +152,8 @@ class OutputResource(GenericResource):
134
152
  sample_count = payload.get('sample_count') or None
135
153
  if sample_count:
136
154
  sample_count = int(sample_count)
155
+ else:
156
+ sample_count = DATAFRAME_SAMPLE_COUNT
137
157
 
138
158
  model = dict(outputs=[])
139
159
 
@@ -163,9 +183,11 @@ class OutputResource(GenericResource):
163
183
  if not output_serialized:
164
184
  output_serialized = serialize_output(block, output)
165
185
 
166
- model['outputs'].append(dict(
167
- data=output_serialized,
168
- uuid=stream_id,
169
- ))
186
+ model['outputs'].append(
187
+ dict(
188
+ data=output_serialized,
189
+ uuid=stream_id,
190
+ )
191
+ )
170
192
 
171
193
  return self(model, user, **kwargs)