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

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

Potentially problematic release.


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

Files changed (624) hide show
  1. mage_ai/ai/utils/xgboost.py +222 -0
  2. mage_ai/api/errors.py +37 -25
  3. mage_ai/api/operations/base.py +13 -1
  4. mage_ai/api/parsers/PipelineScheduleParser.py +1 -1
  5. mage_ai/api/policies/BackfillPolicy.py +1 -0
  6. mage_ai/api/policies/BlockOutputPolicy.py +40 -17
  7. mage_ai/api/policies/GlobalDataProductPolicy.py +91 -41
  8. mage_ai/api/policies/KernelPolicy.py +55 -32
  9. mage_ai/api/policies/KernelProcessPolicy.py +56 -0
  10. mage_ai/api/policies/OutputPolicy.py +73 -41
  11. mage_ai/api/policies/PipelinePolicy.py +206 -137
  12. mage_ai/api/policies/WorkspacePolicy.py +1 -0
  13. mage_ai/api/presenters/BackfillPresenter.py +1 -0
  14. mage_ai/api/presenters/BlockLayoutItemPresenter.py +9 -7
  15. mage_ai/api/presenters/BlockPresenter.py +1 -1
  16. mage_ai/api/presenters/GlobalDataProductPresenter.py +6 -1
  17. mage_ai/api/presenters/KernelPresenter.py +5 -26
  18. mage_ai/api/presenters/KernelProcessPresenter.py +28 -0
  19. mage_ai/api/presenters/PipelinePresenter.py +18 -5
  20. mage_ai/api/presenters/StatusPresenter.py +2 -0
  21. mage_ai/api/presenters/SyncPresenter.py +25 -0
  22. mage_ai/api/resources/AutocompleteItemResource.py +1 -1
  23. mage_ai/api/resources/BlockLayoutItemResource.py +90 -44
  24. mage_ai/api/resources/BlockOutputResource.py +42 -9
  25. mage_ai/api/resources/BlockResource.py +4 -3
  26. mage_ai/api/resources/BlockRunResource.py +27 -22
  27. mage_ai/api/resources/ClusterResource.py +4 -1
  28. mage_ai/api/resources/CustomTemplateResource.py +34 -14
  29. mage_ai/api/resources/DataProviderResource.py +1 -1
  30. mage_ai/api/resources/ExecutionStateResource.py +3 -1
  31. mage_ai/api/resources/FileContentResource.py +8 -2
  32. mage_ai/api/resources/FileResource.py +10 -4
  33. mage_ai/api/resources/FileVersionResource.py +3 -1
  34. mage_ai/api/resources/GitBranchResource.py +101 -31
  35. mage_ai/api/resources/GitCustomBranchResource.py +29 -1
  36. mage_ai/api/resources/GlobalDataProductResource.py +44 -7
  37. mage_ai/api/resources/GlobalHookResource.py +4 -1
  38. mage_ai/api/resources/IntegrationDestinationResource.py +6 -2
  39. mage_ai/api/resources/IntegrationSourceResource.py +8 -4
  40. mage_ai/api/resources/IntegrationSourceStreamResource.py +6 -2
  41. mage_ai/api/resources/KernelProcessResource.py +44 -0
  42. mage_ai/api/resources/KernelResource.py +25 -3
  43. mage_ai/api/resources/OauthResource.py +1 -1
  44. mage_ai/api/resources/OutputResource.py +33 -11
  45. mage_ai/api/resources/PageBlockLayoutResource.py +34 -23
  46. mage_ai/api/resources/PipelineInteractionResource.py +31 -15
  47. mage_ai/api/resources/PipelineResource.py +258 -125
  48. mage_ai/api/resources/PipelineRunResource.py +52 -7
  49. mage_ai/api/resources/PipelineScheduleResource.py +11 -2
  50. mage_ai/api/resources/PipelineTriggerResource.py +6 -1
  51. mage_ai/api/resources/ProjectResource.py +18 -7
  52. mage_ai/api/resources/PullRequestResource.py +6 -4
  53. mage_ai/api/resources/SecretResource.py +1 -1
  54. mage_ai/api/resources/SeedResource.py +8 -1
  55. mage_ai/api/resources/StatusResource.py +21 -6
  56. mage_ai/api/resources/SyncResource.py +6 -8
  57. mage_ai/api/resources/VariableResource.py +46 -26
  58. mage_ai/api/resources/VersionControlProjectResource.py +9 -2
  59. mage_ai/api/resources/WidgetResource.py +1 -1
  60. mage_ai/api/resources/WorkspaceResource.py +6 -5
  61. mage_ai/api/views.py +47 -40
  62. mage_ai/authentication/permissions/seed.py +16 -2
  63. mage_ai/authentication/providers/oidc.py +21 -1
  64. mage_ai/autocomplete/utils.py +13 -9
  65. mage_ai/cache/base.py +1 -1
  66. mage_ai/cache/block.py +18 -12
  67. mage_ai/cache/block_action_object/__init__.py +33 -5
  68. mage_ai/cache/file.py +22 -19
  69. mage_ai/cache/pipeline.py +18 -12
  70. mage_ai/cli/main.py +1 -0
  71. mage_ai/cluster_manager/aws/emr_cluster_manager.py +9 -5
  72. mage_ai/cluster_manager/config.py +2 -2
  73. mage_ai/cluster_manager/kubernetes/workload_manager.py +52 -1
  74. mage_ai/cluster_manager/manage.py +1 -1
  75. mage_ai/cluster_manager/workspace/base.py +7 -1
  76. mage_ai/cluster_manager/workspace/kubernetes.py +22 -1
  77. mage_ai/command_center/applications/factory.py +10 -7
  78. mage_ai/command_center/applications/utils.py +2 -2
  79. mage_ai/command_center/files/factory.py +17 -15
  80. mage_ai/command_center/presenters/text.py +1 -1
  81. mage_ai/command_center/utils.py +25 -13
  82. mage_ai/data/__init__.py +0 -0
  83. mage_ai/data/constants.py +45 -0
  84. mage_ai/data/models/__init__.py +0 -0
  85. mage_ai/data/models/base.py +119 -0
  86. mage_ai/data/models/constants.py +1 -0
  87. mage_ai/data/models/generator.py +115 -0
  88. mage_ai/data/models/manager.py +168 -0
  89. mage_ai/data/models/pyarrow/__init__.py +0 -0
  90. mage_ai/data/models/pyarrow/record_batch.py +55 -0
  91. mage_ai/data/models/pyarrow/shared.py +21 -0
  92. mage_ai/data/models/pyarrow/table.py +8 -0
  93. mage_ai/data/models/reader.py +103 -0
  94. mage_ai/data/models/utils.py +59 -0
  95. mage_ai/data/models/writer.py +91 -0
  96. mage_ai/data/tabular/__init__.py +0 -0
  97. mage_ai/data/tabular/constants.py +23 -0
  98. mage_ai/data/tabular/mocks.py +19 -0
  99. mage_ai/data/tabular/models.py +126 -0
  100. mage_ai/data/tabular/reader.py +602 -0
  101. mage_ai/data/tabular/utils.py +102 -0
  102. mage_ai/data/tabular/writer.py +266 -0
  103. mage_ai/data/variables/__init__.py +0 -0
  104. mage_ai/data/variables/wrapper.py +54 -0
  105. mage_ai/data_cleaner/analysis/charts.py +61 -39
  106. mage_ai/data_cleaner/column_types/column_type_detector.py +53 -31
  107. mage_ai/data_cleaner/estimators/encoders.py +5 -2
  108. mage_ai/data_integrations/utils/scheduler.py +16 -11
  109. mage_ai/data_preparation/decorators.py +1 -0
  110. mage_ai/data_preparation/executors/block_executor.py +237 -155
  111. mage_ai/data_preparation/executors/k8s_block_executor.py +30 -7
  112. mage_ai/data_preparation/executors/k8s_pipeline_executor.py +30 -7
  113. mage_ai/data_preparation/executors/streaming_pipeline_executor.py +2 -2
  114. mage_ai/data_preparation/git/__init__.py +77 -29
  115. mage_ai/data_preparation/git/api.py +69 -8
  116. mage_ai/data_preparation/git/utils.py +64 -34
  117. mage_ai/data_preparation/logging/logger_manager.py +4 -3
  118. mage_ai/data_preparation/models/block/__init__.py +1562 -879
  119. mage_ai/data_preparation/models/block/data_integration/mixins.py +4 -3
  120. mage_ai/data_preparation/models/block/dynamic/__init__.py +17 -6
  121. mage_ai/data_preparation/models/block/dynamic/child.py +41 -102
  122. mage_ai/data_preparation/models/block/dynamic/constants.py +1 -0
  123. mage_ai/data_preparation/models/block/dynamic/counter.py +296 -0
  124. mage_ai/data_preparation/models/block/dynamic/data.py +16 -0
  125. mage_ai/data_preparation/models/block/dynamic/factory.py +163 -0
  126. mage_ai/data_preparation/models/block/dynamic/models.py +19 -0
  127. mage_ai/data_preparation/models/block/dynamic/shared.py +92 -0
  128. mage_ai/data_preparation/models/block/dynamic/utils.py +295 -167
  129. mage_ai/data_preparation/models/block/dynamic/variables.py +384 -144
  130. mage_ai/data_preparation/models/block/dynamic/wrappers.py +77 -0
  131. mage_ai/data_preparation/models/block/extension/utils.py +10 -1
  132. mage_ai/data_preparation/models/block/global_data_product/__init__.py +35 -3
  133. mage_ai/data_preparation/models/block/integration/__init__.py +6 -2
  134. mage_ai/data_preparation/models/block/outputs.py +722 -0
  135. mage_ai/data_preparation/models/block/platform/mixins.py +7 -8
  136. mage_ai/data_preparation/models/block/r/__init__.py +56 -38
  137. mage_ai/data_preparation/models/block/remote/__init__.py +0 -0
  138. mage_ai/data_preparation/models/block/remote/models.py +58 -0
  139. mage_ai/data_preparation/models/block/settings/__init__.py +0 -0
  140. mage_ai/data_preparation/models/block/settings/dynamic/__init__.py +0 -0
  141. mage_ai/data_preparation/models/block/settings/dynamic/constants.py +7 -0
  142. mage_ai/data_preparation/models/block/settings/dynamic/mixins.py +118 -0
  143. mage_ai/data_preparation/models/block/settings/dynamic/models.py +31 -0
  144. mage_ai/data_preparation/models/block/settings/global_data_products/__init__.py +0 -0
  145. mage_ai/data_preparation/models/block/settings/global_data_products/mixins.py +20 -0
  146. mage_ai/data_preparation/models/block/settings/global_data_products/models.py +46 -0
  147. mage_ai/data_preparation/models/block/settings/variables/__init__.py +0 -0
  148. mage_ai/data_preparation/models/block/settings/variables/mixins.py +74 -0
  149. mage_ai/data_preparation/models/block/settings/variables/models.py +49 -0
  150. mage_ai/data_preparation/models/block/spark/mixins.py +2 -1
  151. mage_ai/data_preparation/models/block/sql/__init__.py +30 -5
  152. mage_ai/data_preparation/models/block/sql/utils/shared.py +21 -3
  153. mage_ai/data_preparation/models/block/utils.py +164 -69
  154. mage_ai/data_preparation/models/constants.py +21 -14
  155. mage_ai/data_preparation/models/custom_templates/custom_block_template.py +18 -13
  156. mage_ai/data_preparation/models/custom_templates/custom_pipeline_template.py +33 -16
  157. mage_ai/data_preparation/models/custom_templates/utils.py +1 -1
  158. mage_ai/data_preparation/models/file.py +41 -28
  159. mage_ai/data_preparation/models/global_data_product/__init__.py +100 -58
  160. mage_ai/data_preparation/models/global_hooks/models.py +1 -0
  161. mage_ai/data_preparation/models/interfaces.py +29 -0
  162. mage_ai/data_preparation/models/pipeline.py +374 -185
  163. mage_ai/data_preparation/models/pipelines/integration_pipeline.py +1 -2
  164. mage_ai/data_preparation/models/pipelines/seed.py +1 -1
  165. mage_ai/data_preparation/models/project/__init__.py +66 -18
  166. mage_ai/data_preparation/models/project/constants.py +2 -0
  167. mage_ai/data_preparation/models/triggers/__init__.py +124 -26
  168. mage_ai/data_preparation/models/utils.py +467 -17
  169. mage_ai/data_preparation/models/variable.py +1028 -137
  170. mage_ai/data_preparation/models/variables/__init__.py +0 -0
  171. mage_ai/data_preparation/models/variables/cache.py +149 -0
  172. mage_ai/data_preparation/models/variables/constants.py +72 -0
  173. mage_ai/data_preparation/models/variables/summarizer.py +336 -0
  174. mage_ai/data_preparation/models/variables/utils.py +77 -0
  175. mage_ai/data_preparation/models/widget/__init__.py +63 -41
  176. mage_ai/data_preparation/models/widget/charts.py +40 -27
  177. mage_ai/data_preparation/models/widget/constants.py +2 -0
  178. mage_ai/data_preparation/models/widget/utils.py +3 -3
  179. mage_ai/data_preparation/preferences.py +3 -3
  180. mage_ai/data_preparation/repo_manager.py +55 -21
  181. mage_ai/data_preparation/storage/base_storage.py +2 -2
  182. mage_ai/data_preparation/storage/gcs_storage.py +7 -4
  183. mage_ai/data_preparation/storage/local_storage.py +18 -9
  184. mage_ai/data_preparation/storage/s3_storage.py +5 -2
  185. mage_ai/data_preparation/templates/data_exporters/streaming/oracledb.yaml +8 -0
  186. mage_ai/data_preparation/variable_manager.py +281 -76
  187. mage_ai/io/base.py +3 -2
  188. mage_ai/io/bigquery.py +1 -0
  189. mage_ai/io/redshift.py +7 -5
  190. mage_ai/kernels/__init__.py +0 -0
  191. mage_ai/kernels/models.py +188 -0
  192. mage_ai/kernels/utils.py +169 -0
  193. mage_ai/orchestration/concurrency.py +6 -2
  194. mage_ai/orchestration/db/__init__.py +1 -0
  195. mage_ai/orchestration/db/migrations/versions/0227396a216c_add_userproject_table.py +38 -0
  196. mage_ai/orchestration/db/migrations/versions/42a14d6143f1_update_token_column_type.py +54 -0
  197. mage_ai/orchestration/db/models/dynamic/__init__.py +0 -0
  198. mage_ai/orchestration/db/models/dynamic/controller.py +67 -0
  199. mage_ai/orchestration/db/models/oauth.py +12 -18
  200. mage_ai/orchestration/db/models/projects.py +10 -0
  201. mage_ai/orchestration/db/models/schedules.py +225 -187
  202. mage_ai/orchestration/db/models/schedules_project_platform.py +18 -12
  203. mage_ai/orchestration/db/models/utils.py +46 -5
  204. mage_ai/orchestration/metrics/pipeline_run.py +8 -9
  205. mage_ai/orchestration/notification/sender.py +38 -15
  206. mage_ai/orchestration/pipeline_scheduler_original.py +64 -33
  207. mage_ai/orchestration/pipeline_scheduler_project_platform.py +1 -1
  208. mage_ai/orchestration/run_status_checker.py +11 -4
  209. mage_ai/orchestration/triggers/api.py +41 -2
  210. mage_ai/orchestration/triggers/global_data_product.py +9 -4
  211. mage_ai/orchestration/triggers/utils.py +10 -1
  212. mage_ai/orchestration/utils/resources.py +3 -0
  213. mage_ai/presenters/charts/data_sources/base.py +4 -2
  214. mage_ai/presenters/charts/data_sources/block.py +15 -9
  215. mage_ai/presenters/charts/data_sources/chart_code.py +8 -5
  216. mage_ai/presenters/charts/data_sources/constants.py +1 -0
  217. mage_ai/presenters/charts/data_sources/system_metrics.py +22 -0
  218. mage_ai/presenters/interactions/models.py +11 -7
  219. mage_ai/presenters/pages/loaders/pipelines.py +5 -3
  220. mage_ai/presenters/pages/models/page_components/pipeline_schedules.py +3 -1
  221. mage_ai/presenters/utils.py +2 -0
  222. mage_ai/server/api/blocks.py +2 -1
  223. mage_ai/server/api/downloads.py +9 -2
  224. mage_ai/server/api/runs.py +151 -0
  225. mage_ai/server/api/triggers.py +3 -1
  226. mage_ai/server/constants.py +1 -1
  227. mage_ai/server/frontend_dist/404.html +8 -8
  228. mage_ai/server/frontend_dist/_next/static/UZLabyPgcxtZvp0O0EUUS/_buildManifest.js +1 -0
  229. mage_ai/server/frontend_dist/_next/static/chunks/1376-22de38b4ad008d8a.js +1 -0
  230. mage_ai/server/frontend_dist/_next/static/chunks/1557-25a7d985d5564fd3.js +1 -0
  231. mage_ai/server/frontend_dist/_next/static/chunks/1668-30b4619b9534519b.js +1 -0
  232. mage_ai/server/frontend_dist/_next/static/chunks/1799-c42db95a015689ee.js +1 -0
  233. mage_ai/server/frontend_dist/_next/static/chunks/2996-2108b53b9d371d8d.js +1 -0
  234. mage_ai/server/frontend_dist/_next/static/chunks/{3548-fa0792ddb88f4646.js → 3548-9d26185b3fb663b1.js} +1 -1
  235. mage_ai/server/frontend_dist/_next/static/chunks/{3763-61b542dafdbf5754.js → 3763-40780c6d1e4b261d.js} +1 -1
  236. mage_ai/server/frontend_dist/_next/static/chunks/3782-129dd2a2448a2e36.js +1 -0
  237. mage_ai/server/frontend_dist/_next/static/chunks/3958-bcdfa414ccfa1eb2.js +1 -0
  238. mage_ai/server/frontend_dist/_next/static/chunks/4168-97fd1578d1a38315.js +1 -0
  239. mage_ai/server/frontend_dist/_next/static/chunks/4982-fa5a238b139fbdd2.js +1 -0
  240. mage_ai/server/frontend_dist/_next/static/chunks/5699-176f445e1313f001.js +1 -0
  241. mage_ai/server/frontend_dist/_next/static/chunks/7162-7dd03f0f605de721.js +1 -0
  242. mage_ai/server/frontend_dist/_next/static/chunks/7779-68d2b72a90c5f925.js +1 -0
  243. mage_ai/server/frontend_dist/_next/static/chunks/7966-5446a8e43711e2f9.js +1 -0
  244. mage_ai/server/frontend_dist/_next/static/chunks/8023-6c2f172f48dcb99b.js +1 -0
  245. mage_ai/server/frontend_dist/_next/static/chunks/8095-c351b8a735d73e0c.js +1 -0
  246. mage_ai/server/frontend_dist/_next/static/chunks/9624-8b8e100079ab69e1.js +1 -0
  247. mage_ai/server/frontend_dist/_next/static/chunks/{main-77fe248a6fbd12d8.js → main-b99d4e30a88d9dc7.js} +1 -1
  248. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-9fe2d9d07c94e968.js +1 -0
  249. mage_ai/server/frontend_dist/_next/static/chunks/pages/{block-layout-14f952f66964022f.js → block-layout-7f4b735c67115df5.js} +1 -1
  250. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-e7d48e6b0c3068ac.js +1 -0
  251. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products-b943f31f050fc3a4.js +1 -0
  252. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-4bfc84ff07d7656f.js +1 -0
  253. mage_ai/server/frontend_dist/_next/static/chunks/pages/{overview-597b74828bf105db.js → overview-9f1ac4ec003884f3.js} +1 -1
  254. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-3edc6270c5b0e962.js → frontend_dist/_next/static/chunks/pages/pipeline-runs-6d183f91a2ff6668.js} +1 -1
  255. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-7e737f6fc7e83e9b.js +1 -0
  256. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-38e1fbcfbfc1014e.js +1 -0
  257. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-d94488e3f2eeef36.js +1 -0
  258. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-cc641a7fa8473796.js +1 -0
  259. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-a5c0362763a21fa8.js → block-runs-284309877f3c5a5a.js} +1 -1
  260. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-26250e5335194ade.js +1 -0
  261. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-7acc7afc00df17c2.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-5f4c8128b2413fd8.js} +1 -1
  262. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-4ebfc8e400315dda.js +1 -0
  263. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-e5e0150a256aadb3.js +1 -0
  264. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-eb11c5390c982b49.js +1 -0
  265. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{triggers-1bdfda8edc9cf4a8.js → triggers-4612d15a65c35912.js} +1 -1
  266. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/{profile-3f0df3decc856ee9.js → profile-3ae43c932537b254.js} +1 -1
  267. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-b603d7fe4b175256.js +1 -0
  268. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-c2e9ef989c8bfa73.js → frontend_dist/_next/static/chunks/pages/settings/platform/settings-319ddbabc239e91b.js} +1 -1
  269. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-47b64ced27c24985.js → [...slug]-5c360f72e4498855.js} +1 -1
  270. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{permissions-e5a4d3d815cec25d.js → permissions-fb29fa6c2bd90bb0.js} +1 -1
  271. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-3b76fa959ffa09d3.js +1 -0
  272. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-379e1ee292504842.js → [...slug]-3b787b42f1093b1f.js} +1 -1
  273. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-0b83fbdd39e85f5b.js +1 -0
  274. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-a1e6950974d643a8.js +1 -0
  275. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-2af9afbe727d88aa.js → [...slug]-0aa019d87db8b0b8.js} +1 -1
  276. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{users-a4db8710f703c729.js → users-88c694d19207f2ec.js} +1 -1
  277. mage_ai/server/frontend_dist/_next/static/chunks/pages/{triggers-9cba3211434a8966.js → triggers-a599c6ac89be8c8d.js} +1 -1
  278. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-31d0d50f7f30462b.js +1 -0
  279. mage_ai/server/frontend_dist/_next/static/chunks/{webpack-d079359c241db804.js → webpack-ac7fdc472bedf682.js} +1 -1
  280. mage_ai/server/frontend_dist/block-layout.html +3 -3
  281. mage_ai/server/frontend_dist/compute.html +6 -6
  282. mage_ai/server/frontend_dist/files.html +6 -6
  283. mage_ai/server/frontend_dist/global-data-products/[...slug].html +6 -6
  284. mage_ai/server/frontend_dist/global-data-products.html +6 -6
  285. mage_ai/server/frontend_dist/global-hooks/[...slug].html +6 -6
  286. mage_ai/server/frontend_dist/global-hooks.html +6 -6
  287. mage_ai/server/frontend_dist/index.html +3 -3
  288. mage_ai/server/frontend_dist/manage/files.html +6 -6
  289. mage_ai/server/frontend_dist/manage/settings.html +6 -6
  290. mage_ai/server/frontend_dist/manage/users/[user].html +6 -6
  291. mage_ai/server/frontend_dist/manage/users/new.html +6 -6
  292. mage_ai/server/frontend_dist/manage/users.html +6 -6
  293. mage_ai/server/frontend_dist/manage.html +6 -6
  294. mage_ai/server/frontend_dist/oauth.html +5 -5
  295. mage_ai/server/frontend_dist/overview.html +6 -6
  296. mage_ai/server/frontend_dist/pipeline-runs.html +6 -6
  297. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +6 -6
  298. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +6 -6
  299. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +6 -6
  300. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +3 -3
  301. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +6 -6
  302. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +6 -6
  303. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
  304. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +6 -6
  305. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +6 -6
  306. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +6 -6
  307. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +6 -6
  308. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +6 -6
  309. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +6 -6
  310. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +6 -6
  311. mage_ai/server/frontend_dist/pipelines/[pipeline].html +3 -3
  312. mage_ai/server/frontend_dist/pipelines.html +6 -6
  313. mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +6 -6
  314. mage_ai/server/frontend_dist/platform/global-hooks.html +6 -6
  315. mage_ai/server/frontend_dist/settings/account/profile.html +6 -6
  316. mage_ai/server/frontend_dist/settings/platform/preferences.html +6 -6
  317. mage_ai/server/frontend_dist/settings/platform/settings.html +6 -6
  318. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +6 -6
  319. mage_ai/server/frontend_dist/settings/workspace/permissions.html +6 -6
  320. mage_ai/server/frontend_dist/settings/workspace/preferences.html +6 -6
  321. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +6 -6
  322. mage_ai/server/frontend_dist/settings/workspace/roles.html +6 -6
  323. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +6 -6
  324. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +6 -6
  325. mage_ai/server/frontend_dist/settings/workspace/users.html +6 -6
  326. mage_ai/server/frontend_dist/settings.html +3 -3
  327. mage_ai/server/frontend_dist/sign-in.html +15 -15
  328. mage_ai/server/frontend_dist/templates/[...slug].html +6 -6
  329. mage_ai/server/frontend_dist/templates.html +6 -6
  330. mage_ai/server/frontend_dist/terminal.html +6 -6
  331. mage_ai/server/frontend_dist/test.html +3 -3
  332. mage_ai/server/frontend_dist/triggers.html +6 -6
  333. mage_ai/server/frontend_dist/version-control.html +6 -6
  334. mage_ai/server/frontend_dist_base_path_template/404.html +8 -8
  335. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1376-22de38b4ad008d8a.js +1 -0
  336. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-25a7d985d5564fd3.js +1 -0
  337. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1668-30b4619b9534519b.js +1 -0
  338. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1799-c42db95a015689ee.js +1 -0
  339. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2996-2108b53b9d371d8d.js +1 -0
  340. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{3548-fa0792ddb88f4646.js → 3548-9d26185b3fb663b1.js} +1 -1
  341. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{3763-61b542dafdbf5754.js → 3763-40780c6d1e4b261d.js} +1 -1
  342. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-129dd2a2448a2e36.js +1 -0
  343. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3958-bcdfa414ccfa1eb2.js +1 -0
  344. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4168-97fd1578d1a38315.js +1 -0
  345. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4982-fa5a238b139fbdd2.js +1 -0
  346. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-176f445e1313f001.js +1 -0
  347. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7162-7dd03f0f605de721.js +1 -0
  348. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7779-68d2b72a90c5f925.js +1 -0
  349. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-5446a8e43711e2f9.js +1 -0
  350. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8023-6c2f172f48dcb99b.js +1 -0
  351. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-c351b8a735d73e0c.js +1 -0
  352. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9624-8b8e100079ab69e1.js +1 -0
  353. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{main-70b78159c2bb3fe1.js → main-384298e9133cec76.js} +1 -1
  354. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-13a578bce3b7f30c.js +1 -0
  355. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{block-layout-14f952f66964022f.js → block-layout-7f4b735c67115df5.js} +1 -1
  356. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-e7d48e6b0c3068ac.js +1 -0
  357. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products-b943f31f050fc3a4.js +1 -0
  358. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-4bfc84ff07d7656f.js +1 -0
  359. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{overview-597b74828bf105db.js → overview-9f1ac4ec003884f3.js} +1 -1
  360. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipeline-runs-3edc6270c5b0e962.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-6d183f91a2ff6668.js} +1 -1
  361. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-7e737f6fc7e83e9b.js +1 -0
  362. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-38e1fbcfbfc1014e.js +1 -0
  363. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-d94488e3f2eeef36.js +1 -0
  364. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-cc641a7fa8473796.js +1 -0
  365. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-a5c0362763a21fa8.js → block-runs-284309877f3c5a5a.js} +1 -1
  366. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-26250e5335194ade.js +1 -0
  367. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-7acc7afc00df17c2.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-5f4c8128b2413fd8.js} +1 -1
  368. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-4ebfc8e400315dda.js +1 -0
  369. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-e5e0150a256aadb3.js +1 -0
  370. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-eb11c5390c982b49.js +1 -0
  371. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{triggers-1bdfda8edc9cf4a8.js → triggers-4612d15a65c35912.js} +1 -1
  372. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/{profile-3f0df3decc856ee9.js → profile-3ae43c932537b254.js} +1 -1
  373. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-b603d7fe4b175256.js +1 -0
  374. mage_ai/server/{frontend_dist/_next/static/chunks/pages/settings/platform/settings-c2e9ef989c8bfa73.js → frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-319ddbabc239e91b.js} +1 -1
  375. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-47b64ced27c24985.js → [...slug]-5c360f72e4498855.js} +1 -1
  376. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{permissions-e5a4d3d815cec25d.js → permissions-fb29fa6c2bd90bb0.js} +1 -1
  377. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-3b76fa959ffa09d3.js +1 -0
  378. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-379e1ee292504842.js → [...slug]-3b787b42f1093b1f.js} +1 -1
  379. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-0b83fbdd39e85f5b.js +1 -0
  380. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-a1e6950974d643a8.js +1 -0
  381. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-2af9afbe727d88aa.js → [...slug]-0aa019d87db8b0b8.js} +1 -1
  382. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{users-a4db8710f703c729.js → users-88c694d19207f2ec.js} +1 -1
  383. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{triggers-9cba3211434a8966.js → triggers-a599c6ac89be8c8d.js} +1 -1
  384. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-31d0d50f7f30462b.js +1 -0
  385. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-68c003fb6a175cd7.js → webpack-481689d9989710cd.js} +1 -1
  386. mage_ai/server/frontend_dist_base_path_template/_next/static/kcptwoOU-JJJg6Vwpkfmx/_buildManifest.js +1 -0
  387. mage_ai/server/frontend_dist_base_path_template/block-layout.html +3 -3
  388. mage_ai/server/frontend_dist_base_path_template/compute.html +6 -6
  389. mage_ai/server/frontend_dist_base_path_template/files.html +6 -6
  390. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +6 -6
  391. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +6 -6
  392. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +6 -6
  393. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +6 -6
  394. mage_ai/server/frontend_dist_base_path_template/index.html +3 -3
  395. mage_ai/server/frontend_dist_base_path_template/manage/files.html +6 -6
  396. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +6 -6
  397. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +6 -6
  398. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +6 -6
  399. mage_ai/server/frontend_dist_base_path_template/manage/users.html +6 -6
  400. mage_ai/server/frontend_dist_base_path_template/manage.html +6 -6
  401. mage_ai/server/frontend_dist_base_path_template/oauth.html +5 -5
  402. mage_ai/server/frontend_dist_base_path_template/overview.html +6 -6
  403. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +6 -6
  404. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +6 -6
  405. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +6 -6
  406. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +6 -6
  407. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +3 -3
  408. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +6 -6
  409. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +6 -6
  410. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
  411. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +6 -6
  412. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +6 -6
  413. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +6 -6
  414. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +6 -6
  415. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +6 -6
  416. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +6 -6
  417. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +6 -6
  418. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +3 -3
  419. mage_ai/server/frontend_dist_base_path_template/pipelines.html +6 -6
  420. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +6 -6
  421. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +6 -6
  422. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +6 -6
  423. mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +6 -6
  424. mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +6 -6
  425. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +6 -6
  426. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +6 -6
  427. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +6 -6
  428. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +6 -6
  429. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +6 -6
  430. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +6 -6
  431. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +6 -6
  432. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +6 -6
  433. mage_ai/server/frontend_dist_base_path_template/settings.html +3 -3
  434. mage_ai/server/frontend_dist_base_path_template/sign-in.html +15 -15
  435. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +6 -6
  436. mage_ai/server/frontend_dist_base_path_template/templates.html +6 -6
  437. mage_ai/server/frontend_dist_base_path_template/terminal.html +6 -6
  438. mage_ai/server/frontend_dist_base_path_template/test.html +3 -3
  439. mage_ai/server/frontend_dist_base_path_template/triggers.html +6 -6
  440. mage_ai/server/frontend_dist_base_path_template/version-control.html +6 -6
  441. mage_ai/server/kernel_output_parser.py +4 -1
  442. mage_ai/server/scheduler_manager.py +12 -1
  443. mage_ai/server/server.py +69 -42
  444. mage_ai/server/utils/custom_output.py +284 -0
  445. mage_ai/server/utils/execute_custom_code.py +245 -0
  446. mage_ai/server/utils/output_display.py +123 -289
  447. mage_ai/server/websocket_server.py +116 -69
  448. mage_ai/services/aws/ecs/ecs.py +1 -0
  449. mage_ai/services/k8s/config.py +27 -4
  450. mage_ai/services/k8s/job_manager.py +6 -1
  451. mage_ai/services/k8s/utils.py +97 -0
  452. mage_ai/services/ssh/aws/emr/utils.py +8 -8
  453. mage_ai/settings/keys/auth.py +1 -0
  454. mage_ai/settings/platform/__init__.py +159 -38
  455. mage_ai/settings/platform/constants.py +5 -0
  456. mage_ai/settings/platform/utils.py +53 -10
  457. mage_ai/settings/repo.py +26 -12
  458. mage_ai/settings/server.py +128 -37
  459. mage_ai/shared/array.py +24 -1
  460. mage_ai/shared/complex.py +45 -0
  461. mage_ai/shared/config.py +2 -1
  462. mage_ai/shared/custom_logger.py +11 -0
  463. mage_ai/shared/dates.py +10 -6
  464. mage_ai/shared/files.py +63 -8
  465. mage_ai/shared/hash.py +33 -9
  466. mage_ai/shared/io.py +9 -5
  467. mage_ai/shared/models.py +82 -24
  468. mage_ai/shared/outputs.py +87 -0
  469. mage_ai/shared/parsers.py +144 -13
  470. mage_ai/shared/path_fixer.py +11 -7
  471. mage_ai/shared/singletons/__init__.py +0 -0
  472. mage_ai/shared/singletons/base.py +47 -0
  473. mage_ai/shared/singletons/memory.py +38 -0
  474. mage_ai/shared/strings.py +34 -1
  475. mage_ai/shared/yaml.py +24 -0
  476. mage_ai/streaming/sinks/oracledb.py +57 -0
  477. mage_ai/streaming/sinks/sink_factory.py +4 -0
  478. mage_ai/system/__init__.py +0 -0
  479. mage_ai/system/constants.py +14 -0
  480. mage_ai/system/memory/__init__.py +0 -0
  481. mage_ai/system/memory/constants.py +1 -0
  482. mage_ai/system/memory/manager.py +174 -0
  483. mage_ai/system/memory/presenters.py +158 -0
  484. mage_ai/system/memory/process.py +216 -0
  485. mage_ai/system/memory/samples.py +13 -0
  486. mage_ai/system/memory/utils.py +656 -0
  487. mage_ai/system/memory/wrappers.py +177 -0
  488. mage_ai/system/models.py +58 -0
  489. mage_ai/system/storage/__init__.py +0 -0
  490. mage_ai/system/storage/utils.py +29 -0
  491. mage_ai/tests/api/endpoints/mixins.py +2 -2
  492. mage_ai/tests/api/endpoints/test_blocks.py +2 -1
  493. mage_ai/tests/api/endpoints/test_custom_designs.py +4 -4
  494. mage_ai/tests/api/endpoints/test_pipeline_runs.py +2 -2
  495. mage_ai/tests/api/endpoints/test_projects.py +2 -1
  496. mage_ai/tests/api/operations/base/mixins.py +1 -1
  497. mage_ai/tests/api/operations/base/test_base.py +27 -27
  498. mage_ai/tests/api/operations/base/test_base_with_user_authentication.py +27 -27
  499. mage_ai/tests/api/operations/base/test_base_with_user_permissions.py +23 -23
  500. mage_ai/tests/api/operations/test_syncs.py +6 -4
  501. mage_ai/tests/api/resources/test_pipeline_resource.py +11 -4
  502. mage_ai/tests/authentication/oauth/test_utils.py +1 -1
  503. mage_ai/tests/authentication/providers/test_oidc.py +59 -0
  504. mage_ai/tests/base_test.py +2 -2
  505. mage_ai/tests/data/__init__.py +0 -0
  506. mage_ai/tests/data/models/__init__.py +0 -0
  507. mage_ai/tests/data_preparation/executors/test_block_executor.py +23 -16
  508. mage_ai/tests/data_preparation/git/test_git.py +4 -1
  509. mage_ai/tests/data_preparation/models/block/dynamic/test_combos.py +305 -0
  510. mage_ai/tests/data_preparation/models/block/dynamic/test_counter.py +212 -0
  511. mage_ai/tests/data_preparation/models/block/dynamic/test_factory.py +360 -0
  512. mage_ai/tests/data_preparation/models/block/dynamic/test_variables.py +332 -0
  513. mage_ai/tests/data_preparation/models/block/hook/test_hook_block.py +2 -2
  514. mage_ai/tests/data_preparation/models/block/platform/test_mixins.py +1 -1
  515. mage_ai/tests/data_preparation/models/block/sql/utils/test_shared.py +26 -1
  516. mage_ai/tests/data_preparation/models/block/test_global_data_product.py +5 -2
  517. mage_ai/tests/data_preparation/models/custom_templates/test_utils.py +5 -4
  518. mage_ai/tests/data_preparation/models/global_hooks/test_hook.py +3 -0
  519. mage_ai/tests/data_preparation/models/global_hooks/test_predicates.py +9 -3
  520. mage_ai/tests/data_preparation/models/test_block.py +115 -120
  521. mage_ai/tests/data_preparation/models/test_blocks_helper.py +114 -0
  522. mage_ai/tests/data_preparation/models/test_global_data_product.py +41 -24
  523. mage_ai/tests/data_preparation/models/test_pipeline.py +9 -6
  524. mage_ai/tests/data_preparation/models/test_project.py +4 -1
  525. mage_ai/tests/data_preparation/models/test_utils.py +80 -0
  526. mage_ai/tests/data_preparation/models/test_variable.py +242 -69
  527. mage_ai/tests/data_preparation/models/variables/__init__.py +0 -0
  528. mage_ai/tests/data_preparation/models/variables/test_summarizer.py +481 -0
  529. mage_ai/tests/data_preparation/storage/shared/__init__.py +0 -0
  530. mage_ai/tests/data_preparation/test_repo_manager.py +6 -7
  531. mage_ai/tests/data_preparation/test_variable_manager.py +57 -48
  532. mage_ai/tests/factory.py +64 -43
  533. mage_ai/tests/orchestration/db/models/test_schedules.py +3 -3
  534. mage_ai/tests/orchestration/db/models/test_schedules_dynamic_blocks.py +279 -0
  535. mage_ai/tests/orchestration/test_pipeline_scheduler.py +1 -0
  536. mage_ai/tests/orchestration/triggers/test_global_data_product.py +141 -138
  537. mage_ai/tests/orchestration/triggers/test_utils.py +3 -2
  538. mage_ai/tests/server/test_server.py +19 -0
  539. mage_ai/tests/services/k8s/test_job_manager.py +27 -6
  540. mage_ai/tests/streaming/sinks/test_oracledb.py +38 -0
  541. mage_ai/tests/test_shared.py +61 -0
  542. mage_ai/usage_statistics/logger.py +7 -2
  543. mage_ai/utils/code.py +33 -19
  544. mage_ai/version_control/branch/utils.py +2 -1
  545. mage_ai/version_control/models.py +3 -2
  546. {mage_ai-0.9.69.dist-info → mage_ai-0.9.71.dist-info}/METADATA +6 -3
  547. {mage_ai-0.9.69.dist-info → mage_ai-0.9.71.dist-info}/RECORD +555 -454
  548. mage_ai/data_preparation/models/global_data_product/constants.py +0 -6
  549. mage_ai/server/frontend_dist/_next/static/_krrrgup_C-dPOpX36S8I/_buildManifest.js +0 -1
  550. mage_ai/server/frontend_dist/_next/static/chunks/1557-df144fbd8b2208c3.js +0 -1
  551. mage_ai/server/frontend_dist/_next/static/chunks/2631-b9f9bea3f1cf906d.js +0 -1
  552. mage_ai/server/frontend_dist/_next/static/chunks/3782-ef4cd4f0b52072d0.js +0 -1
  553. mage_ai/server/frontend_dist/_next/static/chunks/4783-422429203610c318.js +0 -1
  554. mage_ai/server/frontend_dist/_next/static/chunks/5699-6d708c6b2153ea08.js +0 -1
  555. mage_ai/server/frontend_dist/_next/static/chunks/635-0d6b7c8804bcd2dc.js +0 -1
  556. mage_ai/server/frontend_dist/_next/static/chunks/7022-0d52dd8868621fb0.js +0 -1
  557. mage_ai/server/frontend_dist/_next/static/chunks/7361-8a23dd8360593e7a.js +0 -1
  558. mage_ai/server/frontend_dist/_next/static/chunks/7966-f07b2913f7326b50.js +0 -1
  559. mage_ai/server/frontend_dist/_next/static/chunks/8095-bdce03896ef9639a.js +0 -1
  560. mage_ai/server/frontend_dist/_next/static/chunks/8146-6bed4e7401e067e6.js +0 -1
  561. mage_ai/server/frontend_dist/_next/static/chunks/9265-d2a1aaec75ec69b8.js +0 -1
  562. mage_ai/server/frontend_dist/_next/static/chunks/9440-4069842b90d4b801.js +0 -1
  563. mage_ai/server/frontend_dist/_next/static/chunks/9624-59b2f803f9c88cd6.js +0 -1
  564. mage_ai/server/frontend_dist/_next/static/chunks/9832-67896490f6e8a014.js +0 -1
  565. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-d9c89527266296f7.js +0 -1
  566. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-591abd392dc50ed4.js +0 -1
  567. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products-78e8e88f2a757a18.js +0 -1
  568. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-852d403c7bda21b3.js +0 -1
  569. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-ff4bd7a8ec3bab40.js +0 -1
  570. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-a8b61d8d239fd16f.js +0 -1
  571. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-95ffcd3e2b27e567.js +0 -1
  572. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-e1dd1ed71d26c10d.js +0 -1
  573. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-1ed9045b2f1dfd65.js +0 -1
  574. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.js +0 -1
  575. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +0 -1
  576. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-f028ef3880ed856c.js +0 -1
  577. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-503049734a8b082f.js +0 -1
  578. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-5b26eeda8aed8a7b.js +0 -1
  579. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-36fa165a48af586b.js +0 -1
  580. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-8b793b3b696a2cd3.js +0 -1
  581. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-5753fac7c1bfdc88.js +0 -1
  582. mage_ai/server/frontend_dist_base_path_template/_next/static/KLL5mirre9d7_ZeEpaw3s/_buildManifest.js +0 -1
  583. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-df144fbd8b2208c3.js +0 -1
  584. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2631-b9f9bea3f1cf906d.js +0 -1
  585. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-ef4cd4f0b52072d0.js +0 -1
  586. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4783-422429203610c318.js +0 -1
  587. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-6d708c6b2153ea08.js +0 -1
  588. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/635-0d6b7c8804bcd2dc.js +0 -1
  589. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-0d52dd8868621fb0.js +0 -1
  590. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-8a23dd8360593e7a.js +0 -1
  591. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-f07b2913f7326b50.js +0 -1
  592. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-bdce03896ef9639a.js +0 -1
  593. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-6bed4e7401e067e6.js +0 -1
  594. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9265-d2a1aaec75ec69b8.js +0 -1
  595. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-4069842b90d4b801.js +0 -1
  596. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9624-59b2f803f9c88cd6.js +0 -1
  597. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9832-67896490f6e8a014.js +0 -1
  598. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-d9c89527266296f7.js +0 -1
  599. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-591abd392dc50ed4.js +0 -1
  600. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products-78e8e88f2a757a18.js +0 -1
  601. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-852d403c7bda21b3.js +0 -1
  602. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-ff4bd7a8ec3bab40.js +0 -1
  603. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-a8b61d8d239fd16f.js +0 -1
  604. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-95ffcd3e2b27e567.js +0 -1
  605. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-e1dd1ed71d26c10d.js +0 -1
  606. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-1ed9045b2f1dfd65.js +0 -1
  607. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.js +0 -1
  608. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +0 -1
  609. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-f028ef3880ed856c.js +0 -1
  610. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-503049734a8b082f.js +0 -1
  611. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-5b26eeda8aed8a7b.js +0 -1
  612. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-36fa165a48af586b.js +0 -1
  613. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-8b793b3b696a2cd3.js +0 -1
  614. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-5753fac7c1bfdc88.js +0 -1
  615. mage_ai/shared/memory.py +0 -90
  616. mage_ai/tests/data_preparation/models/block/dynamic/test_dynamic_helpers.py +0 -48
  617. /mage_ai/{tests/data_preparation/shared → ai/utils}/__init__.py +0 -0
  618. /mage_ai/server/frontend_dist/_next/static/{_krrrgup_C-dPOpX36S8I → UZLabyPgcxtZvp0O0EUUS}/_ssgManifest.js +0 -0
  619. /mage_ai/server/frontend_dist_base_path_template/_next/static/{KLL5mirre9d7_ZeEpaw3s → kcptwoOU-JJJg6Vwpkfmx}/_ssgManifest.js +0 -0
  620. /mage_ai/tests/data_preparation/{shared → storage/shared}/test_secrets.py +0 -0
  621. {mage_ai-0.9.69.dist-info → mage_ai-0.9.71.dist-info}/LICENSE +0 -0
  622. {mage_ai-0.9.69.dist-info → mage_ai-0.9.71.dist-info}/WHEEL +0 -0
  623. {mage_ai-0.9.69.dist-info → mage_ai-0.9.71.dist-info}/entry_points.txt +0 -0
  624. {mage_ai-0.9.69.dist-info → mage_ai-0.9.71.dist-info}/top_level.txt +0 -0
