mage-ai 0.9.57__py3-none-any.whl → 0.9.59__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 (696) hide show
  1. mage_ai/ai/constants.py +1 -0
  2. mage_ai/ai/generator.py +7 -0
  3. mage_ai/ai/llm_pipeline_wizard.py +13 -0
  4. mage_ai/ai/openai_client.py +9 -1
  5. mage_ai/api/logging.py +11 -7
  6. mage_ai/api/policies/BlockPolicy.py +1 -0
  7. mage_ai/api/policies/CacheItemPolicy.py +16 -3
  8. mage_ai/api/policies/CommandCenterItemPolicy.py +56 -0
  9. mage_ai/api/policies/CustomTemplatePolicy.py +0 -3
  10. mage_ai/api/policies/GitBranchPolicy.py +8 -1
  11. mage_ai/api/policies/GitFilePolicy.py +1 -0
  12. mage_ai/api/policies/PipelinePolicy.py +2 -0
  13. mage_ai/api/policies/PipelineSchedulePolicy.py +1 -0
  14. mage_ai/api/policies/VersionControlBranchPolicy.py +98 -0
  15. mage_ai/api/policies/VersionControlFilePolicy.py +96 -0
  16. mage_ai/api/policies/VersionControlProjectPolicy.py +92 -0
  17. mage_ai/api/policies/VersionControlRemotePolicy.py +94 -0
  18. mage_ai/api/presenters/CommandCenterItemPresenter.py +19 -0
  19. mage_ai/api/presenters/GitBranchPresenter.py +2 -0
  20. mage_ai/api/presenters/GitCustomBranchPresenter.py +1 -0
  21. mage_ai/api/presenters/PipelinePresenter.py +5 -5
  22. mage_ai/api/presenters/PipelineSchedulePresenter.py +4 -0
  23. mage_ai/api/presenters/VersionControlBranchPresenter.py +15 -0
  24. mage_ai/api/presenters/VersionControlFilePresenter.py +15 -0
  25. mage_ai/api/presenters/VersionControlProjectPresenter.py +14 -0
  26. mage_ai/api/presenters/VersionControlRemotePresenter.py +15 -0
  27. mage_ai/api/resources/BlockResource.py +110 -80
  28. mage_ai/api/resources/CacheItemResource.py +88 -0
  29. mage_ai/api/resources/CommandCenterItemResource.py +29 -0
  30. mage_ai/api/resources/FileResource.py +15 -1
  31. mage_ai/api/resources/FolderResource.py +2 -1
  32. mage_ai/api/resources/GitBranchResource.py +183 -108
  33. mage_ai/api/resources/GitCustomBranchResource.py +9 -2
  34. mage_ai/api/resources/GitFileResource.py +26 -13
  35. mage_ai/api/resources/KernelResource.py +9 -1
  36. mage_ai/api/resources/LogResource.py +1 -1
  37. mage_ai/api/resources/OauthResource.py +4 -5
  38. mage_ai/api/resources/PipelineResource.py +71 -38
  39. mage_ai/api/resources/PipelineRunResource.py +7 -2
  40. mage_ai/api/resources/ProjectResource.py +1 -2
  41. mage_ai/api/resources/PullRequestResource.py +12 -3
  42. mage_ai/api/resources/SearchResultResource.py +4 -4
  43. mage_ai/api/resources/VersionControlBranchResource.py +85 -0
  44. mage_ai/api/resources/VersionControlFileResource.py +65 -0
  45. mage_ai/api/resources/VersionControlProjectResource.py +46 -0
  46. mage_ai/api/resources/VersionControlRemoteResource.py +64 -0
  47. mage_ai/authentication/oauth/constants.py +13 -16
  48. mage_ai/authentication/operation_history/models.py +11 -32
  49. mage_ai/authentication/operation_history/utils.py +14 -14
  50. mage_ai/authentication/permissions/constants.py +5 -0
  51. mage_ai/authentication/providers/active_directory.py +2 -2
  52. mage_ai/authentication/providers/bitbucket.py +2 -2
  53. mage_ai/authentication/providers/constants.py +6 -12
  54. mage_ai/authentication/providers/ghe.py +2 -2
  55. mage_ai/authentication/providers/google.py +2 -2
  56. mage_ai/authentication/providers/okta.py +2 -2
  57. mage_ai/cache/base.py +11 -3
  58. mage_ai/cache/block.py +116 -32
  59. mage_ai/cache/block_action_object/__init__.py +52 -43
  60. mage_ai/cache/constants.py +1 -0
  61. mage_ai/cache/dbt/utils.py +31 -10
  62. mage_ai/cache/file.py +114 -0
  63. mage_ai/cache/models.py +2 -0
  64. mage_ai/cache/pipeline.py +34 -8
  65. mage_ai/cache/tag.py +51 -10
  66. mage_ai/cache/utils.py +44 -3
  67. mage_ai/cluster_manager/kubernetes/workload_manager.py +9 -1
  68. mage_ai/command_center/__init__.py +0 -0
  69. mage_ai/command_center/applications/__init__.py +0 -0
  70. mage_ai/command_center/applications/constants.py +96 -0
  71. mage_ai/command_center/applications/factory.py +54 -0
  72. mage_ai/command_center/blocks/__init__.py +0 -0
  73. mage_ai/command_center/blocks/factory.py +39 -0
  74. mage_ai/command_center/blocks/utils.py +127 -0
  75. mage_ai/command_center/constants.py +66 -0
  76. mage_ai/command_center/factory.py +161 -0
  77. mage_ai/command_center/files/__init__.py +0 -0
  78. mage_ai/command_center/files/constants.py +235 -0
  79. mage_ai/command_center/files/factory.py +86 -0
  80. mage_ai/command_center/models.py +442 -0
  81. mage_ai/command_center/pipeline_runs/__init__.py +0 -0
  82. mage_ai/command_center/pipeline_runs/utils.py +141 -0
  83. mage_ai/command_center/pipelines/__init__.py +0 -0
  84. mage_ai/command_center/pipelines/constants.py +118 -0
  85. mage_ai/command_center/pipelines/factory.py +132 -0
  86. mage_ai/command_center/pipelines/utils.py +120 -0
  87. mage_ai/command_center/service.py +45 -0
  88. mage_ai/command_center/settings.py +37 -0
  89. mage_ai/command_center/support/__init__.py +0 -0
  90. mage_ai/command_center/support/constants.py +46 -0
  91. mage_ai/command_center/triggers/__init__.py +0 -0
  92. mage_ai/command_center/triggers/factory.py +49 -0
  93. mage_ai/command_center/triggers/utils.py +463 -0
  94. mage_ai/command_center/utils.py +30 -0
  95. mage_ai/data_preparation/executors/azure_container_instance_executor.py +1 -1
  96. mage_ai/data_preparation/executors/block_executor.py +68 -19
  97. mage_ai/data_preparation/executors/ecs_block_executor.py +2 -2
  98. mage_ai/data_preparation/executors/executor_factory.py +2 -0
  99. mage_ai/data_preparation/executors/gcp_cloud_run_block_executor.py +1 -1
  100. mage_ai/data_preparation/executors/k8s_block_executor.py +2 -2
  101. mage_ai/data_preparation/executors/pyspark_block_executor.py +7 -1
  102. mage_ai/data_preparation/git/__init__.py +29 -11
  103. mage_ai/data_preparation/git/api.py +14 -13
  104. mage_ai/data_preparation/git/clients/base.py +4 -8
  105. mage_ai/data_preparation/git/clients/github.py +1 -0
  106. mage_ai/data_preparation/git/utils.py +5 -7
  107. mage_ai/data_preparation/models/block/__init__.py +556 -329
  108. mage_ai/data_preparation/models/block/content.py +111 -0
  109. mage_ai/data_preparation/models/block/data_integration/mixins.py +1 -0
  110. mage_ai/data_preparation/models/block/dbt/block.py +30 -20
  111. mage_ai/data_preparation/models/block/dbt/block_sql.py +93 -257
  112. mage_ai/data_preparation/models/block/dbt/block_yaml.py +81 -158
  113. mage_ai/data_preparation/models/block/dbt/constants.py +12 -0
  114. mage_ai/data_preparation/models/block/dbt/dbt_adapter.py +23 -10
  115. mage_ai/data_preparation/models/block/dbt/dbt_cli.py +124 -612
  116. mage_ai/data_preparation/models/block/dbt/profiles.py +19 -15
  117. mage_ai/data_preparation/models/block/dbt/project.py +3 -0
  118. mage_ai/data_preparation/models/block/dynamic/constants.py +0 -0
  119. mage_ai/data_preparation/models/block/dynamic/dynamic_child.py +507 -47
  120. mage_ai/data_preparation/models/block/dynamic/utils.py +432 -1
  121. mage_ai/data_preparation/models/block/platform/mixins.py +68 -44
  122. mage_ai/data_preparation/models/block/r/__init__.py +19 -9
  123. mage_ai/data_preparation/models/block/sql/__init__.py +33 -18
  124. mage_ai/data_preparation/models/block/sql/utils/shared.py +4 -1
  125. mage_ai/data_preparation/models/block/utils.py +176 -71
  126. mage_ai/data_preparation/models/constants.py +7 -0
  127. mage_ai/data_preparation/models/file.py +23 -4
  128. mage_ai/data_preparation/models/pipeline.py +20 -8
  129. mage_ai/data_preparation/models/project/__init__.py +12 -7
  130. mage_ai/data_preparation/models/project/constants.py +2 -0
  131. mage_ai/data_preparation/models/triggers/__init__.py +7 -0
  132. mage_ai/data_preparation/models/utils.py +20 -0
  133. mage_ai/data_preparation/models/variable.py +113 -15
  134. mage_ai/data_preparation/shared/utils.py +6 -3
  135. mage_ai/data_preparation/storage/base_storage.py +17 -0
  136. mage_ai/data_preparation/storage/gcs_storage.py +4 -0
  137. mage_ai/data_preparation/storage/local_storage.py +15 -0
  138. mage_ai/data_preparation/storage/s3_storage.py +4 -0
  139. mage_ai/data_preparation/templates/data_exporters/qdrant.py +0 -1
  140. mage_ai/data_preparation/templates/data_loaders/qdrant.py +2 -1
  141. mage_ai/data_preparation/variable_manager.py +1 -0
  142. mage_ai/io/base.py +4 -1
  143. mage_ai/io/bigquery.py +25 -16
  144. mage_ai/io/clickhouse.py +3 -0
  145. mage_ai/io/druid.py +3 -0
  146. mage_ai/io/mongodb.py +1 -1
  147. mage_ai/io/pinot.py +3 -0
  148. mage_ai/io/postgres.py +13 -0
  149. mage_ai/io/snowflake.py +4 -0
  150. mage_ai/io/spark.py +8 -3
  151. mage_ai/io/sql.py +6 -0
  152. mage_ai/orchestration/db/__init__.py +26 -19
  153. mage_ai/orchestration/db/cache.py +4 -3
  154. mage_ai/orchestration/db/models/schedules.py +72 -16
  155. mage_ai/orchestration/db/models/schedules_project_platform.py +2 -3
  156. mage_ai/orchestration/pipeline_scheduler_original.py +19 -11
  157. mage_ai/orchestration/pipeline_scheduler_project_platform.py +20 -11
  158. mage_ai/presenters/interactions/constants.py +1 -0
  159. mage_ai/presenters/interactions/models.py +4 -3
  160. mage_ai/presenters/pages/models/client_pages/pipeline_schedules.py +1 -1
  161. mage_ai/server/constants.py +1 -1
  162. mage_ai/server/frontend_dist/404.html +11 -11
  163. mage_ai/server/frontend_dist/_next/static/PPQxHOmWVJ0iQFzG2rc8m/_buildManifest.js +1 -0
  164. mage_ai/server/frontend_dist/_next/static/chunks/1235.c9ed47779baccc05.js +1 -0
  165. mage_ai/server/frontend_dist/_next/static/chunks/125-029194ff22eb33a5.js +1 -0
  166. mage_ai/server/frontend_dist/_next/static/chunks/1557-4f7485c2e2228f77.js +1 -0
  167. mage_ai/server/frontend_dist/_next/static/chunks/2474-8e702cea23ddd16d.js +1 -0
  168. mage_ai/server/frontend_dist/_next/static/chunks/2479-727fa69ee9be6fab.js +1 -0
  169. mage_ai/server/frontend_dist/_next/static/chunks/26-38bc9380422f3900.js +1 -0
  170. mage_ai/server/frontend_dist/_next/static/chunks/2717-3e7ea8543b3825b7.js +1 -0
  171. mage_ai/server/frontend_dist/_next/static/chunks/3366-420721116ea5a665.js +1 -0
  172. mage_ai/server/frontend_dist/_next/static/chunks/3449-a9c98239582cd6f0.js +1 -0
  173. mage_ai/server/frontend_dist/_next/static/chunks/3548-13563a1ff815f922.js +1 -0
  174. mage_ai/server/frontend_dist/_next/static/chunks/3943-9e0a8ba0db34b35f.js +1 -0
  175. mage_ai/server/frontend_dist/_next/static/chunks/4371-ef23f95888d6cd11.js +1 -0
  176. mage_ai/server/frontend_dist/_next/static/chunks/4632.a4171dbf46b31c7c.js +1 -0
  177. mage_ai/server/frontend_dist/_next/static/chunks/523-be11ad59861d00ca.js +1 -0
  178. mage_ai/server/frontend_dist/_next/static/chunks/5457-d582b00545b4cb5e.js +1 -0
  179. mage_ai/server/frontend_dist/_next/static/chunks/{5189.dca121eccea793be.js → 5729.0f2748e9e6dab951.js} +1 -1
  180. mage_ai/server/frontend_dist/_next/static/chunks/5831-2abc4063e887a03e.js +1 -0
  181. mage_ai/server/frontend_dist/_next/static/chunks/6085-692d2f784c0504f2.js +1 -0
  182. mage_ai/server/frontend_dist/_next/static/chunks/635-1e8857c2b6dde289.js +1 -0
  183. mage_ai/server/frontend_dist/_next/static/chunks/7022-0d52dd8868621fb0.js +1 -0
  184. mage_ai/server/frontend_dist/_next/static/chunks/7264-d05f4b7088533f6f.js +1 -0
  185. mage_ai/server/frontend_dist/_next/static/chunks/7361-b3d661ec743bfadf.js +1 -0
  186. mage_ai/server/frontend_dist/_next/static/chunks/737-cc6467310a130dd9.js +1 -0
  187. mage_ai/server/frontend_dist/_next/static/chunks/{4495-4f0340aa82e0c623.js → 7674-9ec4fe64b5bf64d5.js} +1 -1
  188. mage_ai/server/frontend_dist/_next/static/chunks/8038-85d715c8c8394827.js +1 -0
  189. mage_ai/server/frontend_dist/_next/static/chunks/8095-bdce03896ef9639a.js +1 -0
  190. mage_ai/server/frontend_dist/_next/static/chunks/8146-6bed4e7401e067e6.js +1 -0
  191. mage_ai/server/frontend_dist/_next/static/chunks/8192-0c0b91523a38c4ca.js +1 -0
  192. mage_ai/server/frontend_dist/_next/static/chunks/8432-f736d101fc6d9215.js +1 -0
  193. mage_ai/server/frontend_dist/_next/static/chunks/8513-d207733b485c8d03.js +1 -0
  194. mage_ai/server/frontend_dist/_next/static/chunks/9264-7cd9cd0ba86ec5e4.js +1 -0
  195. mage_ai/server/frontend_dist/_next/static/chunks/9265-d2a1aaec75ec69b8.js +1 -0
  196. mage_ai/server/frontend_dist/_next/static/chunks/9440-54add041c392517f.js +1 -0
  197. mage_ai/server/frontend_dist/_next/static/chunks/9624-59b2f803f9c88cd6.js +1 -0
  198. mage_ai/server/frontend_dist/_next/static/chunks/9832-67896490f6e8a014.js +1 -0
  199. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/bd1a647f.fe5d87096be24a62.js → frontend_dist/_next/static/chunks/bd1a647f.04f7913662092327.js} +1 -1
  200. mage_ai/server/frontend_dist/_next/static/chunks/pages/404-7cabe357906f44f2.js +1 -0
  201. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-a11bd2ebe11b3fd2.js +1 -0
  202. mage_ai/server/frontend_dist/_next/static/chunks/pages/block-layout-ffca51945cd154ef.js +1 -0
  203. mage_ai/server/frontend_dist/_next/static/chunks/pages/compute-3ba957769292db80.js +1 -0
  204. mage_ai/server/frontend_dist/_next/static/chunks/pages/files-45679fd18b3edd82.js +1 -0
  205. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-95735a218106aa99.js +1 -0
  206. mage_ai/server/frontend_dist/_next/static/chunks/pages/{global-data-products-927ebbdc29529765.js → global-data-products-81d6c7fd9a9cff38.js} +1 -1
  207. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-eb4421d51fb7368f.js +1 -0
  208. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks-a8c712e20512fede.js +1 -0
  209. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/files-f1be1d4735ba6919.js +1 -0
  210. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-febe676687966276.js +1 -0
  211. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/[user]-70efe222130490b5.js +1 -0
  212. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-0914c36b3c8fd59f.js +1 -0
  213. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users-4f12e989e7809ef9.js +1 -0
  214. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-809d4c99b44991a1.js +1 -0
  215. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/oauth-bd8494f8875c5c97.js → frontend_dist/_next/static/chunks/pages/oauth-aa9079c8dbaea3a5.js} +1 -1
  216. mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-4e30fb5b18383b71.js +1 -0
  217. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipeline-runs-5d31c3aace39182d.js +1 -0
  218. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-85a80ee66f60a65c.js +1 -0
  219. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-0bd74047e257e6d9.js +1 -0
  220. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-80619dc504d0103b.js +1 -0
  221. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-3cc8d74ff8525bfd.js +1 -0
  222. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-cdc379ff24ff8858.js +1 -0
  223. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-03396d6086003e16.js +1 -0
  224. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-d6d920758654f6d9.js +1 -0
  225. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-27727bb87be506c3.js +1 -0
  226. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-16aab67743651a0b.js +1 -0
  227. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-e3ca1bedb660b252.js +1 -0
  228. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-9d58701fe7213727.js +1 -0
  229. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-0041fd76ee15e49f.js +1 -0
  230. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-780be9a2da697915.js +1 -0
  231. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-db8bb970b1f2273f.js +1 -0
  232. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-a3422b0ab1dbacd7.js +1 -0
  233. mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks/[...slug]-987a1603f4201943.js +1 -0
  234. mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks-3dc8bf89cab2722b.js +1 -0
  235. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-43d3f2a5071b9537.js +1 -0
  236. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-c97b1a39b22c112a.js +1 -0
  237. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/settings-49efb66da67554ca.js +1 -0
  238. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-aa5d871de1f3f7b0.js → [...slug]-5117d3555972484c.js} +1 -1
  239. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions-ee1c19d4a192ae4d.js +1 -0
  240. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-4dc5724486ee3396.js +1 -0
  241. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-88d29d1774db67e4.js → [...slug]-fa095aac732368c3.js} +1 -1
  242. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{roles-d8ca763e405cd9d1.js → roles-db6d71f8692a33e7.js} +1 -1
  243. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-99c6a263d2ab9553.js +1 -0
  244. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-250dfdf22bfe67e9.js → [...slug]-9d881ac0a3db9baa.js} +1 -1
  245. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users-bee414d57c4b55d7.js +1 -0
  246. mage_ai/server/frontend_dist/_next/static/chunks/pages/sign-in-e7030e1a7a9e88e1.js +1 -0
  247. mage_ai/server/frontend_dist/_next/static/chunks/pages/templates/[...slug]-312afc9a3f8d0a4f.js +1 -0
  248. mage_ai/server/frontend_dist/_next/static/chunks/pages/templates-e5300c340aa94c6b.js +1 -0
  249. mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-fa7ca0c86142d146.js +1 -0
  250. mage_ai/server/frontend_dist/_next/static/chunks/pages/test-bd51b3918b39329e.js +1 -0
  251. mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-5158a9d98d2459e8.js +1 -0
  252. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-5ce099a7abb354ff.js +1 -0
  253. mage_ai/server/frontend_dist/_next/static/chunks/{webpack-17c3a8f588f14cfd.js → webpack-efa55343114c8128.js} +1 -1
  254. mage_ai/server/{frontend_dist_base_path_template/_next/static/css/d1e8e64d0b07af2f.css → frontend_dist/_next/static/css/b59541b123fd7191.css} +1 -1
  255. mage_ai/server/frontend_dist/block-layout.html +3 -3
  256. mage_ai/server/frontend_dist/compute.html +11 -11
  257. mage_ai/server/frontend_dist/files.html +11 -11
  258. mage_ai/server/frontend_dist/global-data-products/[...slug].html +11 -11
  259. mage_ai/server/frontend_dist/global-data-products.html +11 -11
  260. mage_ai/server/frontend_dist/global-hooks/[...slug].html +11 -11
  261. mage_ai/server/frontend_dist/global-hooks.html +11 -11
  262. mage_ai/server/frontend_dist/index.html +3 -3
  263. mage_ai/server/frontend_dist/manage/files.html +11 -11
  264. mage_ai/server/frontend_dist/manage/settings.html +11 -11
  265. mage_ai/server/frontend_dist/manage/users/[user].html +11 -11
  266. mage_ai/server/frontend_dist/manage/users/new.html +11 -11
  267. mage_ai/server/frontend_dist/manage/users.html +11 -11
  268. mage_ai/server/frontend_dist/manage.html +11 -11
  269. mage_ai/server/frontend_dist/oauth.html +8 -8
  270. mage_ai/server/frontend_dist/overview.html +11 -11
  271. mage_ai/server/frontend_dist/pipeline-runs.html +11 -11
  272. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +11 -11
  273. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +11 -11
  274. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +11 -11
  275. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +3 -3
  276. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +11 -11
  277. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +11 -11
  278. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +11 -11
  279. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +11 -11
  280. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +11 -11
  281. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +11 -11
  282. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +11 -11
  283. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +11 -11
  284. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +11 -11
  285. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +11 -11
  286. mage_ai/server/frontend_dist/pipelines/[pipeline].html +3 -3
  287. mage_ai/server/frontend_dist/pipelines.html +11 -11
  288. mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +11 -11
  289. mage_ai/server/frontend_dist/platform/global-hooks.html +11 -11
  290. mage_ai/server/frontend_dist/settings/account/profile.html +11 -11
  291. mage_ai/server/frontend_dist/settings/platform/preferences.html +11 -11
  292. mage_ai/server/frontend_dist/settings/platform/settings.html +11 -11
  293. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +11 -11
  294. mage_ai/server/frontend_dist/settings/workspace/permissions.html +11 -11
  295. mage_ai/server/frontend_dist/settings/workspace/preferences.html +11 -11
  296. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +11 -11
  297. mage_ai/server/frontend_dist/settings/workspace/roles.html +11 -11
  298. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +11 -11
  299. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +11 -11
  300. mage_ai/server/frontend_dist/settings/workspace/users.html +11 -11
  301. mage_ai/server/frontend_dist/settings.html +3 -3
  302. mage_ai/server/frontend_dist/sign-in.html +40 -41
  303. mage_ai/server/frontend_dist/templates/[...slug].html +11 -11
  304. mage_ai/server/frontend_dist/templates.html +11 -11
  305. mage_ai/server/frontend_dist/terminal.html +11 -11
  306. mage_ai/server/frontend_dist/test.html +3 -3
  307. mage_ai/server/frontend_dist/triggers.html +11 -11
  308. mage_ai/server/frontend_dist/version-control.html +11 -11
  309. mage_ai/server/frontend_dist_base_path_template/404.html +11 -11
  310. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1235.c9ed47779baccc05.js +1 -0
  311. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/125-029194ff22eb33a5.js +1 -0
  312. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-4f7485c2e2228f77.js +1 -0
  313. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2474-8e702cea23ddd16d.js +1 -0
  314. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2479-727fa69ee9be6fab.js +1 -0
  315. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/26-38bc9380422f3900.js +1 -0
  316. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2717-3e7ea8543b3825b7.js +1 -0
  317. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3366-420721116ea5a665.js +1 -0
  318. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3449-a9c98239582cd6f0.js +1 -0
  319. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3548-13563a1ff815f922.js +1 -0
  320. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3943-9e0a8ba0db34b35f.js +1 -0
  321. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4371-ef23f95888d6cd11.js +1 -0
  322. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4632.a4171dbf46b31c7c.js +1 -0
  323. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/523-be11ad59861d00ca.js +1 -0
  324. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-d582b00545b4cb5e.js +1 -0
  325. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{5189.dca121eccea793be.js → 5729.0f2748e9e6dab951.js} +1 -1
  326. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5831-2abc4063e887a03e.js +1 -0
  327. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6085-692d2f784c0504f2.js +1 -0
  328. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/635-1e8857c2b6dde289.js +1 -0
  329. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-0d52dd8868621fb0.js +1 -0
  330. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7264-d05f4b7088533f6f.js +1 -0
  331. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-b3d661ec743bfadf.js +1 -0
  332. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/737-cc6467310a130dd9.js +1 -0
  333. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{4495-4f0340aa82e0c623.js → 7674-9ec4fe64b5bf64d5.js} +1 -1
  334. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8038-85d715c8c8394827.js +1 -0
  335. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-bdce03896ef9639a.js +1 -0
  336. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-6bed4e7401e067e6.js +1 -0
  337. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8192-0c0b91523a38c4ca.js +1 -0
  338. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8432-f736d101fc6d9215.js +1 -0
  339. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8513-d207733b485c8d03.js +1 -0
  340. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9264-7cd9cd0ba86ec5e4.js +1 -0
  341. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9265-d2a1aaec75ec69b8.js +1 -0
  342. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-54add041c392517f.js +1 -0
  343. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9624-59b2f803f9c88cd6.js +1 -0
  344. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9832-67896490f6e8a014.js +1 -0
  345. mage_ai/server/{frontend_dist/_next/static/chunks/bd1a647f.fe5d87096be24a62.js → frontend_dist_base_path_template/_next/static/chunks/bd1a647f.04f7913662092327.js} +1 -1
  346. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/404-7cabe357906f44f2.js +1 -0
  347. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-a11bd2ebe11b3fd2.js +1 -0
  348. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/block-layout-ffca51945cd154ef.js +1 -0
  349. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/compute-3ba957769292db80.js +1 -0
  350. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-45679fd18b3edd82.js +1 -0
  351. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-95735a218106aa99.js +1 -0
  352. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{global-data-products-927ebbdc29529765.js → global-data-products-81d6c7fd9a9cff38.js} +1 -1
  353. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-eb4421d51fb7368f.js +1 -0
  354. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks-a8c712e20512fede.js +1 -0
  355. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/files-f1be1d4735ba6919.js +1 -0
  356. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-febe676687966276.js +1 -0
  357. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-70efe222130490b5.js +1 -0
  358. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-0914c36b3c8fd59f.js +1 -0
  359. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users-4f12e989e7809ef9.js +1 -0
  360. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-809d4c99b44991a1.js +1 -0
  361. mage_ai/server/{frontend_dist/_next/static/chunks/pages/oauth-bd8494f8875c5c97.js → frontend_dist_base_path_template/_next/static/chunks/pages/oauth-aa9079c8dbaea3a5.js} +1 -1
  362. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-4e30fb5b18383b71.js +1 -0
  363. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-5d31c3aace39182d.js +1 -0
  364. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-85a80ee66f60a65c.js +1 -0
  365. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-0bd74047e257e6d9.js +1 -0
  366. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-80619dc504d0103b.js +1 -0
  367. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-3cc8d74ff8525bfd.js +1 -0
  368. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-cdc379ff24ff8858.js +1 -0
  369. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-03396d6086003e16.js +1 -0
  370. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-d6d920758654f6d9.js +1 -0
  371. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-27727bb87be506c3.js +1 -0
  372. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-16aab67743651a0b.js +1 -0
  373. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-e3ca1bedb660b252.js +1 -0
  374. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-9d58701fe7213727.js +1 -0
  375. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-0041fd76ee15e49f.js +1 -0
  376. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-780be9a2da697915.js +1 -0
  377. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-db8bb970b1f2273f.js +1 -0
  378. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-a3422b0ab1dbacd7.js +1 -0
  379. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks/[...slug]-987a1603f4201943.js +1 -0
  380. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks-3dc8bf89cab2722b.js +1 -0
  381. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-43d3f2a5071b9537.js +1 -0
  382. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-c97b1a39b22c112a.js +1 -0
  383. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-49efb66da67554ca.js +1 -0
  384. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-aa5d871de1f3f7b0.js → [...slug]-5117d3555972484c.js} +1 -1
  385. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions-ee1c19d4a192ae4d.js +1 -0
  386. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-4dc5724486ee3396.js +1 -0
  387. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-88d29d1774db67e4.js → [...slug]-fa095aac732368c3.js} +1 -1
  388. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{roles-d8ca763e405cd9d1.js → roles-db6d71f8692a33e7.js} +1 -1
  389. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-99c6a263d2ab9553.js +1 -0
  390. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-250dfdf22bfe67e9.js → [...slug]-9d881ac0a3db9baa.js} +1 -1
  391. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users-bee414d57c4b55d7.js +1 -0
  392. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-e7030e1a7a9e88e1.js +1 -0
  393. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates/[...slug]-312afc9a3f8d0a4f.js +1 -0
  394. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates-e5300c340aa94c6b.js +1 -0
  395. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-fa7ca0c86142d146.js +1 -0
  396. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-bd51b3918b39329e.js +1 -0
  397. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-5158a9d98d2459e8.js +1 -0
  398. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-5ce099a7abb354ff.js +1 -0
  399. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-b55fe1e575d8ac9d.js → webpack-bd35e1c7bd7b5a9a.js} +1 -1
  400. mage_ai/server/{frontend_dist/_next/static/css/d1e8e64d0b07af2f.css → frontend_dist_base_path_template/_next/static/css/b59541b123fd7191.css} +1 -1
  401. mage_ai/server/frontend_dist_base_path_template/_next/static/do4WOsw7lNhouR0mtPTFi/_buildManifest.js +1 -0
  402. mage_ai/server/frontend_dist_base_path_template/block-layout.html +3 -3
  403. mage_ai/server/frontend_dist_base_path_template/compute.html +11 -11
  404. mage_ai/server/frontend_dist_base_path_template/files.html +11 -11
  405. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +11 -11
  406. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +11 -11
  407. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +11 -11
  408. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +11 -11
  409. mage_ai/server/frontend_dist_base_path_template/index.html +3 -3
  410. mage_ai/server/frontend_dist_base_path_template/manage/files.html +11 -11
  411. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +11 -11
  412. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +11 -11
  413. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +11 -11
  414. mage_ai/server/frontend_dist_base_path_template/manage/users.html +11 -11
  415. mage_ai/server/frontend_dist_base_path_template/manage.html +11 -11
  416. mage_ai/server/frontend_dist_base_path_template/oauth.html +8 -8
  417. mage_ai/server/frontend_dist_base_path_template/overview.html +11 -11
  418. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +11 -11
  419. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +11 -11
  420. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +11 -11
  421. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +11 -11
  422. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +3 -3
  423. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +11 -11
  424. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +11 -11
  425. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +11 -11
  426. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +11 -11
  427. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +11 -11
  428. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +11 -11
  429. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +11 -11
  430. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +11 -11
  431. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +11 -11
  432. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +11 -11
  433. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +3 -3
  434. mage_ai/server/frontend_dist_base_path_template/pipelines.html +11 -11
  435. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +11 -11
  436. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +11 -11
  437. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +11 -11
  438. mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +11 -11
  439. mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +11 -11
  440. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +11 -11
  441. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +11 -11
  442. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +11 -11
  443. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +11 -11
  444. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +11 -11
  445. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +11 -11
  446. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +11 -11
  447. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +11 -11
  448. mage_ai/server/frontend_dist_base_path_template/settings.html +3 -3
  449. mage_ai/server/frontend_dist_base_path_template/sign-in.html +40 -41
  450. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +11 -11
  451. mage_ai/server/frontend_dist_base_path_template/templates.html +11 -11
  452. mage_ai/server/frontend_dist_base_path_template/terminal.html +11 -11
  453. mage_ai/server/frontend_dist_base_path_template/test.html +3 -3
  454. mage_ai/server/frontend_dist_base_path_template/triggers.html +11 -11
  455. mage_ai/server/frontend_dist_base_path_template/version-control.html +11 -11
  456. mage_ai/server/logger.py +8 -2
  457. mage_ai/server/server.py +18 -1
  458. mage_ai/services/aws/ecs/config.py +3 -3
  459. mage_ai/services/aws/ecs/ecs.py +2 -2
  460. mage_ai/services/search/block_action_objects.py +59 -5
  461. mage_ai/settings/models/configuration_option.py +3 -1
  462. mage_ai/settings/platform/__init__.py +64 -20
  463. mage_ai/settings/platform/utils.py +4 -1
  464. mage_ai/settings/repo.py +5 -4
  465. mage_ai/shared/custom_logger.py +213 -0
  466. mage_ai/shared/environments.py +4 -0
  467. mage_ai/shared/files.py +52 -1
  468. mage_ai/shared/models.py +2 -1
  469. mage_ai/shared/parsers.py +8 -1
  470. mage_ai/shared/path_fixer.py +62 -5
  471. mage_ai/shared/retry.py +4 -0
  472. mage_ai/shared/strings.py +4 -0
  473. mage_ai/tests/api/endpoints/test_blocks.py +101 -1
  474. mage_ai/tests/api/operations/base/test_base_with_user_permissions.py +4 -1
  475. mage_ai/tests/base_test.py +21 -2
  476. mage_ai/tests/cache/test_pipeline_cache.py +11 -8
  477. mage_ai/tests/data_preparation/executors/test_block_executor.py +55 -45
  478. mage_ai/tests/data_preparation/git/test_api.py +4 -4
  479. mage_ai/tests/data_preparation/models/block/dbt/test_block.py +75 -43
  480. mage_ai/tests/data_preparation/models/block/dbt/test_block_sql.py +329 -320
  481. mage_ai/tests/data_preparation/models/block/dbt/test_block_yaml.py +298 -268
  482. mage_ai/tests/data_preparation/models/block/dbt/test_dbt_adapter.py +14 -4
  483. mage_ai/tests/data_preparation/models/block/dbt/test_dbt_cli.py +14 -11
  484. mage_ai/tests/data_preparation/models/block/dbt/test_profiles.py +2 -2
  485. mage_ai/tests/data_preparation/models/block/dbt/test_project.py +2 -2
  486. mage_ai/tests/data_preparation/models/block/dbt/test_sources.py +2 -2
  487. mage_ai/tests/data_preparation/models/block/dynamic/test_dynamic_child_block_factory.py +477 -474
  488. mage_ai/tests/data_preparation/models/block/dynamic/test_dynamic_helpers.py +25 -24
  489. mage_ai/tests/data_preparation/models/block/platform/test_mixins.py +16 -25
  490. mage_ai/tests/data_preparation/models/block/test_utils.py +8 -8
  491. mage_ai/tests/data_preparation/models/test_block.py +6 -8
  492. mage_ai/tests/data_preparation/models/test_project.py +10 -5
  493. mage_ai/tests/data_preparation/models/test_variable.py +51 -4
  494. mage_ai/tests/orchestration/test_pipeline_scheduler_project_platform.py +1 -0
  495. mage_ai/version_control/__init__.py +0 -0
  496. mage_ai/version_control/models.py +288 -0
  497. {mage_ai-0.9.57.dist-info → mage_ai-0.9.59.dist-info}/METADATA +49 -47
  498. {mage_ai-0.9.57.dist-info → mage_ai-0.9.59.dist-info}/RECORD +504 -486
  499. mage_ai/server/frontend_dist/_next/static/A7VXVGKgLQCukXcjdysDz/_buildManifest.js +0 -1
  500. mage_ai/server/frontend_dist/_next/static/chunks/1124-09b283a2f26cc576.js +0 -1
  501. mage_ai/server/frontend_dist/_next/static/chunks/1154-2f262f7eb38ebaa1.js +0 -1
  502. mage_ai/server/frontend_dist/_next/static/chunks/1235.53172e14801844e5.js +0 -1
  503. mage_ai/server/frontend_dist/_next/static/chunks/1557-724bfc3eabd095f7.js +0 -1
  504. mage_ai/server/frontend_dist/_next/static/chunks/161-33f26e485ddef393.js +0 -1
  505. mage_ai/server/frontend_dist/_next/static/chunks/1751-5adf859690505d7b.js +0 -1
  506. mage_ai/server/frontend_dist/_next/static/chunks/1821-953efd0da290d25f.js +0 -1
  507. mage_ai/server/frontend_dist/_next/static/chunks/2474-352ae192b826d896.js +0 -1
  508. mage_ai/server/frontend_dist/_next/static/chunks/2646-78905b899b68f4eb.js +0 -1
  509. mage_ai/server/frontend_dist/_next/static/chunks/2717-477f64b5e272d5a3.js +0 -1
  510. mage_ai/server/frontend_dist/_next/static/chunks/2852872c-15b31a7081e6a868.js +0 -1
  511. mage_ai/server/frontend_dist/_next/static/chunks/2920.86a65e5f26ff1795.js +0 -1
  512. mage_ai/server/frontend_dist/_next/static/chunks/3004-9fff558eeede3a83.js +0 -1
  513. mage_ai/server/frontend_dist/_next/static/chunks/341-ef0f7b98b7f69802.js +0 -1
  514. mage_ai/server/frontend_dist/_next/static/chunks/3419-b8bd26f5946bec5a.js +0 -1
  515. mage_ai/server/frontend_dist/_next/static/chunks/3437-ce26fc28e114b44e.js +0 -1
  516. mage_ai/server/frontend_dist/_next/static/chunks/3540-9bb48b08f439d0a0.js +0 -1
  517. mage_ai/server/frontend_dist/_next/static/chunks/3745-61b1c63bb56bb670.js +0 -1
  518. mage_ai/server/frontend_dist/_next/static/chunks/3859-ba594d21a1260cd2.js +0 -1
  519. mage_ai/server/frontend_dist/_next/static/chunks/3943-a49377acc514e77f.js +0 -1
  520. mage_ai/server/frontend_dist/_next/static/chunks/5283-8d1dacb2eeb9e652.js +0 -1
  521. mage_ai/server/frontend_dist/_next/static/chunks/5457-b373ebdf4d05d8e2.js +0 -1
  522. mage_ai/server/frontend_dist/_next/static/chunks/5499-261cfa2410506eb4.js +0 -1
  523. mage_ai/server/frontend_dist/_next/static/chunks/5533-3455832bc3f8429b.js +0 -1
  524. mage_ai/server/frontend_dist/_next/static/chunks/5729-9d8204ab91da631d.js +0 -1
  525. mage_ai/server/frontend_dist/_next/static/chunks/5810-addfa3491ae6b01c.js +0 -1
  526. mage_ai/server/frontend_dist/_next/static/chunks/5820-28adeabb5cda2b96.js +0 -1
  527. mage_ai/server/frontend_dist/_next/static/chunks/5896-7b8e36634d7d94eb.js +0 -1
  528. mage_ai/server/frontend_dist/_next/static/chunks/6043-728790621ca9014c.js +0 -1
  529. mage_ai/server/frontend_dist/_next/static/chunks/6285-648f9a732e100b2f.js +0 -1
  530. mage_ai/server/frontend_dist/_next/static/chunks/6563-5b3b97c9088baf69.js +0 -1
  531. mage_ai/server/frontend_dist/_next/static/chunks/6639-74eefed142e14ea6.js +0 -1
  532. mage_ai/server/frontend_dist/_next/static/chunks/6965-c613d1834c8ed92d.js +0 -1
  533. mage_ai/server/frontend_dist/_next/static/chunks/7022-1c1c93b6222d48f9.js +0 -1
  534. mage_ai/server/frontend_dist/_next/static/chunks/7361-559f4d2eca379217.js +0 -1
  535. mage_ai/server/frontend_dist/_next/static/chunks/7858-26a5a5d04fa3c703.js +0 -1
  536. mage_ai/server/frontend_dist/_next/static/chunks/8146-7fc9ef7d0202e6ab.js +0 -1
  537. mage_ai/server/frontend_dist/_next/static/chunks/8264-68db2a8334ad48f1.js +0 -1
  538. mage_ai/server/frontend_dist/_next/static/chunks/8432-0ace6fb7bdbc6864.js +0 -1
  539. mage_ai/server/frontend_dist/_next/static/chunks/844-1e171f361e63b36d.js +0 -1
  540. mage_ai/server/frontend_dist/_next/static/chunks/8731-82571147875a2d58.js +0 -1
  541. mage_ai/server/frontend_dist/_next/static/chunks/874-d9e1b3c9c00ebac9.js +0 -1
  542. mage_ai/server/frontend_dist/_next/static/chunks/8998-e46ae0a83be32d42.js +0 -1
  543. mage_ai/server/frontend_dist/_next/static/chunks/9264-5df6e4c7b1e85c02.js +0 -1
  544. mage_ai/server/frontend_dist/_next/static/chunks/9302-913007e2f801ad65.js +0 -1
  545. mage_ai/server/frontend_dist/_next/static/chunks/9440-c51bf1e8f271cb25.js +0 -1
  546. mage_ai/server/frontend_dist/_next/static/chunks/9624-89a4b20eb3b3c754.js +0 -1
  547. mage_ai/server/frontend_dist/_next/static/chunks/976-0a8c2c4d7acd957b.js +0 -1
  548. mage_ai/server/frontend_dist/_next/static/chunks/pages/404-5ddd12931e0e3e41.js +0 -1
  549. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-4c0239ca6203e827.js +0 -1
  550. mage_ai/server/frontend_dist/_next/static/chunks/pages/block-layout-d40babdbf465a7e1.js +0 -1
  551. mage_ai/server/frontend_dist/_next/static/chunks/pages/compute-822e66aa2e90cf4c.js +0 -1
  552. mage_ai/server/frontend_dist/_next/static/chunks/pages/files-373217c5de51aeef.js +0 -1
  553. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-0325e76a2f3e08c1.js +0 -1
  554. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-a172f5a447bd8925.js +0 -1
  555. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks-97bec2ac883e0c26.js +0 -1
  556. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/files-02d001d99eeaae3f.js +0 -1
  557. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-2e577bfd4f0db2b7.js +0 -1
  558. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/[user]-1827574a4ba95a72.js +0 -1
  559. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-a913c361bcc0d1a9.js +0 -1
  560. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users-4e6fdcbbfc931d67.js +0 -1
  561. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-1c327edcf05df9c9.js +0 -1
  562. mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-5a98e6a531410afb.js +0 -1
  563. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipeline-runs-1442183d13edec2e.js +0 -1
  564. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-38b2241cdd10320c.js +0 -1
  565. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-1c646dbef65d6a69.js +0 -1
  566. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-35cb916a18ac4e1f.js +0 -1
  567. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-cd1918632dfef29d.js +0 -1
  568. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-67b0572c84db0940.js +0 -1
  569. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-40201b626ea3a664.js +0 -1
  570. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-d1f23308effebe03.js +0 -1
  571. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-9a116d88f00916ff.js +0 -1
  572. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-2d5abcd019d4bea1.js +0 -1
  573. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-5363a7ae9afe8983.js +0 -1
  574. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-931a1b3112866a72.js +0 -1
  575. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-5ec5367cb877db38.js +0 -1
  576. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-8366661f8e2b2959.js +0 -1
  577. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-378f8dada7d0c1dd.js +0 -1
  578. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-627be24ef4963cfb.js +0 -1
  579. mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks/[...slug]-814bbd11e10c26dc.js +0 -1
  580. mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks-021ec25e05862f8f.js +0 -1
  581. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-2b0aa123043519b8.js +0 -1
  582. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-05186e17c94347c1.js +0 -1
  583. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/settings-efe8bf1bf3177a7e.js +0 -1
  584. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions-ce45aad47049d993.js +0 -1
  585. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-1bc694b056ff0bcb.js +0 -1
  586. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-42bd909eb8951040.js +0 -1
  587. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users-97c4ce119f7238b5.js +0 -1
  588. mage_ai/server/frontend_dist/_next/static/chunks/pages/sign-in-1af3ba18ff646dd4.js +0 -1
  589. mage_ai/server/frontend_dist/_next/static/chunks/pages/templates/[...slug]-ff9d49355393daea.js +0 -1
  590. mage_ai/server/frontend_dist/_next/static/chunks/pages/templates-299a2c8f2dd89cf3.js +0 -1
  591. mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-fb3f398009a02879.js +0 -1
  592. mage_ai/server/frontend_dist/_next/static/chunks/pages/test-59a08e06f4ef6c3a.js +0 -1
  593. mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-551b85802515e313.js +0 -1
  594. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-1362aeda4a31dd41.js +0 -1
  595. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1124-09b283a2f26cc576.js +0 -1
  596. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1154-2f262f7eb38ebaa1.js +0 -1
  597. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1235.53172e14801844e5.js +0 -1
  598. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-724bfc3eabd095f7.js +0 -1
  599. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/161-33f26e485ddef393.js +0 -1
  600. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1751-5adf859690505d7b.js +0 -1
  601. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1821-953efd0da290d25f.js +0 -1
  602. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2474-352ae192b826d896.js +0 -1
  603. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2646-78905b899b68f4eb.js +0 -1
  604. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2717-477f64b5e272d5a3.js +0 -1
  605. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2852872c-15b31a7081e6a868.js +0 -1
  606. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2920.86a65e5f26ff1795.js +0 -1
  607. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3004-9fff558eeede3a83.js +0 -1
  608. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/341-ef0f7b98b7f69802.js +0 -1
  609. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3419-b8bd26f5946bec5a.js +0 -1
  610. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3437-ce26fc28e114b44e.js +0 -1
  611. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3540-9bb48b08f439d0a0.js +0 -1
  612. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3745-61b1c63bb56bb670.js +0 -1
  613. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3859-ba594d21a1260cd2.js +0 -1
  614. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3943-a49377acc514e77f.js +0 -1
  615. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5283-8d1dacb2eeb9e652.js +0 -1
  616. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-b373ebdf4d05d8e2.js +0 -1
  617. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5499-261cfa2410506eb4.js +0 -1
  618. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5533-3455832bc3f8429b.js +0 -1
  619. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5729-9d8204ab91da631d.js +0 -1
  620. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5810-addfa3491ae6b01c.js +0 -1
  621. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5820-28adeabb5cda2b96.js +0 -1
  622. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5896-7b8e36634d7d94eb.js +0 -1
  623. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6043-728790621ca9014c.js +0 -1
  624. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6285-648f9a732e100b2f.js +0 -1
  625. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6563-5b3b97c9088baf69.js +0 -1
  626. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6639-74eefed142e14ea6.js +0 -1
  627. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6965-c613d1834c8ed92d.js +0 -1
  628. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-1c1c93b6222d48f9.js +0 -1
  629. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-559f4d2eca379217.js +0 -1
  630. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7858-26a5a5d04fa3c703.js +0 -1
  631. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-7fc9ef7d0202e6ab.js +0 -1
  632. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8264-68db2a8334ad48f1.js +0 -1
  633. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8432-0ace6fb7bdbc6864.js +0 -1
  634. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/844-1e171f361e63b36d.js +0 -1
  635. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8731-82571147875a2d58.js +0 -1
  636. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/874-d9e1b3c9c00ebac9.js +0 -1
  637. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8998-e46ae0a83be32d42.js +0 -1
  638. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9264-5df6e4c7b1e85c02.js +0 -1
  639. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9302-913007e2f801ad65.js +0 -1
  640. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-c51bf1e8f271cb25.js +0 -1
  641. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9624-89a4b20eb3b3c754.js +0 -1
  642. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/976-0a8c2c4d7acd957b.js +0 -1
  643. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/404-5ddd12931e0e3e41.js +0 -1
  644. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-4c0239ca6203e827.js +0 -1
  645. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/block-layout-d40babdbf465a7e1.js +0 -1
  646. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/compute-822e66aa2e90cf4c.js +0 -1
  647. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-373217c5de51aeef.js +0 -1
  648. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-0325e76a2f3e08c1.js +0 -1
  649. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-a172f5a447bd8925.js +0 -1
  650. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks-97bec2ac883e0c26.js +0 -1
  651. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/files-02d001d99eeaae3f.js +0 -1
  652. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-2e577bfd4f0db2b7.js +0 -1
  653. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-1827574a4ba95a72.js +0 -1
  654. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-a913c361bcc0d1a9.js +0 -1
  655. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users-4e6fdcbbfc931d67.js +0 -1
  656. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-1c327edcf05df9c9.js +0 -1
  657. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-5a98e6a531410afb.js +0 -1
  658. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-1442183d13edec2e.js +0 -1
  659. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-38b2241cdd10320c.js +0 -1
  660. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-1c646dbef65d6a69.js +0 -1
  661. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-35cb916a18ac4e1f.js +0 -1
  662. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-cd1918632dfef29d.js +0 -1
  663. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-67b0572c84db0940.js +0 -1
  664. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-40201b626ea3a664.js +0 -1
  665. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-d1f23308effebe03.js +0 -1
  666. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-9a116d88f00916ff.js +0 -1
  667. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-2d5abcd019d4bea1.js +0 -1
  668. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-5363a7ae9afe8983.js +0 -1
  669. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-931a1b3112866a72.js +0 -1
  670. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-5ec5367cb877db38.js +0 -1
  671. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-8366661f8e2b2959.js +0 -1
  672. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-378f8dada7d0c1dd.js +0 -1
  673. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-627be24ef4963cfb.js +0 -1
  674. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks/[...slug]-814bbd11e10c26dc.js +0 -1
  675. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks-021ec25e05862f8f.js +0 -1
  676. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-2b0aa123043519b8.js +0 -1
  677. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-05186e17c94347c1.js +0 -1
  678. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-efe8bf1bf3177a7e.js +0 -1
  679. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions-ce45aad47049d993.js +0 -1
  680. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-1bc694b056ff0bcb.js +0 -1
  681. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-42bd909eb8951040.js +0 -1
  682. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users-97c4ce119f7238b5.js +0 -1
  683. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-1af3ba18ff646dd4.js +0 -1
  684. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates/[...slug]-ff9d49355393daea.js +0 -1
  685. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates-299a2c8f2dd89cf3.js +0 -1
  686. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-fb3f398009a02879.js +0 -1
  687. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-59a08e06f4ef6c3a.js +0 -1
  688. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-551b85802515e313.js +0 -1
  689. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-1362aeda4a31dd41.js +0 -1
  690. mage_ai/server/frontend_dist_base_path_template/_next/static/wSRrM15xnvA8lOWcaque7/_buildManifest.js +0 -1
  691. /mage_ai/server/frontend_dist/_next/static/{A7VXVGKgLQCukXcjdysDz → PPQxHOmWVJ0iQFzG2rc8m}/_ssgManifest.js +0 -0
  692. /mage_ai/server/frontend_dist_base_path_template/_next/static/{wSRrM15xnvA8lOWcaque7 → do4WOsw7lNhouR0mtPTFi}/_ssgManifest.js +0 -0
  693. {mage_ai-0.9.57.dist-info → mage_ai-0.9.59.dist-info}/LICENSE +0 -0
  694. {mage_ai-0.9.57.dist-info → mage_ai-0.9.59.dist-info}/WHEEL +0 -0
  695. {mage_ai-0.9.57.dist-info → mage_ai-0.9.59.dist-info}/entry_points.txt +0 -0
  696. {mage_ai-0.9.57.dist-info → mage_ai-0.9.59.dist-info}/top_level.txt +0 -0