@@ -1,30 +1,41 @@
1
1
  import os
2
+ import re
2
3
  from datetime import datetime
3
- from typing import Any, Dict, List
4
-
5
- import pandas as pd
6
-
7
- from mage_ai.data_cleaner.shared.utils import is_geo_dataframe, is_spark_dataframe
8
- from mage_ai.data_preparation.models.variable import (
9
- VARIABLE_DIR,
10
- Variable,
11
- VariableType,
4
+ from typing import Any, Dict, List, Optional
5
+
6
+ from mage_ai.data.constants import InputDataType
7
+ from mage_ai.data.models.generator import DataGenerator
8
+ from mage_ai.data.tabular.models import BatchSettings
9
+ from mage_ai.data_preparation.models.utils import (
10
+ infer_variable_type,
11
+ warn_for_repo_path,
12
+ )
13
+ from mage_ai.data_preparation.models.variable import VARIABLE_DIR, Variable
14
+ from mage_ai.data_preparation.models.variables.constants import VariableType
15
+ from mage_ai.data_preparation.models.variables.utils import (
16
+ get_first_data_output_variable_uuid,
17
+ is_output_variable,
12
18
  )
13
19
  from mage_ai.data_preparation.repo_manager import get_repo_config
14
20
  from mage_ai.data_preparation.storage.local_storage import LocalStorage
21
+ from mage_ai.io.base import ExportWritePolicy
15
22
  from mage_ai.settings.platform import project_platform_activated
16
23
  from mage_ai.settings.repo import get_repo_path, get_variables_dir
24
+ from mage_ai.settings.server import MEMORY_MANAGER_V2
17
25
  from mage_ai.shared.constants import GCS_PREFIX, S3_PREFIX
18
26
  from mage_ai.shared.dates import str_to_timedelta
19
27
  from mage_ai.shared.environments import is_debug
28
+ from mage_ai.shared.strings import to_ordinal_integers
20
29
  from mage_ai.shared.utils import clean_name
30
+ from mage_ai.system.models import ResourceUsage
21
31
 
22
32
 
23
33
  class VariableManager:
24
34
  def __init__(self, repo_path=None, variables_dir=None):
35
+ warn_for_repo_path(repo_path)
25
36
  self.repo_path = repo_path or get_repo_path()
26
37
  if variables_dir is None:
27
- self.variables_dir = self.repo_path
38
+ self.variables_dir = get_variables_dir(repo_path=self.repo_path)
28
39
  else:
29
40
  self.variables_dir = variables_dir
30
41
  self.storage = LocalStorage()
@@ -32,9 +43,9 @@ class VariableManager:
32
43
 
33
44
  @classmethod
34
45
  def get_manager(
35
- self,
36
- repo_path: str = None,
37
- variables_dir: str = None,
46
+ cls,
47
+ repo_path: Optional[str] = None,
48
+ variables_dir: Optional[str] = None,
38
49
  ) -> 'VariableManager':
39
50
  manager_args = dict(
40
51
  repo_path=repo_path,
@@ -53,45 +64,137 @@ class VariableManager:
53
64
  block_uuid: str,
54
65
  variable_uuid: str,
55
66
  data: Any,
56
- partition: str = None,
57
- variable_type: VariableType = None,
67
+ partition: Optional[str] = None,
68
+ variable_type: Optional[VariableType] = None,
58
69
  clean_block_uuid: bool = True,
59
- ) -> None:
60
- if type(data) is pd.DataFrame:
61
- variable_type = VariableType.DATAFRAME
62
- elif is_spark_dataframe(data):
63
- variable_type = VariableType.SPARK_DATAFRAME
64
- elif is_geo_dataframe(data):
65
- variable_type = VariableType.GEO_DATAFRAME
70
+ clean_variable_uuid: bool = True,
71
+ disable_variable_type_inference: bool = False,
72
+ input_data_types: Optional[List[InputDataType]] = None,
73
+ resource_usage: Optional[ResourceUsage] = None,
74
+ read_batch_settings: Optional[BatchSettings] = None,
75
+ read_chunks: Optional[List] = None,
76
+ write_batch_settings: Optional[BatchSettings] = None,
77
+ write_chunks: Optional[List] = None,
78
+ ) -> Variable:
79
+ """
80
+ Used by:
81
+ block
82
+ block/data_integration/utils
83
+ """
84
+ basic_iterable = False
85
+ if not disable_variable_type_inference:
86
+ variable_type, basic_iterable = infer_variable_type(
87
+ data,
88
+ repo_path=self.repo_path,
89
+ variable_type=variable_type,
90
+ )
91
+
66
92
  variable = Variable(
67
- clean_name(variable_uuid),
93
+ clean_name(variable_uuid) if clean_variable_uuid else variable_uuid,
68
94
  self.pipeline_path(pipeline_uuid),
69
95
  block_uuid,
96
+ clean_block_uuid=clean_block_uuid,
97
+ input_data_types=input_data_types,
70
98
  partition=partition,
99
+ read_batch_settings=read_batch_settings,
100
+ read_chunks=read_chunks,
101
+ resource_usage=resource_usage,
71
102
  storage=self.storage,
72
103
  variable_type=variable_type,
73
- clean_block_uuid=clean_block_uuid,
104
+ variables_dir=self.variables_dir,
105
+ write_batch_settings=write_batch_settings,
106
+ write_chunks=write_chunks,
74
107
  )
75
108
 
76
- # Delete data if it exists
77
- variable.delete()
78
- variable.variable_type = variable_type
79
- variable.write_data(data)
109
+ if (
110
+ write_batch_settings
111
+ and write_batch_settings.mode
112
+ and ExportWritePolicy.APPEND != write_batch_settings.mode
113
+ ):
114
+ # Delete data if it exists
115
+ variable.delete()
116
+
117
+ if (
118
+ basic_iterable
119
+ and MEMORY_MANAGER_V2
120
+ and variable_type
121
+ in [
122
+ VariableType.DATAFRAME,
123
+ VariableType.POLARS_DATAFRAME,
124
+ VariableType.SERIES_PANDAS,
125
+ VariableType.SERIES_POLARS,
126
+ ]
127
+ ):
128
+ for idx, data_nested in enumerate(DataGenerator(data)):
129
+ variable_nested = self.add_variable(
130
+ pipeline_uuid,
131
+ block_uuid,
132
+ os.path.join(str(variable_uuid), str(idx)),
133
+ data_nested,
134
+ clean_block_uuid=clean_block_uuid,
135
+ clean_variable_uuid=False,
136
+ input_data_types=input_data_types,
137
+ partition=partition,
138
+ read_batch_settings=read_batch_settings,
139
+ read_chunks=read_chunks,
140
+ resource_usage=resource_usage,
141
+ variable_type=variable_type,
142
+ write_batch_settings=write_batch_settings,
143
+ write_chunks=write_chunks,
144
+ )
145
+ if variable_nested.variable_type:
146
+ variable.variable_types.append(variable_nested.variable_type)
147
+
148
+ variable.variable_type = VariableType.ITERABLE
149
+ variable.write_metadata()
150
+ else:
151
+ variable.variable_type = variable_type
152
+ variable.write_data(data)
153
+
80
154
  if is_debug():