@@ -124,7 +124,11 @@ class File:
124
124
  repo_path_alt = repo_path
125
125
  if repo_path_alt is None:
126
126
  repo_path_alt = get_repo_path(file_path=file_path)
127
- return File(os.path.basename(file_path), os.path.dirname(file_path), repo_path_alt)
127
+ return File(
128
+ os.path.basename(file_path or ''),
129
+ os.path.dirname(file_path or ''),
130
+ repo_path_alt or '',
131
+ )
128
132
 
129
133
  @classmethod
130
134
  def get_all_files(
@@ -274,6 +278,8 @@ class File:
274
278
 
275
279
  update_caches(repo_path, dir_path, filename)
276
280
 
281
+ update_file_cache()
282
+
277
283
  @classmethod
278
284
  async def write_async(
279
285
  self,
@@ -304,6 +310,8 @@ class File:
304
310
 
305
311
  await update_caches_async(repo_path, dir_path, filename)
306
312
 
313
+ update_file_cache()
314
+
307
315
  def exists(self) -> bool:
308
316
  return self.file_exists(self.file_path)
309
317
 
@@ -322,7 +330,7 @@ class File:
322
330
  async with aiofiles.open(self.file_path, mode='r', encoding='utf-8') as fp:
323
331
  file_content = await fp.read()
324
332
  return file_content
325
- except FileNotFoundError as err:
333
+ except Exception as err:
326
334
  print(err)
327
335
  return ''
328
336
 
@@ -369,6 +377,8 @@ class File:
369
377
  def delete(self):
370
378
  os.remove(self.file_path)
371
379
 
380
+ update_file_cache()
381
+
372
382
  def rename(self, dir_path: str, filename):
373
383
  full_path = os.path.join(self.repo_path, dir_path, filename)
374
384
 
@@ -395,6 +405,8 @@ class File:
395
405
  self.dir_path = dir_path
396
406
  self.filename = filename
397
407
 
408
+ update_file_cache()
409
+
398
410
  def to_dict(self, include_content=False):
399
411
  data = dict(name=self.filename, path=os.path.join(self.dir_path, self.filename))
400
412
  if include_content:
@@ -511,7 +523,7 @@ async def update_caches_async(repo_path: str, dir_path: str, filename: str) -> N
511
523
  dbt_cache = await DBTCache.initialize_cache_async(root_project=True)
512
524
  await dbt_cache.update_async(file_path=os.path.join(repo_path, dir_path, filename))
513
525
  except Exception as err:
514
- print(f'[ERROR] File.update_caches DBTCache: {err}.')
526
+ print(f'[ERROR] File update DBTCache for {repo_path}, {dir_path}, {filename}: {err}.')
515
527
  if is_debug():
516
528
  raise err
517
529
 
@@ -526,6 +538,13 @@ def update_caches(repo_path: str, dir_path: str, filename: str) -> None:
526
538
  dbt_cache = DBTCache.initialize_cache(root_project=True)
527
539
  dbt_cache.update(file_path=os.path.join(repo_path, dir_path, filename))
528
540
  except Exception as err:
529
- print(f'[ERROR] File.update_caches DBTCache: {err}.')
541
+ print(f'[ERROR] File update DBTCache for {repo_path}, {dir_path}, {filename}: {err}.')
530
542
  if is_debug():
531
543
  raise err
544
+
545
+
546
+ def update_file_cache() -> None:
547
+ project_model = Project(root_project=True)
548
+ if project_model and project_model.is_feature_enabled(FeatureUUID.COMMAND_CENTER):
549
+ from mage_ai.cache.file import FileCache
550
+ FileCache().invalidate()
@@ -3,7 +3,7 @@ import datetime
3
3
  import json
4
4
  import os
5
5
  import shutil
6
- from typing import Any, Callable, Dict, List
6
+ from typing import Any, Callable, Dict, List, Tuple, Union
7
7
 
8
8
  import aiofiles
9
9
  import dateutil.parser
@@ -310,6 +310,7 @@ class Pipeline:
310
310
  raise_exception (bool, optional): Whether to raise Exception.
311
311
  If raise_exception = False, return None as the config when exception happens.
312
312
  """
313
+ include_repo_path = repo_path is not None
313
314
  repo_path = repo_path or get_repo_path()
314
315
  config_path = os.path.join(
315
316
  repo_path,
@@ -330,6 +331,9 @@ class Pipeline:
330
331
  raise e
331
332
  config = None
332
333
 
334
+ if include_repo_path and config:
335
+ config['repo_path'] = repo_path
336
+
333
337
  return config
334
338
 
335
339
  @classmethod
@@ -390,7 +394,11 @@ class Pipeline:
390
394
  return pipeline
391
395
 
392
396
  @classmethod
393
- def get_all_pipelines_all_projects(self, *args, **kwargs):
397
+ def get_all_pipelines_all_projects(
398
+ self,
399
+ *args,
400
+ **kwargs,
401
+ ) -> Union[List[str], List[Tuple[str, str]]]:
394
402
  if project_platform_activated():
395
403
  repo_paths = [d.get(
396
404
  'full_path',
@@ -409,7 +417,8 @@ class Pipeline:
409
417
  repo_path: str = None,
410
418
  repo_paths: List[str] = None,
411
419
  disable_pipelines_folder_creation: bool = False,
412
- ) -> List[str]:
420
+ include_repo_path: bool = False,
421
+ ) -> Union[List[str], List[Tuple[str, str]]]:
413
422
  arr = []
414
423
 
415
424
  paths = []
@@ -422,12 +431,13 @@ class Pipeline:
422
431
  pipelines_folder = os.path.join(path, PIPELINES_FOLDER)
423
432
  pipelines_folder_exists = os.path.exists(pipelines_folder)
424
433
  if not pipelines_folder_exists and not disable_pipelines_folder_creation:
425
- os.mkdir(pipelines_folder)
426
- pipelines_folder_exists = True
434
+ if os.path.exists(os.path.dirname(pipelines_folder)):
435
+ os.mkdir(pipelines_folder)
436
+ pipelines_folder_exists = True
427
437
 
428
438
  if pipelines_folder_exists:
429
439
  arr.extend([
430
- d
440
+ (d, path) if include_repo_path else d
431
441
  for d in os.listdir(pipelines_folder)
432
442
  if self.is_valid_pipeline(os.path.join(pipelines_folder, d))
433
443
  ])
@@ -1157,7 +1167,7 @@ class Pipeline:
1157
1167
 
1158
1168
  for block in self.blocks_by_uuid.values():
1159
1169
  if old_uuid:
1160
- cache.remove_pipeline(block, old_uuid)
1170
+ cache.remove_pipeline(block, old_uuid, self.repo_path)
1161
1171
  cache.update_pipeline(block, self)
1162
1172
 
1163
1173
  if should_update_tag_cache:
@@ -1167,7 +1177,7 @@ class Pipeline:
1167
1177
 
1168
1178
  for tag_uuid in self.tags:
1169
1179
  if old_uuid:
1170
- cache.remove_pipeline(tag_uuid, old_uuid)
1180
+ cache.remove_pipeline(tag_uuid, old_uuid, self.repo_path)
1171
1181
  cache.add_pipeline(tag_uuid, self)
1172
1182
 
1173
1183
  def __update_block_order(self, blocks: List[Dict]) -> bool:
@@ -1357,6 +1367,7 @@ class Pipeline:
1357
1367
  spark=None,
1358
1368
  index: int = None,
1359
1369
  sample_count: int = None,
1370
+ dynamic_block_index: int = None,
1360
1371
  ):
1361
1372
  block = self.get_block(block_uuid)
1362
1373
 
@@ -1385,6 +1396,7 @@ class Pipeline:
1385
1396
  raise_exception=raise_exception,
1386
1397
  spark=spark,
1387
1398
  variable_uuid=variable_name,
1399
+ dynamic_block_index=dynamic_block_index,
1388
1400
  )
1389
1401
 
1390
1402
  return variable
@@ -23,8 +23,7 @@ class Project():
23
23
  self.root_project = root_project
24
24
  self.repo_path = repo_path or get_repo_path(root_project=self.root_project)
25
25
 
26
- parts = self.repo_path.split('/')
27
- self.name = parts[-1]
26
+ self.name = os.path.basename(self.repo_path)
28
27
  self.settings = None
29
28
 
30
29
  if not root_project and project_platform_activated():
@@ -32,12 +31,9 @@ class Project():
32
31
  if self.settings and self.settings.get('uuid'):
33
32
  self.name = self.settings.get('uuid')
34
33
 
35
- self.repo_config = repo_config or get_repo_config(
36
- repo_path=self.repo_path,
37
- root_project=self.root_project,
38
- )
39
34
  self.version = VERSION
40
35
  self._features = None
36
+ self._repo_config = repo_config
41
37
 
42
38
  self.__repo_config_root_project = None
43
39
 
@@ -47,6 +43,15 @@ class Project():
47
43
  root_project=True,
48
44
  )
49
45
 
46
+ @property
47
+ def repo_config(self):
48
+ if not self._repo_config:
49
+ self._repo_config = get_repo_config(
50
+ repo_path=self.repo_path,
51
+ root_project=self.root_project,
52
+ )
53
+ return self._repo_config
54
+
50
55
  @property
51
56
  def workspace_config_defaults(self) -> Dict:
52
57
  config = self.repo_config.workspace_config_defaults or {}
@@ -174,7 +179,7 @@ class Project():
174
179
  def is_feature_enabled(self, feature_name: FeatureUUID) -> bool:
175
180
  feature_enabled = self.features.get(feature_name.value, False)
176
181
 
177
- if is_debug():
182
+ if is_debug() and not os.getenv('DISABLE_DATABASE_TERMINAL_OUTPUT'):
178
183
  print(f'[Project.is_feature_enabled]: {feature_name} | {feature_enabled}')
179
184
 
180
185
  return feature_enabled
@@ -3,6 +3,8 @@ from enum import Enum
3
3
 
4
4
  class FeatureUUID(str, Enum):
5
5
  ADD_NEW_BLOCK_V2 = 'add_new_block_v2'
6
+ CODE_BLOCK_V2 = 'code_block_v2'
7
+ COMMAND_CENTER = 'command_center'
6
8
  COMPUTE_MANAGEMENT = 'compute_management'
7
9
  CUSTOM_DESIGN = 'custom_design'
8
10
  DATA_INTEGRATION_IN_BATCH_PIPELINE = 'data_integration_in_batch_pipeline'
@@ -29,6 +29,13 @@ class ScheduleType(str, enum.Enum):
29
29
  TIME = 'time'
30
30
 
31
31
 
32
+ SCHEDULE_TYPE_TO_LABEL = {
33
+ ScheduleType.API: 'API',
34
+ ScheduleType.EVENT: 'Event',
35
+ ScheduleType.TIME: 'Schedule',
36
+ }
37
+
38
+
32
39
  class ScheduleInterval(str, enum.Enum):
33
40
  ONCE = '@once'
34
41
  HOURLY = '@hourly'
@@ -4,6 +4,7 @@ from typing import Any, Dict
4
4
  import dask.dataframe as dd
5
5
  import numpy
6
6
  import pandas as pd
7
+ import polars as pl
7
8
  import simplejson
8
9
  import yaml
9
10
 
@@ -24,6 +25,11 @@ CAST_TYPE_COLUMN_TYPES = set([
24
25
  'float64',
25
26
  ])
26
27
 
28
+ POLARS_CAST_TYPE_COLUMN_TYPES = {
29
+ 'Float64': pl.Float64,
30
+ 'Int64': pl.Int64,
31
+ }
32
+
27
33
 
28
34
  def serialize_columns(row: pd.Series, column_types: Dict) -> pd.Series:
29
35
  for column, column_type in column_types.items():
@@ -54,6 +60,16 @@ def cast_column_types(df: pd.DataFrame, column_types: Dict):
54
60
  return df
55
61
 
56
62
 
63
+ def cast_column_types_polars(df: pl.DataFrame, column_types: Dict):
64
+ for column, column_type in column_types.items():
65
+ if column_type in POLARS_CAST_TYPE_COLUMN_TYPES:
66
+ try:
67
+ df = df.cast({column: POLARS_CAST_TYPE_COLUMN_TYPES.get(column_type)})
68
+ except Exception:
69
+ traceback.print_exc()
70
+ return df
71
+
72
+
57
73
  def deserialize_columns(row: pd.Series, column_types: Dict) -> pd.Series:
58
74
  for column, column_type in column_types.items():
59
75
  if column_type not in JSON_SERIALIZABLE_COLUMN_TYPES:
@@ -85,6 +101,10 @@ def apply_transform_pandas(df: pd.DataFrame, apply_function) -> pd.DataFrame:
85
101
  return df.apply(apply_function, axis=1)
86
102
 
87
103
 
104
+ def apply_transform_polars(df: pl.DataFrame, apply_function) -> pl.DataFrame:
105
+ return df.apply(apply_function, axis=1)
106
+
107
+
88
108
  def should_serialize_pandas(column_types: Dict) -> bool:
89
109
  if not column_types:
90
110
  return False
@@ -21,6 +21,7 @@ from mage_ai.data_preparation.models.utils import ( # dask_from_pandas,
21
21
  STRING_SERIALIZABLE_COLUMN_TYPES,
22
22
  apply_transform_pandas,
23
23
  cast_column_types,
24
+ cast_column_types_polars,
24
25
  deserialize_columns,
25
26
  serialize_columns,
26
27
  should_deserialize_pandas,
@@ -36,6 +37,8 @@ DATAFRAME_PARQUET_FILE = 'data.parquet'
36
37
  DATAFRAME_PARQUET_SAMPLE_FILE = 'sample_data.parquet'
37
38
  DATAFRAME_CSV_FILE = 'data.csv'
38
39
 
40
+ METADATA_FILE = 'type.json'
41
+
39
42
  JSON_FILE = 'data.json'
40
43
  JSON_SAMPLE_FILE = 'sample_data.json'
41
44
 
@@ -87,26 +90,43 @@ class Variable:
87
90
  def variable_path(self):
88
91
  return os.path.join(self.variable_dir_path, self.uuid or '')
89
92
 
93
+ @property
94
+ def metadata_path(self):
95
+ return os.path.join(self.variable_path, METADATA_FILE)
96
+
90
97
  @classmethod
91
98
  def dir_path(self, pipeline_path, block_uuid):
92
99
  return os.path.join(pipeline_path, VARIABLE_DIR, clean_name(block_uuid))
93
100
 
94
101
  def check_variable_type(self, spark=None):
95
102
  """
96
- Infer variable type based on data in the storage.
103
+ If the variable has a metadata file, read the variable type from the metadata file.
104
+ Fallback to inferring variable type based on data in the storage.
97
105
  """
106
+ if self.variable_type is None:
107
+ try:
108
+ if self.storage.path_exists(self.metadata_path):
109
+ metadata = self.storage.read_json_file(self.metadata_path, raise_exception=True)
110
+ self.variable_type = metadata.get('type')
111
+ except Exception:
112
+ traceback.print_exc()
113
+
98
114
  if self.variable_type is None and self.storage.path_exists(
99
115
  os.path.join(self.variable_path, DATAFRAME_PARQUET_FILE)
100
116
  ):
101
117
  # If parquet file exists for given variable, set the variable type to DATAFRAME
102
118
  self.variable_type = VariableType.DATAFRAME
103
- elif ((self.variable_type == VariableType.DATAFRAME or self.variable_type is None)
104
- and os.path.exists(
105
- os.path.join(self.variable_dir_path, f'{self.uuid}', 'data.sh'))):
119
+ elif (
120
+ self.variable_type == VariableType.DATAFRAME or self.variable_type is None
121
+ ) and os.path.exists(
122
+ os.path.join(self.variable_path, f'{self.uuid}', 'data.sh')
123
+ ):
106
124
  self.variable_type = VariableType.GEO_DATAFRAME
107
- elif self.variable_type is None and \
108
- len(self.storage.listdir(self.variable_path, suffix='.parquet')) > 0 and \
109
- spark is not None:
125
+ elif (
126
+ self.variable_type is None
127
+ and len(self.storage.listdir(self.variable_path, suffix='.parquet')) > 0
128
+ and spark is not None
129
+ ):
110
130
  self.variable_type = VariableType.SPARK_DATAFRAME
111
131
 
112
132
  def convert_parquet_to_csv(self):
@@ -164,6 +184,12 @@ class Variable:
164
184
  sample=sample,
165
185
  sample_count=sample_count,
166
186
  )
187
+ elif self.variable_type == VariableType.POLARS_DATAFRAME:
188
+ return self.__read_polars_parquet(
189
+ raise_exception=raise_exception,
190
+ sample=sample,
191
+ sample_count=sample_count,
192
+ )
167
193
  elif self.variable_type == VariableType.SPARK_DATAFRAME:
168
194
  return self.__read_spark_parquet(sample=sample, sample_count=sample_count, spark=spark)
169
195
  elif self.variable_type == VariableType.GEO_DATAFRAME:
@@ -193,6 +219,11 @@ class Variable:
193
219
  """
194
220
  if self.variable_type == VariableType.DATAFRAME:
195
221
  return self.__read_parquet(sample=sample, sample_count=sample_count)
222
+ elif self.variable_type == VariableType.POLARS_DATAFRAME:
223
+ return self.__read_polars_parquet(
224
+ sample=sample,
225
+ sample_count=sample_count,
226
+ )
196
227
  elif self.variable_type == VariableType.SPARK_DATAFRAME:
197
228
  return self.__read_spark_parquet(sample=sample, sample_count=sample_count, spark=spark)
198
229
  elif self.variable_type == VariableType.DATAFRAME_ANALYSIS:
@@ -231,6 +262,12 @@ class Variable:
231
262
  elif is_geo_dataframe(data):
232
263
  self.variable_type = VariableType.GEO_DATAFRAME
233
264
 
265
+ # Dataframe analysis variables share the same uuid as the original dataframe variable
266
+ # so we won't write the metadata file for them
267
+ if self.variable_type == VariableType.DATAFRAME_ANALYSIS:
268
+ self.__write_dataframe_analysis(data)
269
+ return
270
+
234
271
  if self.variable_type == VariableType.DATAFRAME:
235
272
  self.__write_parquet(data)
236
273
  elif self.variable_type == VariableType.POLARS_DATAFRAME:
@@ -239,11 +276,11 @@ class Variable:
239
276
  self.__write_spark_parquet(data)
240
277
  elif self.variable_type == VariableType.GEO_DATAFRAME:
241
278
  self.__write_geo_dataframe(data)
242
- elif self.variable_type == VariableType.DATAFRAME_ANALYSIS:
243
- self.__write_dataframe_analysis(data)
244
279
  else:
245
280
  self.__write_json(data)
246
281
 
282
+ self.write_metadata()
283
+
247
284
  async def write_data_async(self, data: Any) -> None:
248
285
  """
249
286
  Write variable data to the persistent storage.
@@ -260,6 +297,10 @@ class Variable:
260
297
  elif is_geo_dataframe(data):
261
298
  self.variable_type = VariableType.GEO_DATAFRAME
262
299
 
300
+ if self.variable_type == VariableType.DATAFRAME_ANALYSIS:
301
+ self.__write_dataframe_analysis(data)
302
+ return
303
+
263
304
  if self.variable_type == VariableType.DATAFRAME:
264
305
  self.__write_parquet(data)
265
306
  elif self.variable_type == VariableType.POLARS_DATAFRAME:
@@ -268,11 +309,22 @@ class Variable:
268
309
  self.__write_spark_parquet(data)
269
310
  elif self.variable_type == VariableType.GEO_DATAFRAME:
270
311
  self.__write_geo_dataframe(data)
271
- elif self.variable_type == VariableType.DATAFRAME_ANALYSIS:
272
- self.__write_dataframe_analysis(data)
273
312
  else:
274
313
  await self.__write_json_async(data)
275
314
 
315
+ self.write_metadata()
316
+
317
+ def write_metadata(self) -> None:
318
+ """
319
+ Write metadata to the persistent storage.
320
+ """
321
+ metadata = dict(
322
+ type=self.variable_type.value
323
+ if isinstance(self.variable_type, VariableType)
324
+ else self.variable_type,
325
+ )
326
+ self.storage.write_json_file(self.metadata_path, metadata)
327
+
276
328
  def __delete_dataframe_analysis(self) -> None:
277
329
  for k in DATAFRAME_ANALYSIS_KEYS:
278
330
  file_path = os.path.join(self.variable_path, f'{k}.json')
@@ -300,7 +352,7 @@ class Variable:
300
352
  self,
301
353
  default_value: Dict = None,
302
354
  raise_exception: bool = False,
303
- sample: bool = False
355
+ sample: bool = False,
304
356
  ) -> Dict:
305
357
  if default_value is None:
306
358
  default_value = {}
@@ -443,6 +495,51 @@ class Variable:
443
495
  df = cast_column_types(df, column_types)
444
496
  return df
445
497
 
498
+ def __read_polars_parquet(
499
+ self,
500
+ sample: bool = False,
501
+ sample_count: int = None,
502
+ raise_exception: bool = False,
503
+ ) -> pl.DataFrame:
504
+ file_path = os.path.join(self.variable_path, DATAFRAME_PARQUET_FILE)
505
+ sample_file_path = os.path.join(
506
+ self.variable_path, DATAFRAME_PARQUET_SAMPLE_FILE
507
+ )
508
+
509
+ read_sample_success = False
510
+ if sample:
511
+ try:
512
+ df = self.storage.read_polars_parquet(sample_file_path, use_pyarrow=True)
513
+ read_sample_success = True
514
+ except Exception as ex:
515
+ if raise_exception:
516
+ raise Exception(
517
+ f'Failed to read parquet file: {sample_file_path}'
518
+ ) from ex
519
+ else:
520
+ traceback.print_exc()
521
+ if not read_sample_success:
522
+ try:
523
+ df = self.storage.read_polars_parquet(file_path, use_pyarrow=True)
524
+ except Exception as ex:
525
+ if raise_exception:
526
+ raise Exception(f'Failed to read parquet file: {file_path}') from ex
527
+ else:
528
+ traceback.print_exc()
529
+ df = pl.DataFrame()
530
+ if sample:
531
+ sample_count = sample_count or DATAFRAME_SAMPLE_COUNT
532
+ if df.shape[0] > sample_count:
533
+ df = df.head(sample_count)
534
+
535
+ column_types_filename = os.path.join(self.variable_path, DATAFRAME_COLUMN_TYPES_FILE)
536
+ if self.storage.path_exists(column_types_filename):
537
+ column_types = self.storage.read_json_file(column_types_filename)
538
+ # No Mage specific code to serialize columns for polars when writing a variable,
539
+ # so no need to deserialize columns here
540
+ df = cast_column_types_polars(df, column_types)
541
+ return df
542
+
446
543
  def __read_spark_parquet(self, sample: bool = False, sample_count: int = None, spark=None):
447
544
  if spark is None:
448
545
  return None
@@ -514,7 +611,7 @@ class Variable:
514
611
  pl_df = pl.from_pandas(df_output)
515
612
  self.__write_polars_dataframe(pl_df)
516
613
  # Test read dataframe from parquet
517
- self. __read_parquet(sample=True, raise_exception=True)
614
+ self.__read_parquet(sample=True, raise_exception=True)
518
615
 
519
616
  return
520
617
  except Exception:
@@ -536,7 +633,7 @@ class Variable:
536
633
  try:
537
634
  df_sample_output = df_output_serialized.iloc[
538
635
  :DATAFRAME_SAMPLE_COUNT,
539
- :DATAFRAME_SAMPLE_MAX_COLUMNS
636
+ :DATAFRAME_SAMPLE_MAX_COLUMNS,
540
637
  ]
541
638
 
542
639
  self.storage.write_parquet(
@@ -616,7 +713,8 @@ class Variable:
616
713
  if dataframe_analysis_keys is not None and k not in dataframe_analysis_keys:
617
714
  continue
618
715
  result[k] = await self.storage.read_json_file_async(
619
- os.path.join(self.variable_path, f'{k}.json'))
716
+ os.path.join(self.variable_path, f'{k}.json')
717
+ )
620
718
  return result
621
719
 
622
720
  def __write_dataframe_analysis(self, data: Dict[str, Dict]) -> None:
@@ -4,21 +4,24 @@ from typing import Callable, Dict
4
4
  from mage_ai.shared.hash import get_json_value, merge_dict
5
5
 
6
6
 
7
- def get_template_vars() -> Dict[str, Callable]:
7
+ def get_template_vars(include_python_libraries: Dict = None) -> Dict[str, Callable]:
8
8
  from mage_ai.data_preparation.shared.secrets import get_secret_value
9
- no_db_kwargs = get_template_vars_no_db()
9
+ no_db_kwargs = get_template_vars_no_db(include_python_libraries=include_python_libraries)
10
10
 
11
11
  kwargs = dict(mage_secret_var=get_secret_value)
12
12
 
13
13
  return merge_dict(no_db_kwargs, kwargs)
14
14
 
15
15
 
16
- def get_template_vars_no_db() -> Dict[str, Callable]:
16
+ def get_template_vars_no_db(include_python_libraries: Dict = None) -> Dict[str, Callable]:
17
17
  kwargs = dict(
18
18
  env_var=os.getenv,
19
19
  json_value=get_json_value,
20
20
  )
21
21
 
22
+ if include_python_libraries:
23
+ kwargs.update(include_python_libraries)
24
+
22
25
  try:
23
26
  from mage_ai.services.aws.secrets_manager.secrets_manager import get_secret
24
27
  kwargs['aws_secret_var'] = get_secret
@@ -2,6 +2,9 @@ from abc import ABC, abstractmethod
2
2
  from contextlib import contextmanager
3
3
  from typing import Dict, List
4
4
 
5
+ import pandas as pd
6
+ import polars as pl
7
+
5
8
 
6
9
  class BaseStorage(ABC):
7
10
  @abstractmethod
@@ -46,6 +49,20 @@ class BaseStorage(ABC):
46
49
  """
47
50
  pass
48
51
 
52
+ @abstractmethod
53
+ def read_parquet(self, file_path: str, **kwargs) -> pd.DataFrame:
54
+ """
55
+ Read parquet from a file with file path and return a pandas DataFrame.
56
+ """
57
+ pass
58
+
59
+ @abstractmethod
60
+ def read_polars_parquet(self, file_path: str, **kwargs) -> pl.DataFrame:
61
+ """
62
+ Read parquet from a file with file path and return a polars DataFrame.
63
+ """
64
+ pass
65
+
49
66
  @abstractmethod
50
67
  def read_json_file(
51
68
  self,
@@ -107,6 +107,10 @@ class GCSStorage(BaseStorage):
107
107
  buffer = io.BytesIO(self.bucket.blob(gcs_url_path(file_path)).download_as_bytes())
108
108
  return pd.read_parquet(buffer, **kwargs)
109
109
 
110
+ def read_polars_parquet(self, file_path: str, **kwargs) -> pl.DataFrame:
111
+ buffer = io.BytesIO(self.bucket.blob(gcs_url_path(file_path)).download_as_bytes())
112
+ return pl.read_parquet(buffer, **kwargs)
113
+
110
114
  def write_parquet(self, df: pd.DataFrame, file_path: str) -> None:
111
115
  buffer = io.BytesIO()
112
116
  df.to_parquet(buffer)
@@ -96,6 +96,9 @@ class LocalStorage(BaseStorage):
96
96
  def read_parquet(self, file_path: str, **kwargs) -> pd.DataFrame:
97
97
  return pd.read_parquet(file_path, engine='pyarrow')
98
98
 
99
+ def read_polars_parquet(self, file_path: str, **kwargs) -> pl.DataFrame:
100
+ return pl.read_parquet(file_path, use_pyarrow=True)
101
+
99
102
  def write_csv(self, df: pd.DataFrame, file_path: str) -> None:
100
103
  File.create_parent_directories(file_path)
101
104
  df.to_csv(file_path, index=False)
@@ -135,3 +138,15 @@ class LocalStorage(BaseStorage):
135
138
  except Exception as err:
136
139
  if is_debug():
137
140
  print(f'[ERROR] LocalStorage.read_async: {err}')
141
+
142
+ def read(self, file_path: str) -> str:
143
+ dirname = os.path.dirname(file_path)
144
+ if not os.path.isdir(dirname):
145
+ os.mkdir(dirname)
146
+
147
+ with open(file_path, mode='r') as file:
148
+ try:
149
+ return file.read()
150
+ except Exception as err:
151
+ if is_debug():
152
+ print(f'[ERROR] LocalStorage.read: {err}')
@@ -97,6 +97,10 @@ class S3Storage(BaseStorage):
97
97
  buffer = io.BytesIO(self.client.get_object(s3_url_path(file_path)).read())
98
98
  return pd.read_parquet(buffer, **kwargs)
99
99
 
100
+ def read_polars_parquet(self, file_path: str, **kwargs) -> pl.DataFrame:
101
+ buffer = io.BytesIO(self.client.get_object(s3_url_path(file_path)).read())
102
+ return pl.read_parquet(buffer, **kwargs)
103
+
100
104
  def write_parquet(self, df: pd.DataFrame, file_path: str) -> None:
101
105
  buffer = io.BytesIO()
102
106
  df.to_parquet(buffer)
@@ -5,7 +5,6 @@ from pandas import DataFrame
5
5
  from mage_ai.settings.repo import get_repo_path
6
6
  from mage_ai.io.config import ConfigFileLoader
7
7
  from mage_ai.io.qdrant import Qdrant
8
- from sentence_transformers import SentenceTransformer
9
8
 
10
9
  if 'data_exporter' not in globals():
11
10
  from mage_ai.data_preparation.decorators import data_exporter
@@ -8,9 +8,10 @@ from os import path
8
8
  {{ super() -}}
9
9
  {% endblock %}
10
10
 
11
- DEFAULT_MODEL = 'all-MiniLM-L6-v2'
12
11
 
13
12
  {% block content %}
13
+ DEFAULT_MODEL = 'all-MiniLM-L6-v2'
14
+
14
15
  @data_loader
15
16
  def load_data_from_qdrant(*args, **kwargs):
16
17
  """
@@ -71,6 +71,7 @@ class VariableManager:
71
71
  variable_type=variable_type,
72
72
  clean_block_uuid=clean_block_uuid,
73
73
  )
74
+
74
75
  # Delete data if it exists
75
76
  variable.delete()
76
77
  variable.variable_type = variable_type