81
155
  print(
82
- f'Variable {variable_uuid} ({variable_type or "no type"}) for block {block_uuid} '
156
+ f'Variable {variable_uuid} ({variable_type or "no type"}) '
157
+ f'for block {block_uuid} '
83
158
  f'in pipeline {pipeline_uuid} '
84
159
  f'stored in {variable.variable_path}'
85
160
  )
86
161
 
162
+ return variable
163
+
164
+ def add_variable_types(
165
+ self,
166
+ pipeline_uuid: str,
167
+ block_uuid: str,
168
+ variable_uuid: str,
169
+ variable_types: List[VariableType],
170
+ clean_block_uuid: bool = True,
171
+ clean_variable_uuid: bool = True,
172
+ partition: Optional[str] = None,
173
+ ) -> None:
174
+ variable = self.build_variable(
175
+ pipeline_uuid,
176
+ block_uuid,
177
+ variable_uuid,
178
+ clean_block_uuid=clean_block_uuid,
179
+ clean_variable_uuid=clean_variable_uuid,
180
+ partition=partition,
181
+ variable_type=VariableType.ITERABLE,
182
+ )
183
+ variable.variable_types = variable_types
184
+ variable.write_metadata()
185
+
87
186
  def build_variable(
88
187
  self,
89
188
  pipeline_uuid: str,
90
189
  block_uuid: str,
91
190
  variable_uuid: str,
92
- partition: str = None,
93
- variable_type: VariableType = None,
191
+ partition: Optional[str] = None,
192
+ variable_type: Optional[VariableType] = None,
193
+ clean_block_uuid: bool = True,
94
194
  clean_variable_uuid: bool = True,
195
+ input_data_types: Optional[List[InputDataType]] = None,
196
+ read_batch_settings: Optional[BatchSettings] = None,
197
+ read_chunks: Optional[List] = None,
95
198
  ) -> Variable:
96
199
  return Variable(
97
200
  clean_name(variable_uuid) if clean_variable_uuid else variable_uuid,
@@ -100,6 +203,11 @@ class VariableManager:
100
203
  partition=partition,
101
204
  storage=self.storage,
102
205
  variable_type=variable_type,
206
+ clean_block_uuid=clean_block_uuid,
207
+ read_batch_settings=read_batch_settings,
208
+ read_chunks=read_chunks,
209
+ input_data_types=input_data_types,
210
+ variables_dir=self.variables_dir,
103
211
  )
104
212
 
105
213
  async def add_variable_async(
@@ -108,16 +216,26 @@ class VariableManager:
108
216
  block_uuid: str,
109
217
  variable_uuid: str,
110
218
  data: Any,
111
- partition: str = None,
112
- variable_type: VariableType = None,
219
+ partition: Optional[str] = None,
220
+ variable_type: Optional[VariableType] = None,
113
221
  clean_block_uuid: bool = True,
222
+ input_data_types: Optional[List[InputDataType]] = None,
223
+ resource_usage: Optional[ResourceUsage] = None,
224
+ read_batch_settings: Optional[BatchSettings] = None,
225
+ read_chunks: Optional[List] = None,
226
+ write_batch_settings: Optional[BatchSettings] = None,
227
+ write_chunks: Optional[List] = None,
114
228
  ) -> None:
115
- if type(data) is pd.DataFrame:
116
- variable_type = VariableType.DATAFRAME
117
- elif is_spark_dataframe(data):
118
- variable_type = VariableType.SPARK_DATAFRAME
119
- elif is_geo_dataframe(data):
120
- variable_type = VariableType.GEO_DATAFRAME
229
+ """
230
+ Used by:
231
+ block
232
+ """
233
+ variable_type, _ = infer_variable_type(
234
+ data,
235
+ repo_path=self.repo_path,
236
+ variable_type=variable_type,
237
+ )
238
+
121
239
  variable = Variable(
122
240
  clean_name(variable_uuid),
123
241
  self.pipeline_path(pipeline_uuid),
@@ -126,30 +244,43 @@ class VariableManager:
126
244
  storage=self.storage,
127
245
  variable_type=variable_type,
128
246
  clean_block_uuid=clean_block_uuid,
247
+ input_data_types=input_data_types,
248
+ resource_usage=resource_usage,
249
+ read_batch_settings=read_batch_settings,
250
+ read_chunks=read_chunks,
251
+ variables_dir=self.variables_dir,
252
+ write_batch_settings=write_batch_settings,
253
+ write_chunks=write_chunks,
129
254
  )
255
+
130
256
  # Delete data if it exists
131
257
  variable.delete()
132
258
  variable.variable_type = variable_type
133
259
  await variable.write_data_async(data)
134
260
 
135
- def clean_variables(
136
- self,
137
- pipeline_uuid: str = None
138
- ):
261
+ def clean_variables(self, pipeline_uuid: Optional[str] = None):
139
262
  from mage_ai.data_preparation.models.pipeline import Pipeline
140
263
 
141
264
  repo_config = get_repo_config()
142
- if not repo_config.variables_retention_period:
265
+ if repo_config.variables_retention_period is None:
143
266
  print('Variable retention period is not provided.')
144
267
  return
145
- min_partition = (datetime.utcnow() -
146
- str_to_timedelta(repo_config.variables_retention_period)).strftime(
147
- format='%Y%m%dT%H%M%S')
268
+
269
+ retention_ds = str_to_timedelta(repo_config.variables_retention_period)
270
+ if retention_ds is None:
271
+ return
272
+
273
+ min_partition = (datetime.utcnow() - retention_ds).strftime(format='%Y%m%dT%H%M%S')
274
+
148
275
  print(f'Clean variables before partition {min_partition}')
149
276
  if pipeline_uuid is None:
150
- pipeline_uuids = Pipeline.get_all_pipelines(self.repo_path)
277
+ pipeline_uuids = [
278
+ d[0] if isinstance(d, tuple) else d
279
+ for d in Pipeline.get_all_pipelines(self.repo_path)
280
+ ]
151
281
  else:
152
282
  pipeline_uuids = [pipeline_uuid]
283
+
153
284
  for pipeline_uuid in pipeline_uuids:
154
285
  print(f'Removing cached variables from pipeline {pipeline_uuid}')
155
286
  pipeline_variable_path = os.path.join(
@@ -177,8 +308,8 @@ class VariableManager:
177
308
  pipeline_uuid: str,
178
309
  block_uuid: str,
179
310
  variable_uuid: str,
180
- partition: str = None,
181
- variable_type: VariableType = None,
311
+ partition: Optional[str] = None,
312
+ variable_type: Optional[VariableType] = None,
182
313
  clean_block_uuid: bool = True,
183
314
  ) -> None:
184
315
  Variable(
@@ -189,6 +320,7 @@ class VariableManager:
189
320
  storage=self.storage,
190
321
  variable_type=variable_type,
191
322
  clean_block_uuid=clean_block_uuid,
323
+ variables_dir=self.variables_dir,
192
324
  ).delete()
193
325
 
194
326
  def get_variable(
@@ -196,14 +328,19 @@ class VariableManager:
196
328
  pipeline_uuid: str,
197
329
  block_uuid: str,
198
330
  variable_uuid: str,
199
- dataframe_analysis_keys: List[str] = None,
200
- partition: str = None,
201
- variable_type: VariableType = None,
331
+ dataframe_analysis_keys: Optional[List[str]] = None,
332
+ partition: Optional[str] = None,
333
+ variable_type: Optional[VariableType] = None,
202
334
  raise_exception: bool = False,
203
335
  sample: bool = False,
204
- sample_count: int = None,
205
- spark=None,
336
+ sample_count: Optional[int] = None,
337
+ spark: Optional[Any] = None,
206
338
  clean_block_uuid: bool = True,
339
+ input_data_types: Optional[List[InputDataType]] = None,
340
+ read_batch_settings: Optional[BatchSettings] = None,
341
+ read_chunks: Optional[List] = None,
342
+ write_batch_settings: Optional[BatchSettings] = None,
343
+ write_chunks: Optional[List] = None,
207
344
  ) -> Any:
208
345
  variable = self.get_variable_object(
209
346
  pipeline_uuid,
@@ -213,6 +350,11 @@ class VariableManager:
213
350
  variable_type=variable_type,
214
351
  spark=spark,
215
352
  clean_block_uuid=clean_block_uuid,
353
+ input_data_types=input_data_types,
354
+ read_batch_settings=read_batch_settings,
355
+ read_chunks=read_chunks,
356
+ write_batch_settings=write_batch_settings,
357
+ write_chunks=write_chunks,
216
358
  )
217
359
  return variable.read_data(
218
360
  dataframe_analysis_keys=dataframe_analysis_keys,
@@ -226,14 +368,29 @@ class VariableManager:
226
368
  self,
227
369
  pipeline_uuid: str,
228
370
  block_uuid: str,
229
- variable_uuid: str,
230
- partition: str = None,
231
- variable_type: VariableType = None,
371
+ variable_uuid: Optional[str] = None,
372
+ partition: Optional[str] = None,
373
+ variable_type: Optional[VariableType] = None,
374
+ variable_types: Optional[List[VariableType]] = None,
232
375
  clean_block_uuid: bool = True,
376
+ skip_check_variable_type: Optional[bool] = None,
233
377
  spark=None,
378
+ input_data_types: Optional[List[InputDataType]] = None,
379
+ read_batch_settings: Optional[BatchSettings] = None,
380
+ read_chunks: Optional[List] = None,
381
+ write_batch_settings: Optional[BatchSettings] = None,
382
+ write_chunks: Optional[List] = None,
234
383
  ) -> Variable:
235
384
  if variable_type == VariableType.DATAFRAME and spark is not None:
236
385
  variable_type = VariableType.SPARK_DATAFRAME
386
+
387
+ if not variable_uuid:
388
+ variable_uuid = get_first_data_output_variable_uuid(
389
+ self.get_variables_by_block(pipeline_uuid, block_uuid, partition=partition)
390
+ )
391
+ if not variable_uuid:
392
+ variable_uuid = 'output_0'
393
+
237
394
  return Variable(
238
395
  variable_uuid,
239
396
  self.pipeline_path(pipeline_uuid),
@@ -242,11 +399,20 @@ class VariableManager:
242
399
  spark=spark,
243
400
  storage=self.storage,
244
401
  variable_type=variable_type,
402
+ variable_types=variable_types,
245
403
  clean_block_uuid=clean_block_uuid,
404
+ input_data_types=input_data_types,
405
+ read_batch_settings=read_batch_settings,
406
+ read_chunks=read_chunks,
407
+ skip_check_variable_type=skip_check_variable_type,
408
+ variables_dir=self.variables_dir,
409
+ write_batch_settings=write_batch_settings,
410
+ write_chunks=write_chunks,
246
411
  )
247
412
 
248
413
  def get_variables_by_pipeline(self, pipeline_uuid: str) -> Dict[str, List[str]]:
249
414
  from mage_ai.data_preparation.models.pipeline import Pipeline
415
+
250
416
  pipeline = Pipeline.get(pipeline_uuid, repo_path=self.repo_path)
251
417
  variable_dir_path = os.path.join(self.pipeline_path(pipeline_uuid), VARIABLE_DIR)
252
418
  if not self.storage.path_exists(variable_dir_path):
@@ -269,9 +435,10 @@ class VariableManager:
269
435
  self,
270
436
  pipeline_uuid: str,
271
437
  block_uuid: str,
272
- partition: str = None,
438
+ partition: Optional[str] = None,
273
439
  clean_block_uuid: bool = True,
274
- max_results: int = None,
440
+ max_results: Optional[int] = None,
441
+ output_variable_only: Optional[bool] = None,
275
442
  ) -> List[str]:
276
443
  variable_dir_path = os.path.join(
277
444
  self.pipeline_path(pipeline_uuid),
@@ -281,8 +448,29 @@ class VariableManager:
281
448
  )
282
449
  if not self.storage.path_exists(variable_dir_path):
283
450
  return []
284
- variables = self.storage.listdir(variable_dir_path, max_results=max_results)
285
- return sorted([v.split('.')[0] for v in variables])
451
+
452
+ opts = {}
453
+ if max_results is not None:
454
+ opts['max_results'] = max_results
455
+
456
+ variable_uuids = self.storage.listdir(variable_dir_path, **opts)
457
+ variable_uuids = [
458
+ v
459
+ for v in variable_uuids
460
+ if v.split('.')[0] and (not output_variable_only or is_output_variable(v))
461
+ ]
462
+
463
+ def __sort_variables(text):
464
+ number = re.findall('\\d+', text)
465
+ if number:
466
+ if len(number) == 1:
467
+ number.append(0)
468
+ number = number[:2]
469
+ else:
470
+ number = to_ordinal_integers(text)[:2]
471
+ return [int(i) for i in number]
472
+
473
+ return sorted(variable_uuids, key=__sort_variables)
286
474
 
287
475
  def pipeline_path(self, pipeline_uuid: str) -> str:
288
476
  path = os.path.join(self.variables_dir, 'pipelines', pipeline_uuid)
@@ -308,9 +496,7 @@ class GCSVariableManager(VariableManager):
308
496
  self.storage = GCSStorage(dirpath=variables_dir)
309
497
 
310
498
 
311
- def clean_variables(
312
- pipeline_uuid: str = None
313
- ):
499
+ def clean_variables(pipeline_uuid: str = None):
314
500
  variables_dir = get_variables_dir()
315
501
  VariableManager(variables_dir=variables_dir).clean_variables(pipeline_uuid=pipeline_uuid)
316
502
 
@@ -318,24 +504,39 @@ def clean_variables(
318
504
  def get_global_variables(
319
505
  pipeline_uuid: str,
320
506
  pipeline=None,
507
+ context_data: Dict = None,
508
+ repo_path: str = None,
509
+ variables_dir: str = None,
321
510
  ) -> Dict[str, Any]:
322
511
  """
323
512
  Get all global variables. Global variables are stored together with project's code.
324
513
  """
325
514
  from mage_ai.data_preparation.models.pipeline import Pipeline
326
515
 
327
- pipeline = pipeline or Pipeline.get(pipeline_uuid, all_projects=project_platform_activated())
516
+ pipeline = pipeline or Pipeline.get(
517
+ pipeline_uuid,
518
+ all_projects=project_platform_activated(),
519
+ context_data=context_data,
520
+ repo_path=repo_path,
521
+ )
328
522
  if pipeline.variables is not None:
329
523
  global_variables = pipeline.variables
330
524
  else:
331
- variables_dir = get_variables_dir()
332
- variables = VariableManager(variables_dir=variables_dir).get_variables_by_block(
525
+ variables_dir = variables_dir or get_variables_dir(repo_path=repo_path)
526
+ variable_manager = VariableManager(
527
+ repo_path=repo_path, variables_dir=variables_dir
528
+ )
529
+ variables = variable_manager.get_variables_by_block(
333
530
  pipeline_uuid,
334
531
  'global',
335
532
  )
336
533
  global_variables = dict()
337
534
  for variable in variables:
338
- global_variables[variable] = get_global_variable(pipeline_uuid, variable)
535
+ global_variables[variable] = variable_manager.get_variable(
536
+ pipeline_uuid,
537
+ 'global',
538
+ variable,
539
+ )
339
540
 
340
541
  return global_variables
341
542
 
@@ -349,7 +550,10 @@ def get_global_variable(
349
550
  """
350
551
  from mage_ai.data_preparation.models.pipeline import Pipeline
351
552
 
352
- pipeline = Pipeline.get(pipeline_uuid, all_projects=project_platform_activated())
553
+ pipeline = Pipeline.get(
554
+ pipeline_uuid,
555
+ all_projects=project_platform_activated(),
556
+ )
353
557
  if pipeline.variables is not None:
354
558
  return pipeline.variables.get(key)
355
559
  else:
@@ -360,12 +564,7 @@ def get_global_variable(
360
564
  )
361
565
 
362
566
 
363
- def get_variable(
364
- pipeline_uuid: str,
365
- block_uuid: str,
366
- key: str,
367
- **kwargs
368
- ) -> Any:
567
+ def get_variable(pipeline_uuid: str, block_uuid: str, key: str, **kwargs) -> Any:
369
568
  """
370
569
  Set block intermediate variable by key.
371
570
  Block intermediate variables are stored in variables dir.
@@ -382,12 +581,15 @@ def set_global_variable(
382
581
  pipeline_uuid: str,
383
582
  key: str,
384
583
  value: Any,
584
+ repo_path: str = None,
385
585
  ) -> None:
386
586
  """
387
587
  Set global variable by key. Global variables are stored together with project's code.
388
588
  """
389
589
  from mage_ai.data_preparation.models.pipeline import Pipeline
590
+
390
591
  pipeline = Pipeline.get(pipeline_uuid)
592
+ pipeline = Pipeline.get(pipeline_uuid, repo_path=repo_path)
391
593
 
392
594
  if pipeline.variables is None:
393
595
  pipeline.variables = get_global_variables(pipeline_uuid)
@@ -397,12 +599,15 @@ def set_global_variable(
397
599
  def delete_global_variable(
398
600
  pipeline_uuid: str,
399
601
  key: str,
602
+ repo_path: str = None,
400
603
  ) -> None:
401
604
  """
402
605
  Delete global variable by key. Global variables are stored together with project's code.
403
606
  """
404
607
  from mage_ai.data_preparation.models.pipeline import Pipeline
608
+
405
609
  pipeline = Pipeline.get(pipeline_uuid)
610
+ pipeline = Pipeline.get(pipeline_uuid, repo_path=repo_path)
406
611
  if pipeline.variables is not None:
407
612
  pipeline.delete_global_variable(key)
408
613
  else:
mage_ai/io/base.py CHANGED
@@ -8,6 +8,7 @@ from pandas import DataFrame
8
8
 
9
9
  from mage_ai.io.constants import SQL_RESERVED_WORDS
10
10
  from mage_ai.shared.logger import VerbosePrintHandler
11
+ from mage_ai.shared.models import BaseEnum
11
12
  from mage_ai.shared.utils import clean_name
12
13
 
13
14
  QUERY_ROW_LIMIT = 10_000_000
@@ -47,7 +48,7 @@ class FileFormat(str, Enum):
47
48
  XML = 'xml'
48
49
 
49
50
 
50
- class ExportWritePolicy(str, Enum):
51
+ class ExportWritePolicy(BaseEnum):
51
52
  APPEND = 'append'
52
53
  FAIL = 'fail'
53
54
  REPLACE = 'replace'
@@ -150,7 +151,7 @@ class BaseFile(BaseIO):
150
151
  elif format == FileFormat.XML:
151
152
  return pd.read_xml
152
153
  else:
153
- raise ValueError(f'Invalid format \'{format}\' specified.')
154
+ raise ValueError(f"Invalid format '{format}' specified.")
154
155
 
155
156
  def _read(
156
157
  self,
mage_ai/io/bigquery.py CHANGED
@@ -242,6 +242,7 @@ WHERE TABLE_NAME = '{table_name}'
242
242
  elif len(parts) == 3:
243
243
  database, schema, table_name = parts
244
244
 
245
+ database = database or self.default_database()
245
246
  df_existing = self.client.query(f"""
246
247
  SELECT 1
247
248
  FROM `{database}.{schema}.__TABLES_SUMMARY__`
mage_ai/io/redshift.py CHANGED
@@ -239,12 +239,14 @@ class Redshift(BaseSQL):
239
239
  col_with_types = ', '.join(col_with_types)
240
240
  query = f'CREATE TABLE IF NOT EXISTS {full_table_name} ({col_with_types})'
241
241
  cur.execute(query)
242
+ if df.shape[0] > 0:
243
+ columns = ', '.join([t[0] for t in columns_with_type])
244
+ values = [f"""({', '.join([format_value(x) for x in v])})"""
245
+ for v in df.values]
246
+ values = ', '.join(values)
247
+ query = f'INSERT INTO {full_table_name} ({columns})\nVALUES {values}'
242
248
 
243
- columns = ', '.join([t[0] for t in columns_with_type])
244
- values = [f"""({', '.join([format_value(x) for x in v])})""" for v in df.values]
245
- values = ', '.join(values)
246
- query = f'INSERT INTO {full_table_name} ({columns})\nVALUES {values}'
247
- cur.execute(query)
249
+ cur.execute(query)
248
250
 
249
251
  self.conn.commit()
250
252
 
File without changes