mage-ai 0.9.44__py3-none-any.whl → 0.9.46__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 (540) hide show
  1. mage_ai/api/constants.py +2 -0
  2. mage_ai/api/operations/base.py +208 -12
  3. mage_ai/api/policies/BasePolicy.py +3 -3
  4. mage_ai/api/policies/ComputeClusterPolicy.py +96 -0
  5. mage_ai/api/policies/ComputeConnectionPolicy.py +74 -0
  6. mage_ai/api/policies/ComputeServicePolicy.py +50 -0
  7. mage_ai/api/policies/DownloadPolicy.py +29 -0
  8. mage_ai/api/policies/GitCustomBranchPolicy.py +1 -0
  9. mage_ai/api/policies/GlobalHookPolicy.py +126 -0
  10. mage_ai/api/policies/OauthPolicy.py +56 -7
  11. mage_ai/api/policies/ProjectPolicy.py +1 -0
  12. mage_ai/api/policies/RolePolicy.py +12 -1
  13. mage_ai/api/presenters/ComputeClusterPresenter.py +19 -0
  14. mage_ai/api/presenters/ComputeConnectionPresenter.py +26 -0
  15. mage_ai/api/presenters/ComputeServicePresenter.py +15 -0
  16. mage_ai/api/presenters/DownloadPresenter.py +13 -0
  17. mage_ai/api/presenters/GlobalHookPresenter.py +74 -0
  18. mage_ai/api/presenters/OauthPresenter.py +1 -0
  19. mage_ai/api/presenters/PipelinePresenter.py +1 -0
  20. mage_ai/api/presenters/ProjectPresenter.py +1 -0
  21. mage_ai/api/presenters/SparkApplicationPresenter.py +2 -0
  22. mage_ai/api/presenters/WorkspacePresenter.py +22 -22
  23. mage_ai/api/resources/AsyncBaseResource.py +39 -0
  24. mage_ai/api/resources/BackfillResource.py +1 -0
  25. mage_ai/api/resources/BlockResource.py +57 -0
  26. mage_ai/api/resources/ClusterResource.py +1 -1
  27. mage_ai/api/resources/ComputeClusterResource.py +109 -0
  28. mage_ai/api/resources/ComputeConnectionResource.py +103 -0
  29. mage_ai/api/resources/ComputeServiceResource.py +35 -0
  30. mage_ai/api/resources/DownloadResource.py +56 -0
  31. mage_ai/api/resources/ExecutionStateResource.py +1 -1
  32. mage_ai/api/resources/GitBranchResource.py +35 -29
  33. mage_ai/api/resources/GitCustomBranchResource.py +9 -0
  34. mage_ai/api/resources/GlobalHookResource.py +192 -0
  35. mage_ai/api/resources/KernelResource.py +10 -0
  36. mage_ai/api/resources/OauthResource.py +60 -98
  37. mage_ai/api/resources/PipelineResource.py +4 -4
  38. mage_ai/api/resources/PipelineScheduleResource.py +37 -16
  39. mage_ai/api/resources/ProjectResource.py +5 -3
  40. mage_ai/api/resources/SessionResource.py +24 -9
  41. mage_ai/api/resources/SparkApplicationResource.py +5 -5
  42. mage_ai/api/resources/SparkEnvironmentResource.py +1 -2
  43. mage_ai/api/resources/SparkExecutorResource.py +1 -2
  44. mage_ai/api/resources/SparkJobResource.py +3 -6
  45. mage_ai/api/resources/SparkSqlResource.py +6 -11
  46. mage_ai/api/resources/SparkStageAttemptResource.py +2 -3
  47. mage_ai/api/resources/SparkStageAttemptTaskResource.py +1 -2
  48. mage_ai/api/resources/SparkStageAttemptTaskSummaryResource.py +1 -2
  49. mage_ai/api/resources/SparkStageResource.py +3 -6
  50. mage_ai/api/resources/SparkThreadResource.py +1 -2
  51. mage_ai/api/resources/UserResource.py +32 -31
  52. mage_ai/api/resources/mixins/spark.py +25 -4
  53. mage_ai/authentication/oauth/constants.py +4 -0
  54. mage_ai/authentication/oauth2.py +1 -3
  55. mage_ai/authentication/permissions/constants.py +4 -0
  56. mage_ai/authentication/providers/__init__.py +0 -0
  57. mage_ai/authentication/providers/active_directory.py +136 -0
  58. mage_ai/authentication/providers/constants.py +17 -0
  59. mage_ai/authentication/providers/ghe.py +81 -0
  60. mage_ai/authentication/providers/google.py +86 -0
  61. mage_ai/authentication/providers/oauth.py +60 -0
  62. mage_ai/authentication/providers/okta.py +101 -0
  63. mage_ai/authentication/providers/sso.py +20 -0
  64. mage_ai/authentication/providers/utils.py +12 -0
  65. mage_ai/cluster_manager/aws/emr_cluster_manager.py +2 -1
  66. mage_ai/cluster_manager/workspace/base.py +7 -3
  67. mage_ai/data_integrations/destinations/constants.py +2 -0
  68. mage_ai/data_preparation/executors/block_executor.py +3 -0
  69. mage_ai/data_preparation/executors/pipeline_executor.py +9 -0
  70. mage_ai/data_preparation/git/__init__.py +3 -3
  71. mage_ai/data_preparation/git/api.py +69 -35
  72. mage_ai/data_preparation/models/block/__init__.py +95 -60
  73. mage_ai/data_preparation/models/block/data_integration/data.py +1 -1
  74. mage_ai/data_preparation/models/block/dbt/block_sql.py +95 -1
  75. mage_ai/data_preparation/models/block/dbt/utils.py +6 -0
  76. mage_ai/data_preparation/models/block/spark/mixins.py +82 -34
  77. mage_ai/data_preparation/models/download/__init__.py +8 -0
  78. mage_ai/data_preparation/models/global_hooks/__init__.py +0 -0
  79. mage_ai/data_preparation/models/global_hooks/constants.py +44 -0
  80. mage_ai/data_preparation/models/global_hooks/models.py +928 -0
  81. mage_ai/data_preparation/models/global_hooks/utils.py +21 -0
  82. mage_ai/data_preparation/models/pipeline.py +82 -6
  83. mage_ai/data_preparation/models/pipelines/models.py +16 -0
  84. mage_ai/data_preparation/models/project/__init__.py +6 -0
  85. mage_ai/data_preparation/models/project/constants.py +1 -0
  86. mage_ai/data_preparation/models/project/models.py +12 -0
  87. mage_ai/data_preparation/repo_manager.py +23 -1
  88. mage_ai/data_preparation/templates/callbacks/base.jinja +4 -0
  89. mage_ai/data_preparation/templates/data_exporters/streaming/kafka.yaml +1 -0
  90. mage_ai/data_preparation/templates/data_loaders/streaming/activemq.yaml +6 -0
  91. mage_ai/data_preparation/templates/data_loaders/streaming/kafka.yaml +1 -0
  92. mage_ai/data_preparation/templates/data_loaders/streaming/nats.yaml +20 -0
  93. mage_ai/data_preparation/templates/repo/io_config.yaml +2 -2
  94. mage_ai/io/duckdb.py +0 -1
  95. mage_ai/orchestration/concurrency.py +8 -1
  96. mage_ai/orchestration/db/models/schedules.py +23 -2
  97. mage_ai/orchestration/pipeline_scheduler.py +168 -105
  98. mage_ai/orchestration/queue/process_queue.py +9 -1
  99. mage_ai/orchestration/triggers/api.py +11 -3
  100. mage_ai/orchestration/triggers/constants.py +1 -0
  101. mage_ai/orchestration/triggers/utils.py +23 -0
  102. mage_ai/server/active_kernel.py +37 -4
  103. mage_ai/server/api/downloads.py +76 -1
  104. mage_ai/server/api/triggers.py +1 -0
  105. mage_ai/server/constants.py +1 -1
  106. mage_ai/server/frontend_dist/404.html +2 -2
  107. mage_ai/server/frontend_dist/_next/static/9jB4XPuz6BzxBcG9VNao5/_buildManifest.js +1 -0
  108. mage_ai/server/frontend_dist/_next/static/chunks/1749-9a6276b2918fdae1.js +1 -0
  109. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/7519-8c29bbb92e03cc77.js → frontend_dist/_next/static/chunks/1845-5ce774d5ab81ed57.js} +1 -1
  110. mage_ai/server/frontend_dist/_next/static/chunks/1952-ac7722e8b1ab88fe.js +1 -0
  111. mage_ai/server/frontend_dist/_next/static/chunks/3419-f8d518d024e7b5c8.js +1 -0
  112. mage_ai/server/frontend_dist/_next/static/chunks/4267-fd4d8049e83178de.js +1 -0
  113. mage_ai/server/frontend_dist/_next/static/chunks/4366-93e09e5a4a7e182c.js +1 -0
  114. mage_ai/server/frontend_dist/_next/static/chunks/5457-949640f4037bf12f.js +1 -0
  115. mage_ai/server/frontend_dist/_next/static/chunks/5499-76cf8f023c6b0985.js +1 -0
  116. mage_ai/server/frontend_dist/_next/static/chunks/553-7f7919e14392ca67.js +1 -0
  117. mage_ai/server/frontend_dist/_next/static/chunks/5638-a65610405a70961c.js +1 -0
  118. mage_ai/server/frontend_dist/_next/static/chunks/5810-12eadc488265d55b.js +1 -0
  119. mage_ai/server/frontend_dist/_next/static/chunks/5820-28adeabb5cda2b96.js +1 -0
  120. mage_ai/server/frontend_dist/_next/static/chunks/595-0d174b1f9fbfce4f.js +1 -0
  121. mage_ai/server/frontend_dist/_next/static/chunks/600-705fe234320ec5de.js +1 -0
  122. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/3122-f27de34d0b5426af.js → frontend_dist/_next/static/chunks/6285-e9b45335bfb9ccaf.js} +1 -1
  123. mage_ai/server/frontend_dist/_next/static/chunks/6333-bc1b433b428a9095.js +1 -0
  124. mage_ai/server/frontend_dist/_next/static/chunks/{5397-b5f2e477acc6bd6b.js → 6965-c613d1834c8ed92d.js} +1 -1
  125. mage_ai/server/frontend_dist/_next/static/chunks/{7022-18fde36eb46e1d65.js → 7022-070ec0144a4d029c.js} +1 -1
  126. mage_ai/server/frontend_dist/_next/static/chunks/722-a1584445357a276c.js +1 -0
  127. mage_ai/server/frontend_dist/_next/static/chunks/{7858-c83d25349d0e980f.js → 7858-d9df72e95e438284.js} +1 -1
  128. mage_ai/server/frontend_dist/_next/static/chunks/8264-0d582a6ca33c3dfa.js +1 -0
  129. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/3684-cbda680fd8927d07.js → frontend_dist/_next/static/chunks/8432-f191e39f9b5893f2.js} +1 -1
  130. mage_ai/server/frontend_dist/_next/static/chunks/90-a7308bae028d7001.js +1 -0
  131. mage_ai/server/frontend_dist/_next/static/chunks/9264-1d4f0327d42fed91.js +1 -0
  132. mage_ai/server/frontend_dist/_next/static/chunks/9618-2c5045255ac5a6e7.js +1 -0
  133. mage_ai/server/frontend_dist/_next/static/chunks/{976-27c4eed1c9b20c44.js → 976-18c98af60b76f1a7.js} +1 -1
  134. mage_ai/server/frontend_dist/_next/static/chunks/framework-22b71764bf44ede4.js +1 -0
  135. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-ebef928183f9a3bb.js +1 -0
  136. mage_ai/server/frontend_dist/_next/static/chunks/pages/block-layout-a24cb24b6f08bbc9.js +1 -0
  137. mage_ai/server/frontend_dist/_next/static/chunks/pages/compute-419775ca1293b354.js +1 -0
  138. mage_ai/server/frontend_dist/_next/static/chunks/pages/files-0f2d4be6fdca86ca.js +1 -0
  139. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/{[...slug]-3f6fc312f67ff72e.js → [...slug]-cfd68e760ae00958.js} +1 -1
  140. mage_ai/server/frontend_dist/_next/static/chunks/pages/{global-data-products-f4cd03036c3e8723.js → global-data-products-c3b79ef31007f95b.js} +1 -1
  141. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-77edfa32d000e88b.js +1 -0
  142. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks-e561ae38cf5592e8.js +1 -0
  143. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/files-449a022f2f0f2d94.js +1 -0
  144. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-60845f0b59142f32.js +1 -0
  145. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-1d9b298fdceabbf1.js → frontend_dist/_next/static/chunks/pages/manage/users/[user]-9384c5f1efa2ac18.js} +1 -1
  146. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-abd8571907664fdf.js +1 -0
  147. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/{users-a7c970122a10afdc.js → users-28a930b148d99766.js} +1 -1
  148. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-f83deb790548693b.js +1 -0
  149. mage_ai/server/frontend_dist/_next/static/chunks/pages/oauth-8bb62c4f6a511c43.js +1 -0
  150. mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-f0c40645f385f23f.js +1 -0
  151. mage_ai/server/frontend_dist/_next/static/chunks/pages/{pipeline-runs-c79819d6826e5416.js → pipeline-runs-b35d37bfba8fbccc.js} +1 -1
  152. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-10e9a2d19541caa2.js +1 -0
  153. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-c8d3a5289ab93f88.js +1 -0
  154. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-571c0962333b92f0.js +1 -0
  155. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-ff7e9108502f5716.js +1 -0
  156. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-a52d2d3e0c2978f4.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-ef680455ae54ccbe.js} +1 -1
  157. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-ddddcddd2f74b4f6.js +1 -0
  158. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-4a238307feddb522.js +1 -0
  159. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-e051057d9fe94f23.js +1 -0
  160. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/{[run]-4977276c8f84b5f4.js → [run]-0691711636fa95c7.js} +1 -1
  161. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-ce717786f31e8f04.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-2d20b2cd08907afd.js} +1 -1
  162. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-2914e326a5f1ffe0.js +1 -0
  163. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-b75bf17498e87354.js +1 -0
  164. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-3a7500e6e53084d3.js +1 -0
  165. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-c0e551d265a8d467.js +1 -0
  166. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/{[pipeline]-35fe7762cb83a733.js → [pipeline]-02c843b9c8418bb5.js} +1 -1
  167. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-e47db5c3eaf683af.js +1 -0
  168. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-55ac955dfa9a5a8d.js +1 -0
  169. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-d6a62284c7c99cb3.js → [...slug]-b78b1be5b9ed84b9.js} +1 -1
  170. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{permissions-b1389695f758c32b.js → permissions-37b78a436eeab258.js} +1 -1
  171. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-29c92a9bc54ae5cd.js +1 -0
  172. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-0bdb66265286ab22.js → [...slug]-db05a80d18c168e5.js} +1 -1
  173. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{roles-e04e18fc295ca76a.js → roles-f55c77e4f46c8d33.js} +1 -1
  174. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-2a1f8737561fdd94.js +1 -0
  175. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-0267358c91122109.js → [...slug]-e3bf6e5d8bb250c4.js} +1 -1
  176. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{users-50fed18bb9b8d142.js → users-20f0a050a42a015d.js} +1 -1
  177. mage_ai/server/frontend_dist/_next/static/chunks/pages/{settings-56f83205752b1323.js → settings-0f0121db7f5ff93d.js} +1 -1
  178. mage_ai/server/frontend_dist/_next/static/chunks/pages/sign-in-99e2748e3c1d57a3.js +1 -0
  179. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/templates/[...slug]-9370551ffa462144.js → frontend_dist/_next/static/chunks/pages/templates/[...slug]-f44ccd1499ffd23a.js} +1 -1
  180. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/templates-3cff90df13a1a755.js → frontend_dist/_next/static/chunks/pages/templates-1bfaa1c50e844813.js} +1 -1
  181. mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-ed121e305169cf1c.js +1 -0
  182. mage_ai/server/frontend_dist/_next/static/chunks/pages/test-9ae68758102cc843.js +1 -0
  183. mage_ai/server/frontend_dist/_next/static/chunks/pages/{triggers-ffaab4c013e62ba1.js → triggers-572d82d6eb7a5d43.js} +1 -1
  184. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-2d26d80370a2e481.js +1 -0
  185. mage_ai/server/frontend_dist/block-layout.html +2 -2
  186. mage_ai/server/frontend_dist/compute.html +5 -5
  187. mage_ai/server/frontend_dist/files.html +5 -5
  188. mage_ai/server/frontend_dist/global-data-products/[...slug].html +5 -5
  189. mage_ai/server/frontend_dist/global-data-products.html +5 -5
  190. mage_ai/server/frontend_dist/global-hooks/[...slug].html +24 -0
  191. mage_ai/server/frontend_dist/global-hooks.html +24 -0
  192. mage_ai/server/frontend_dist/index.html +2 -2
  193. mage_ai/server/frontend_dist/manage/files.html +5 -5
  194. mage_ai/server/frontend_dist/manage/settings.html +5 -5
  195. mage_ai/server/frontend_dist/manage/users/[user].html +5 -5
  196. mage_ai/server/frontend_dist/manage/users/new.html +5 -5
  197. mage_ai/server/frontend_dist/manage/users.html +5 -5
  198. mage_ai/server/frontend_dist/manage.html +5 -5
  199. mage_ai/server/frontend_dist/oauth.html +4 -4
  200. mage_ai/server/frontend_dist/overview.html +5 -5
  201. mage_ai/server/frontend_dist/pipeline-runs.html +5 -5
  202. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +5 -5
  203. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +5 -5
  204. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +5 -5
  205. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +2 -2
  206. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +5 -5
  207. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +5 -5
  208. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +5 -5
  209. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +5 -5
  210. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +5 -5
  211. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +5 -5
  212. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +5 -5
  213. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +5 -5
  214. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +5 -5
  215. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +5 -5
  216. mage_ai/server/frontend_dist/pipelines/[pipeline].html +2 -2
  217. mage_ai/server/frontend_dist/pipelines.html +5 -5
  218. mage_ai/server/frontend_dist/settings/account/profile.html +5 -5
  219. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +5 -5
  220. mage_ai/server/frontend_dist/settings/workspace/permissions.html +5 -5
  221. mage_ai/server/frontend_dist/settings/workspace/preferences.html +5 -5
  222. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +5 -5
  223. mage_ai/server/frontend_dist/settings/workspace/roles.html +5 -5
  224. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +5 -5
  225. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +5 -5
  226. mage_ai/server/frontend_dist/settings/workspace/users.html +5 -5
  227. mage_ai/server/frontend_dist/settings.html +2 -2
  228. mage_ai/server/frontend_dist/sign-in.html +17 -17
  229. mage_ai/server/frontend_dist/templates/[...slug].html +5 -5
  230. mage_ai/server/frontend_dist/templates.html +5 -5
  231. mage_ai/server/frontend_dist/terminal.html +5 -5
  232. mage_ai/server/frontend_dist/test.html +15 -15
  233. mage_ai/server/frontend_dist/triggers.html +5 -5
  234. mage_ai/server/frontend_dist/version-control.html +5 -5
  235. mage_ai/server/frontend_dist_base_path_template/404.html +2 -2
  236. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1749-9a6276b2918fdae1.js +1 -0
  237. mage_ai/server/{frontend_dist/_next/static/chunks/7519-8c29bbb92e03cc77.js → frontend_dist_base_path_template/_next/static/chunks/1845-5ce774d5ab81ed57.js} +1 -1
  238. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1952-ac7722e8b1ab88fe.js +1 -0
  239. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3419-f8d518d024e7b5c8.js +1 -0
  240. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4267-fd4d8049e83178de.js +1 -0
  241. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4366-93e09e5a4a7e182c.js +1 -0
  242. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-949640f4037bf12f.js +1 -0
  243. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5499-76cf8f023c6b0985.js +1 -0
  244. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/553-7f7919e14392ca67.js +1 -0
  245. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5638-a65610405a70961c.js +1 -0
  246. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5810-12eadc488265d55b.js +1 -0
  247. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5820-28adeabb5cda2b96.js +1 -0
  248. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/595-0d174b1f9fbfce4f.js +1 -0
  249. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/600-705fe234320ec5de.js +1 -0
  250. mage_ai/server/{frontend_dist/_next/static/chunks/3122-f27de34d0b5426af.js → frontend_dist_base_path_template/_next/static/chunks/6285-e9b45335bfb9ccaf.js} +1 -1
  251. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6333-bc1b433b428a9095.js +1 -0
  252. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{5397-b5f2e477acc6bd6b.js → 6965-c613d1834c8ed92d.js} +1 -1
  253. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{7022-18fde36eb46e1d65.js → 7022-070ec0144a4d029c.js} +1 -1
  254. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/722-a1584445357a276c.js +1 -0
  255. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{7858-c83d25349d0e980f.js → 7858-d9df72e95e438284.js} +1 -1
  256. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8264-0d582a6ca33c3dfa.js +1 -0
  257. mage_ai/server/{frontend_dist/_next/static/chunks/3684-cbda680fd8927d07.js → frontend_dist_base_path_template/_next/static/chunks/8432-f191e39f9b5893f2.js} +1 -1
  258. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/90-a7308bae028d7001.js +1 -0
  259. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9264-1d4f0327d42fed91.js +1 -0
  260. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9618-2c5045255ac5a6e7.js +1 -0
  261. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{976-27c4eed1c9b20c44.js → 976-18c98af60b76f1a7.js} +1 -1
  262. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/framework-22b71764bf44ede4.js +1 -0
  263. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-ebef928183f9a3bb.js +1 -0
  264. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/block-layout-a24cb24b6f08bbc9.js +1 -0
  265. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/compute-419775ca1293b354.js +1 -0
  266. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-0f2d4be6fdca86ca.js +1 -0
  267. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/{[...slug]-3f6fc312f67ff72e.js → [...slug]-cfd68e760ae00958.js} +1 -1
  268. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{global-data-products-f4cd03036c3e8723.js → global-data-products-c3b79ef31007f95b.js} +1 -1
  269. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-77edfa32d000e88b.js +1 -0
  270. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks-e561ae38cf5592e8.js +1 -0
  271. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/files-449a022f2f0f2d94.js +1 -0
  272. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-60845f0b59142f32.js +1 -0
  273. mage_ai/server/{frontend_dist/_next/static/chunks/pages/manage/users/[user]-1d9b298fdceabbf1.js → frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-9384c5f1efa2ac18.js} +1 -1
  274. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-abd8571907664fdf.js +1 -0
  275. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/{users-a7c970122a10afdc.js → users-28a930b148d99766.js} +1 -1
  276. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-f83deb790548693b.js +1 -0
  277. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/oauth-8bb62c4f6a511c43.js +1 -0
  278. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-f0c40645f385f23f.js +1 -0
  279. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{pipeline-runs-c79819d6826e5416.js → pipeline-runs-b35d37bfba8fbccc.js} +1 -1
  280. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-10e9a2d19541caa2.js +1 -0
  281. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-c8d3a5289ab93f88.js +1 -0
  282. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-571c0962333b92f0.js +1 -0
  283. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-ff7e9108502f5716.js +1 -0
  284. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-a52d2d3e0c2978f4.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-ef680455ae54ccbe.js} +1 -1
  285. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-ddddcddd2f74b4f6.js +1 -0
  286. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-4a238307feddb522.js +1 -0
  287. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-e051057d9fe94f23.js +1 -0
  288. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/{[run]-4977276c8f84b5f4.js → [run]-0691711636fa95c7.js} +1 -1
  289. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-ce717786f31e8f04.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-2d20b2cd08907afd.js} +1 -1
  290. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-2914e326a5f1ffe0.js +1 -0
  291. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-b75bf17498e87354.js +1 -0
  292. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-3a7500e6e53084d3.js +1 -0
  293. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-c0e551d265a8d467.js +1 -0
  294. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/{[pipeline]-35fe7762cb83a733.js → [pipeline]-02c843b9c8418bb5.js} +1 -1
  295. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-e47db5c3eaf683af.js +1 -0
  296. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-55ac955dfa9a5a8d.js +1 -0
  297. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-d6a62284c7c99cb3.js → [...slug]-b78b1be5b9ed84b9.js} +1 -1
  298. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{permissions-b1389695f758c32b.js → permissions-37b78a436eeab258.js} +1 -1
  299. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-29c92a9bc54ae5cd.js +1 -0
  300. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-0bdb66265286ab22.js → [...slug]-db05a80d18c168e5.js} +1 -1
  301. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{roles-e04e18fc295ca76a.js → roles-f55c77e4f46c8d33.js} +1 -1
  302. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-2a1f8737561fdd94.js +1 -0
  303. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-0267358c91122109.js → [...slug]-e3bf6e5d8bb250c4.js} +1 -1
  304. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{users-50fed18bb9b8d142.js → users-20f0a050a42a015d.js} +1 -1
  305. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{settings-56f83205752b1323.js → settings-0f0121db7f5ff93d.js} +1 -1
  306. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-99e2748e3c1d57a3.js +1 -0
  307. mage_ai/server/{frontend_dist/_next/static/chunks/pages/templates/[...slug]-9370551ffa462144.js → frontend_dist_base_path_template/_next/static/chunks/pages/templates/[...slug]-f44ccd1499ffd23a.js} +1 -1
  308. mage_ai/server/{frontend_dist/_next/static/chunks/pages/templates-3cff90df13a1a755.js → frontend_dist_base_path_template/_next/static/chunks/pages/templates-1bfaa1c50e844813.js} +1 -1
  309. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-ed121e305169cf1c.js +1 -0
  310. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-9ae68758102cc843.js +1 -0
  311. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{triggers-ffaab4c013e62ba1.js → triggers-572d82d6eb7a5d43.js} +1 -1
  312. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-2d26d80370a2e481.js +1 -0
  313. mage_ai/server/frontend_dist_base_path_template/_next/static/uPDjJYpJMst1q6psbRyte/_buildManifest.js +1 -0
  314. mage_ai/server/frontend_dist_base_path_template/block-layout.html +2 -2
  315. mage_ai/server/frontend_dist_base_path_template/compute.html +2 -2
  316. mage_ai/server/frontend_dist_base_path_template/files.html +2 -2
  317. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +2 -2
  318. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +2 -2
  319. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +24 -0
  320. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +24 -0
  321. mage_ai/server/frontend_dist_base_path_template/index.html +2 -2
  322. mage_ai/server/frontend_dist_base_path_template/manage/files.html +2 -2
  323. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +2 -2
  324. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +2 -2
  325. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +2 -2
  326. mage_ai/server/frontend_dist_base_path_template/manage/users.html +2 -2
  327. mage_ai/server/frontend_dist_base_path_template/manage.html +2 -2
  328. mage_ai/server/frontend_dist_base_path_template/oauth.html +3 -3
  329. mage_ai/server/frontend_dist_base_path_template/overview.html +2 -2
  330. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +2 -2
  331. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +2 -2
  332. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +2 -2
  333. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +2 -2
  334. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +2 -2
  335. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +2 -2
  336. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +2 -2
  337. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +2 -2
  338. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +2 -2
  339. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +2 -2
  340. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +2 -2
  341. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +2 -2
  342. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +2 -2
  343. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +2 -2
  344. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +2 -2
  345. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +2 -2
  346. mage_ai/server/frontend_dist_base_path_template/pipelines.html +2 -2
  347. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +2 -2
  348. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +2 -2
  349. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +2 -2
  350. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +2 -2
  351. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +2 -2
  352. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +2 -2
  353. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +2 -2
  354. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +2 -2
  355. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +2 -2
  356. mage_ai/server/frontend_dist_base_path_template/settings.html +2 -2
  357. mage_ai/server/frontend_dist_base_path_template/sign-in.html +9 -9
  358. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +2 -2
  359. mage_ai/server/frontend_dist_base_path_template/templates.html +2 -2
  360. mage_ai/server/frontend_dist_base_path_template/terminal.html +2 -2
  361. mage_ai/server/frontend_dist_base_path_template/test.html +14 -14
  362. mage_ai/server/frontend_dist_base_path_template/triggers.html +2 -2
  363. mage_ai/server/frontend_dist_base_path_template/version-control.html +2 -2
  364. mage_ai/server/server.py +43 -15
  365. mage_ai/server/utils/output_display.py +6 -0
  366. mage_ai/server/websocket_server.py +14 -0
  367. mage_ai/services/aws/ecs/config.py +11 -8
  368. mage_ai/services/aws/emr/config.py +1 -0
  369. mage_ai/services/aws/emr/constants.py +1 -0
  370. mage_ai/services/aws/emr/emr.py +20 -7
  371. mage_ai/services/compute/__init__.py +0 -0
  372. mage_ai/services/compute/aws/__init__.py +0 -0
  373. mage_ai/services/compute/aws/constants.py +21 -0
  374. mage_ai/services/compute/aws/models.py +459 -0
  375. mage_ai/services/compute/aws/steps.py +482 -0
  376. mage_ai/services/compute/constants.py +27 -0
  377. mage_ai/services/compute/models.py +212 -0
  378. mage_ai/services/k8s/job_manager.py +3 -0
  379. mage_ai/services/spark/api/aws_emr.py +38 -0
  380. mage_ai/services/spark/api/base.py +7 -4
  381. mage_ai/services/spark/api/constants.py +4 -0
  382. mage_ai/services/spark/api/local.py +25 -24
  383. mage_ai/services/spark/api/service.py +15 -5
  384. mage_ai/services/spark/constants.py +1 -1
  385. mage_ai/services/spark/models/applications.py +45 -3
  386. mage_ai/services/spark/models/base.py +3 -19
  387. mage_ai/services/spark/models/environments.py +16 -11
  388. mage_ai/services/spark/models/executors.py +2 -2
  389. mage_ai/services/spark/models/sqls.py +46 -15
  390. mage_ai/services/spark/models/stages.py +55 -32
  391. mage_ai/services/spark/models/threads.py +2 -2
  392. mage_ai/services/spark/utils.py +22 -6
  393. mage_ai/services/ssh/__init__.py +0 -0
  394. mage_ai/services/ssh/aws/__init__.py +0 -0
  395. mage_ai/services/ssh/aws/emr/__init__.py +0 -0
  396. mage_ai/services/ssh/aws/emr/constants.py +10 -0
  397. mage_ai/services/ssh/aws/emr/models.py +326 -0
  398. mage_ai/services/ssh/aws/emr/utils.py +151 -0
  399. mage_ai/settings/__init__.py +16 -1
  400. mage_ai/settings/secret_generation.py +7 -0
  401. mage_ai/settings/sso.py +20 -0
  402. mage_ai/shared/hash.py +17 -1
  403. mage_ai/shared/models.py +253 -0
  404. mage_ai/streaming/constants.py +2 -0
  405. mage_ai/streaming/sources/activemq.py +89 -0
  406. mage_ai/streaming/sources/nats_js.py +182 -0
  407. mage_ai/streaming/sources/source_factory.py +8 -0
  408. mage_ai/tests/ai/test_ai_functions.py +53 -8
  409. mage_ai/tests/api/endpoints/test_oauths.py +33 -0
  410. mage_ai/tests/api/endpoints/test_projects.py +1 -0
  411. mage_ai/tests/api/endpoints/test_workspaces.py +55 -0
  412. mage_ai/tests/api/operations/test_base.py +7 -5
  413. mage_ai/tests/api/operations/test_operations.py +0 -1
  414. mage_ai/tests/api/operations/test_operations_with_hooks.py +577 -0
  415. mage_ai/tests/api/operations/test_syncs.py +0 -1
  416. mage_ai/tests/api/operations/test_users.py +13 -2
  417. mage_ai/tests/data_preparation/executors/test_block_executor.py +1 -0
  418. mage_ai/tests/data_preparation/models/global_hooks/__init__.py +0 -0
  419. mage_ai/tests/data_preparation/models/global_hooks/test_global_hooks.py +575 -0
  420. mage_ai/tests/data_preparation/models/global_hooks/test_hook.py +760 -0
  421. mage_ai/tests/data_preparation/models/global_hooks/test_utils.py +33 -0
  422. mage_ai/tests/data_preparation/models/test_pipeline.py +5 -0
  423. mage_ai/tests/data_preparation/test_repo_manager.py +11 -0
  424. mage_ai/tests/data_preparation/test_templates.py +1 -0
  425. mage_ai/tests/factory.py +132 -10
  426. mage_ai/tests/orchestration/queue/test_process_queue.py +15 -2
  427. mage_ai/tests/orchestration/test_pipeline_scheduler.py +447 -79
  428. mage_ai/tests/services/aws/ecs/__init__.py +0 -0
  429. mage_ai/tests/services/aws/ecs/test_config.py +144 -0
  430. mage_ai/tests/services/k8s/test_job_manager.py +22 -1
  431. mage_ai/tests/shared/mixins.py +291 -0
  432. mage_ai/tests/shared/test_hash.py +17 -1
  433. mage_ai/tests/streaming/sources/test_activemq.py +32 -0
  434. mage_ai/tests/streaming/sources/test_nats_js.py +32 -0
  435. mage_ai/tests/streaming/sources/test_source_factory.py +26 -1
  436. {mage_ai-0.9.44.dist-info → mage_ai-0.9.46.dist-info}/METADATA +28 -66
  437. {mage_ai-0.9.44.dist-info → mage_ai-0.9.46.dist-info}/RECORD +443 -364
  438. mage_ai/authentication/oauth/active_directory.py +0 -17
  439. mage_ai/server/frontend_dist/_next/static/RPXiX8RpZ7oO-yeaEtV2c/_buildManifest.js +0 -1
  440. mage_ai/server/frontend_dist/_next/static/chunks/1125-91d3ce33140ef041.js +0 -1
  441. mage_ai/server/frontend_dist/_next/static/chunks/1749-607014ecf28268bf.js +0 -1
  442. mage_ai/server/frontend_dist/_next/static/chunks/1952-573c7fc7ad84da6e.js +0 -1
  443. mage_ai/server/frontend_dist/_next/static/chunks/3004-231cad9039ae5dcb.js +0 -1
  444. mage_ai/server/frontend_dist/_next/static/chunks/3419-0873e170ef7d6303.js +0 -1
  445. mage_ai/server/frontend_dist/_next/static/chunks/3932-0ceca9599d6e6d00.js +0 -1
  446. mage_ai/server/frontend_dist/_next/static/chunks/4267-335766a915ee2fa9.js +0 -1
  447. mage_ai/server/frontend_dist/_next/static/chunks/5457-8be2e0a3fe0ba64b.js +0 -1
  448. mage_ai/server/frontend_dist/_next/static/chunks/5499-bca977f466e259e1.js +0 -1
  449. mage_ai/server/frontend_dist/_next/static/chunks/553-edf533e634e85192.js +0 -1
  450. mage_ai/server/frontend_dist/_next/static/chunks/5810-37c6091b29a1fe53.js +0 -1
  451. mage_ai/server/frontend_dist/_next/static/chunks/600-0733eb84f0a0a9e0.js +0 -1
  452. mage_ai/server/frontend_dist/_next/static/chunks/6333-53b6ebbef95a3691.js +0 -1
  453. mage_ai/server/frontend_dist/_next/static/chunks/722-3fff38a9019369fe.js +0 -1
  454. mage_ai/server/frontend_dist/_next/static/chunks/8224-39a93ee1058b6069.js +0 -1
  455. mage_ai/server/frontend_dist/_next/static/chunks/8264-6ef8fdb195694807.js +0 -1
  456. mage_ai/server/frontend_dist/_next/static/chunks/9264-1b5c4b071ed544c3.js +0 -1
  457. mage_ai/server/frontend_dist/_next/static/chunks/framework-7c365855dab1bf41.js +0 -1
  458. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-a4a660fa14cf05a9.js +0 -1
  459. mage_ai/server/frontend_dist/_next/static/chunks/pages/block-layout-c465c14d48392b11.js +0 -1
  460. mage_ai/server/frontend_dist/_next/static/chunks/pages/compute-b1f8d5a7a9a30f2d.js +0 -1
  461. mage_ai/server/frontend_dist/_next/static/chunks/pages/files-93c094bad0f299fb.js +0 -1
  462. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/files-891e5bd5935f7473.js +0 -1
  463. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-d2e4ee4e68d36807.js +0 -1
  464. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-4a49126fcfe8ced0.js +0 -1
  465. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-5f8c5d0bc6ad1113.js +0 -1
  466. mage_ai/server/frontend_dist/_next/static/chunks/pages/oauth-09467512a85c96ed.js +0 -1
  467. mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-31bde04718d0d3a8.js +0 -1
  468. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-96718f95103d7844.js +0 -1
  469. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-a9266d353f288e8c.js +0 -1
  470. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-b5c29c852262312e.js +0 -1
  471. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-5d525454ff7aeb3f.js +0 -1
  472. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-883f4ae9a4a264c0.js +0 -1
  473. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-c65be964e6398cb7.js +0 -1
  474. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-1f5b4a974bd39740.js +0 -1
  475. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-074c32397d341de9.js +0 -1
  476. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-50f5d8706ed0bc73.js +0 -1
  477. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-e151c1552fcb67bd.js +0 -1
  478. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-cc36f0f8c73fee4b.js +0 -1
  479. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-8336c4326f1e7d96.js +0 -1
  480. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-01dd679e4a21e0d9.js +0 -1
  481. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-4d9051c073a9b2ff.js +0 -1
  482. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-88d41c33b8fcb300.js +0 -1
  483. mage_ai/server/frontend_dist/_next/static/chunks/pages/sign-in-d859e07561eb9010.js +0 -1
  484. mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-578d862f3e56e6e6.js +0 -1
  485. mage_ai/server/frontend_dist/_next/static/chunks/pages/test-1c0588d685b909b9.js +0 -1
  486. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-e284cf1535d93798.js +0 -1
  487. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1125-91d3ce33140ef041.js +0 -1
  488. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1749-607014ecf28268bf.js +0 -1
  489. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1952-573c7fc7ad84da6e.js +0 -1
  490. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3004-231cad9039ae5dcb.js +0 -1
  491. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3419-0873e170ef7d6303.js +0 -1
  492. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3932-0ceca9599d6e6d00.js +0 -1
  493. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4267-335766a915ee2fa9.js +0 -1
  494. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-8be2e0a3fe0ba64b.js +0 -1
  495. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5499-bca977f466e259e1.js +0 -1
  496. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/553-edf533e634e85192.js +0 -1
  497. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5810-37c6091b29a1fe53.js +0 -1
  498. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/600-0733eb84f0a0a9e0.js +0 -1
  499. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6333-53b6ebbef95a3691.js +0 -1
  500. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/722-3fff38a9019369fe.js +0 -1
  501. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8224-39a93ee1058b6069.js +0 -1
  502. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8264-6ef8fdb195694807.js +0 -1
  503. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9264-1b5c4b071ed544c3.js +0 -1
  504. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/framework-7c365855dab1bf41.js +0 -1
  505. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-a4a660fa14cf05a9.js +0 -1
  506. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/block-layout-c465c14d48392b11.js +0 -1
  507. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/compute-b1f8d5a7a9a30f2d.js +0 -1
  508. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-93c094bad0f299fb.js +0 -1
  509. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/files-891e5bd5935f7473.js +0 -1
  510. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-d2e4ee4e68d36807.js +0 -1
  511. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-4a49126fcfe8ced0.js +0 -1
  512. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-5f8c5d0bc6ad1113.js +0 -1
  513. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/oauth-09467512a85c96ed.js +0 -1
  514. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-31bde04718d0d3a8.js +0 -1
  515. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-96718f95103d7844.js +0 -1
  516. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-a9266d353f288e8c.js +0 -1
  517. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-b5c29c852262312e.js +0 -1
  518. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-5d525454ff7aeb3f.js +0 -1
  519. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-883f4ae9a4a264c0.js +0 -1
  520. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-c65be964e6398cb7.js +0 -1
  521. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-1f5b4a974bd39740.js +0 -1
  522. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-074c32397d341de9.js +0 -1
  523. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-50f5d8706ed0bc73.js +0 -1
  524. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-e151c1552fcb67bd.js +0 -1
  525. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-cc36f0f8c73fee4b.js +0 -1
  526. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-8336c4326f1e7d96.js +0 -1
  527. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-01dd679e4a21e0d9.js +0 -1
  528. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-4d9051c073a9b2ff.js +0 -1
  529. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-88d41c33b8fcb300.js +0 -1
  530. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-d859e07561eb9010.js +0 -1
  531. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-578d862f3e56e6e6.js +0 -1
  532. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-1c0588d685b909b9.js +0 -1
  533. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-e284cf1535d93798.js +0 -1
  534. mage_ai/server/frontend_dist_base_path_template/_next/static/rNR5JgSxO3eA2BWGa_i7U/_buildManifest.js +0 -1
  535. /mage_ai/server/frontend_dist/_next/static/{RPXiX8RpZ7oO-yeaEtV2c → 9jB4XPuz6BzxBcG9VNao5}/_ssgManifest.js +0 -0
  536. /mage_ai/server/frontend_dist_base_path_template/_next/static/{rNR5JgSxO3eA2BWGa_i7U → uPDjJYpJMst1q6psbRyte}/_ssgManifest.js +0 -0
  537. {mage_ai-0.9.44.dist-info → mage_ai-0.9.46.dist-info}/LICENSE +0 -0
  538. {mage_ai-0.9.44.dist-info → mage_ai-0.9.46.dist-info}/WHEEL +0 -0
  539. {mage_ai-0.9.44.dist-info → mage_ai-0.9.46.dist-info}/entry_points.txt +0 -0
  540. {mage_ai-0.9.44.dist-info → mage_ai-0.9.46.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,20 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Awaitable, Dict
3
+
4
+
5
+ class SsoProvider(ABC):
6
+ """
7
+ Base class for single sign on providers. Can be used in conjunction with OauthProvider.
8
+ """
9
+ @abstractmethod
10
+ async def get_user_info(self, **kwargs) -> Awaitable[Dict]:
11
+ """
12
+ This method should return a dictionary containing the user's information.
13
+
14
+ Returns:
15
+ Dict: dictionary with the following parameters
16
+ email (str): user's email
17
+ username (str): username
18
+ user_roles (List[Role], optional): list of user roles for the user
19
+ """
20
+ pass
@@ -0,0 +1,12 @@
1
+ from urllib.parse import unquote, urlparse
2
+
3
+ from mage_ai.settings import ROUTES_BASE_PATH
4
+
5
+
6
+ def get_base_url(url: str) -> str:
7
+ parsed_url = urlparse(unquote(url))
8
+ base_url = parsed_url.scheme + '://' + parsed_url.netloc
9
+ if ROUTES_BASE_PATH:
10
+ base_url += f'/{ROUTES_BASE_PATH}'
11
+
12
+ return base_url
@@ -51,6 +51,7 @@ class EmrClusterManager(ClusterManager):
51
51
 
52
52
  def set_active_cluster(
53
53
  self,
54
+ auto_creation: bool = True,
54
55
  auto_selection: bool = False,
55
56
  cluster_id=None,
56
57
  emr_config: Dict = None,
@@ -59,7 +60,7 @@ class EmrClusterManager(ClusterManager):
59
60
  clusters = self.list_clusters()
60
61
  if len(clusters) > 0:
61
62
  cluster_id = clusters[0]['id']
62
- else:
63
+ elif auto_creation:
63
64
  self.create_cluster(emr_config=emr_config)
64
65
  if cluster_id is None:
65
66
  return
@@ -10,6 +10,7 @@ from mage_ai.data_preparation.repo_manager import ProjectType, get_project_type
10
10
  from mage_ai.orchestration.constants import Entity
11
11
  from mage_ai.orchestration.db.models.oauth import User
12
12
  from mage_ai.settings.repo import get_repo_path
13
+ from mage_ai.shared.hash import merge_dict
13
14
 
14
15
 
15
16
  class classproperty(property):
@@ -25,7 +26,7 @@ class Workspace(abc.ABC):
25
26
  self._config = None
26
27
 
27
28
  @classproperty
28
- def project_folder(cls) -> str:
29
+ def project_folder(self) -> str:
29
30
  return os.path.join(get_repo_path(), 'projects')
30
31
 
31
32
  @property
@@ -48,7 +49,7 @@ class Workspace(abc.ABC):
48
49
 
49
50
  @property
50
51
  def project_uuid(self) -> Optional[str]:
51
- self.config.get('project_uuid')
52
+ return self.config.project_uuid
52
53
 
53
54
  def get_access(self, user: User) -> int:
54
55
  return user.get_access(Entity.PROJECT, self.project_uuid)
@@ -114,8 +115,11 @@ class Workspace(abc.ABC):
114
115
  data['project_uuid'] = project_uuid
115
116
 
116
117
  workspace_class = cls.workspace_class_from_type(cluster_type)
118
+
117
119
  try:
118
- return workspace_class.initialize(name, config_path, **payload, **data)
120
+ return workspace_class.initialize(
121
+ name, config_path, **merge_dict(payload, data)
122
+ )
119
123
  except Exception:
120
124
  if config_path and os.path.exists(config_path):
121
125
  os.remove(config_path)
@@ -2,9 +2,11 @@ DESTINATIONS = [
2
2
  dict(name='Amazon S3'),
3
3
  dict(name='BigQuery'),
4
4
  dict(name='Clickhouse'),
5
+ dict(name='Delta Lake Azure'),
5
6
  dict(name='Delta Lake S3'),
6
7
  dict(name='Elasticsearch'),
7
8
  dict(name='Google Cloud Storage'),
9
+ dict(name='Kafka'),
8
10
  dict(name='MongoDB'),
9
11
  dict(
10
12
  module_name='MSSQL',
@@ -557,6 +557,7 @@ class BlockExecutor:
557
557
  )
558
558
  self._execute_callback(
559
559
  'on_failure',
560
+ callback_kwargs=dict(__error=error),
560
561
  dynamic_block_index=dynamic_block_index,
561
562
  dynamic_upstream_block_uuids=dynamic_upstream_block_uuids,
562
563
  global_vars=global_vars,
@@ -1043,6 +1044,7 @@ class BlockExecutor:
1043
1044
  global_vars: Dict,
1044
1045
  logging_tags: Dict,
1045
1046
  pipeline_run: PipelineRun,
1047
+ callback_kwargs: Dict = None,
1046
1048
  dynamic_block_index: Union[int, None] = None,
1047
1049
  dynamic_upstream_block_uuids: Union[List[str], None] = None,
1048
1050
  ):
@@ -1068,6 +1070,7 @@ class BlockExecutor:
1068
1070
  try:
1069
1071
  callback_block.execute_callback(
1070
1072
  callback,
1073
+ callback_kwargs=callback_kwargs,
1071
1074
  dynamic_block_index=dynamic_block_index,
1072
1075
  dynamic_upstream_block_uuids=dynamic_upstream_block_uuids,
1073
1076
  execution_partition=self.execution_partition,
@@ -1,6 +1,9 @@
1
1
  import asyncio
2
+ from datetime import datetime
2
3
  from typing import Dict, List
3
4
 
5
+ import pytz
6
+
4
7
  from mage_ai.data_preparation.executors.block_executor import BlockExecutor
5
8
  from mage_ai.data_preparation.logging.logger import DictLogger
6
9
  from mage_ai.data_preparation.logging.logger_manager_factory import LoggerManagerFactory
@@ -93,6 +96,12 @@ class PipelineExecutor:
93
96
  block_uuid=block_run.block_uuid,
94
97
  execution_partition=self.execution_partition,
95
98
  )
99
+ block_run_data = dict(status=BlockRun.BlockRunStatus.RUNNING)
100
+ if not block_run.started_at or \
101
+ (block_run.metrics and not block_run.metrics.get('controller')):
102
+ block_run_data['started_at'] = datetime.now(tz=pytz.UTC)
103
+
104
+ block_run.update(**block_run_data)
96
105
  BlockExecutor(**executor_kwargs).execute(
97
106
  block_run_id=block_run.id,
98
107
  global_vars=global_vars,
@@ -59,7 +59,7 @@ class Git:
59
59
  if self.remote_repo_link:
60
60
  url = urlsplit(self.remote_repo_link)
61
61
 
62
- token = self.__get_access_token()
62
+ token = self.get_access_token()
63
63
 
64
64
  if self.git_config and url:
65
65
  user = self.git_config.username
@@ -299,7 +299,7 @@ class Git:
299
299
  url = urlsplit(submodule_url)
300
300
  if self.auth_type == AuthType.HTTPS:
301
301
  user = self.git_config.username
302
- token = self.__get_access_token()
302
+ token = self.get_access_token()
303
303
  url = url._replace(netloc=f'{user}:{token}@{url.netloc}')
304
304
  url = urlunsplit(url)
305
305
  # Overwrite the submodule URL with git credentials.
@@ -780,7 +780,7 @@ class Git:
780
780
  proc.kill()
781
781
  raise TimeoutError
782
782
 
783
- def __get_access_token(self) -> str:
783
+ def get_access_token(self) -> str:
784
784
  token = None
785
785
  if os.getenv(GIT_ACCESS_TOKEN_VAR):
786
786
  token = os.getenv(GIT_ACCESS_TOKEN_VAR)
@@ -27,10 +27,7 @@ def get_oauth_client_id(provider: str) -> str:
27
27
  return f'{provider}_{get_project_uuid()}'
28
28
 
29
29
 
30
- def get_access_token_for_user(
31
- user: User,
32
- provider: str = None
33
- ) -> Oauth2AccessToken:
30
+ def get_access_token_for_user(user: User, provider: str = None) -> Oauth2AccessToken:
34
31
  if not provider:
35
32
  provider = OAUTH_PROVIDER_GHE if get_ghe_hostname() else OAUTH_PROVIDER_GITHUB
36
33
  access_tokens = access_tokens_for_client(get_oauth_client_id(provider), user=user)
@@ -38,14 +35,19 @@ def get_access_token_for_user(
38
35
  return access_tokens[0]
39
36
 
40
37
 
41
- def fetch(remote_name: str, remote_url: str, token: str) -> RemoteProgress:
38
+ def fetch(
39
+ remote_name: str,
40
+ remote_url: str,
41
+ token: str,
42
+ user: User = None,
43
+ ) -> RemoteProgress:
42
44
  from mage_ai.data_preparation.git import Git
43
45
 
44
46
  custom_progress = RemoteProgress()
45
- username = get_username(token)
47
+ username = get_username(token, user=user)
46
48
 
47
49
  url = build_authenticated_remote_url(remote_url, username, token)
48
- git_manager = Git.get_manager()
50
+ git_manager = Git.get_manager(user=user)
49
51
 
50
52
  remote = git_manager.repo.remotes[remote_name]
51
53
  url_original = list(remote.urls)[0]
@@ -65,14 +67,20 @@ def fetch(remote_name: str, remote_url: str, token: str) -> RemoteProgress:
65
67
  return custom_progress
66
68
 
67
69
 
68
- def pull(remote_name: str, remote_url: str, branch_name: str, token: str) -> RemoteProgress:
70
+ def pull(
71
+ remote_name: str,
72
+ remote_url: str,
73
+ branch_name: str,
74
+ token: str,
75
+ user: User = None,
76
+ ) -> RemoteProgress:
69
77
  from mage_ai.data_preparation.git import Git
70
78
 
71
79
  custom_progress = RemoteProgress()
72
- username = get_username(token)
80
+ username = get_username(token, user=user)
73
81
 
74
82
  url = build_authenticated_remote_url(remote_url, username, token)
75
- git_manager = Git.get_manager()
83
+ git_manager = Git.get_manager(user=user)
76
84
 
77
85
  remote = git_manager.repo.remotes[remote_name]
78
86
  url_original = list(remote.urls)[0]
@@ -92,14 +100,20 @@ def pull(remote_name: str, remote_url: str, branch_name: str, token: str) -> Rem
92
100
  return custom_progress
93
101
 
94
102
 
95
- def push(remote_name: str, remote_url: str, branch_name: str, token: str) -> RemoteProgress:
103
+ def push(
104
+ remote_name: str,
105
+ remote_url: str,
106
+ branch_name: str,
107
+ token: str,
108
+ user: User = None,
109
+ ) -> RemoteProgress:
96
110
  from mage_ai.data_preparation.git import Git
97
111
 
98
112
  custom_progress = RemoteProgress()
99
- username = get_username(token)
113
+ username = get_username(token, user=user)
100
114
 
101
115
  url = build_authenticated_remote_url(remote_url, username, token)
102
- git_manager = Git.get_manager()
116
+ git_manager = Git.get_manager(user=user)
103
117
 
104
118
  remote = git_manager.repo.remotes[remote_name]
105
119
  url_original = list(remote.urls)[0]
@@ -119,13 +133,19 @@ def push(remote_name: str, remote_url: str, branch_name: str, token: str) -> Rem
119
133
  return custom_progress
120
134
 
121
135
 
122
- def reset_hard(remote_name: str, remote_url: str, branch_name: str, token: str) -> None:
136
+ def reset_hard(
137
+ remote_name: str,
138
+ remote_url: str,
139
+ branch_name: str,
140
+ token: str,
141
+ user: User = None,
142
+ ) -> None:
123
143
  from mage_ai.data_preparation.git import Git
124
144
 
125
- username = get_username(token)
145
+ username = get_username(token, user=user)
126
146
 
127
147
  url = build_authenticated_remote_url(remote_url, username, token)
128
- git_manager = Git.get_manager()
148
+ git_manager = Git.get_manager(user=user)
129
149
 
130
150
  remote = git_manager.repo.remotes[remote_name]
131
151
  url_original = list(remote.urls)[0]
@@ -142,13 +162,18 @@ def reset_hard(remote_name: str, remote_url: str, branch_name: str, token: str)
142
162
  print(err)
143
163
 
144
164
 
145
- def clone(remote_name: str, remote_url: str, token: str) -> None:
165
+ def clone(
166
+ remote_name: str,
167
+ remote_url: str,
168
+ token: str,
169
+ user: User = None,
170
+ ) -> None:
146
171
  from mage_ai.data_preparation.git import Git
147
172
 
148
- username = get_username(token)
173
+ username = get_username(token, user=user)
149
174
 
150
175
  url = build_authenticated_remote_url(remote_url, username, token)
151
- git_manager = Git.get_manager()
176
+ git_manager = Git.get_manager(user=user)
152
177
 
153
178
  remote = git_manager.repo.remotes[remote_name]
154
179
  url_original = list(remote.urls)[0]
@@ -172,7 +197,7 @@ def clone(remote_name: str, remote_url: str, token: str) -> None:
172
197
  tmp_path,
173
198
  git_manager.repo_path,
174
199
  dirs_exist_ok=True,
175
- ignore=lambda x, y: ['.preferences.yaml']
200
+ ignore=lambda x, y: ['.preferences.yaml'],
176
201
  )
177
202
  Git.get_manager().repo.git.clean('-fd', exclude='.preferences.yaml')
178
203
  finally:
@@ -200,8 +225,14 @@ def build_authenticated_remote_url(remote_url: str, username: str, token: str) -
200
225
  return urlunsplit(url)
201
226
 
202
227
 
203
- def get_username(token: str) -> str:
204
- return get_user(token)['login']
228
+ def get_username(token: str, user: User = None) -> str:
229
+ resp = get_user(token)
230
+ if resp.get('login') is None:
231
+ from mage_ai.data_preparation.git import Git
232
+ git_manager = Git.get_manager(user=user, setup_repo=False)
233
+ return git_manager.git_config.username
234
+ else:
235
+ return resp['login']
205
236
 
206
237
 
207
238
  def get_user(token: str) -> Dict:
@@ -212,11 +243,15 @@ def get_user(token: str) -> Dict:
212
243
  endpoint = f'{API_ENDPOINT}/user'
213
244
  if ghe_hostname and ghe_hostname != DEFAULT_GITHUB_HOSTNAME:
214
245
  endpoint = f'{ghe_hostname}/api/v3/user'
215
- resp = requests.get(endpoint, headers={
216
- 'Accept': 'application/vnd.github+json',
217
- 'Authorization': f'Bearer {token}',
218
- 'X-GitHub-Api-Version': '2022-11-28',
219
- })
246
+ resp = requests.get(
247
+ endpoint,
248
+ headers={
249
+ 'Accept': 'application/vnd.github+json',
250
+ 'Authorization': f'Bearer {token}',
251
+ 'X-GitHub-Api-Version': '2022-11-28',
252
+ },
253
+ timeout=10,
254
+ )
220
255
 
221
256
  return resp.json()
222
257
 
@@ -228,10 +263,12 @@ def check_connection(repo: Repo, remote_url: str) -> None:
228
263
  async def validate_authentication_for_remote_url(repo: Repo, remote_url: str) -> None:
229
264
  proc = repo.git.ls_remote(remote_url, as_process=True)
230
265
 
231
- asyncio.run(__poll_process_with_timeout(
232
- proc,
233
- error_message='Error connecting to remote, make sure your access is valid.',
234
- ))
266
+ asyncio.run(
267
+ __poll_process_with_timeout(
268
+ proc,
269
+ error_message='Error connecting to remote, make sure your access is valid.',
270
+ )
271
+ )
235
272
 
236
273
 
237
274
  async def __poll_process_with_timeout(
@@ -253,10 +290,7 @@ async def __poll_process_with_timeout(
253
290
 
254
291
  if return_code is not None and return_code != 0:
255
292
  _, err = proc.communicate()
256
- message = (
257
- err.decode('UTF-8') if err
258
- else error_message
259
- )
293
+ message = err.decode('UTF-8') if err else error_message
260
294
  raise ChildProcessError(message)
261
295
 
262
296
  if return_code is None:
@@ -1,6 +1,7 @@
1
1
  import asyncio
2
2
  import functools
3
3
  import importlib.util
4
+ import inspect
4
5
  import json
5
6
  import logging
6
7
  import os
@@ -188,6 +189,7 @@ def run_blocks_sync(
188
189
  run_sensors: bool = True,
189
190
  run_tests: bool = True,
190
191
  selected_blocks: Set[str] = None,
192
+ update_status: bool = True,
191
193
  ) -> None:
192
194
  tries_by_block_uuid = {}
193
195
  tasks = dict()
@@ -242,6 +244,7 @@ def run_blocks_sync(
242
244
  from_notebook=not run_sensors,
243
245
  global_vars=global_vars,
244
246
  run_all_blocks=True,
247
+ update_status=update_status,
245
248
  )
246
249
 
247
250
  if run_tests:
@@ -277,6 +280,7 @@ class Block(DataIntegrationMixin, SparkBlock):
277
280
  language: BlockLanguage = BlockLanguage.PYTHON,
278
281
  configuration: Dict = None,
279
282
  has_callback: bool = False,
283
+ repo_config=None,
280
284
  timeout: int = None,
281
285
  ) -> None:
282
286
  if configuration is None:
@@ -338,12 +342,26 @@ class Block(DataIntegrationMixin, SparkBlock):
338
342
 
339
343
  self.execution_timestamp_start = None
340
344
  self.execution_timestamp_end = None
345
+ self.execution_uuid = None
346
+ self._compute_service_uuid = None
347
+ self._repo_config = repo_config
341
348
  self._spark_session_current = None
349
+ self.global_vars = None
342
350
 
343
351
  @property
344
352
  def uuid(self) -> str:
345
353
  return self._uuid
346
354
 
355
+ @property
356
+ def repo_config(self):
357
+ if self._repo_config:
358
+ return self._repo_config
359
+
360
+ if self.pipeline:
361
+ self._repo_config = self.pipeline.repo_config
362
+
363
+ return self._repo_config
364
+
347
365
  @property
348
366
  def uuid_replicated(self) -> str:
349
367
  if self.replicated_block:
@@ -873,6 +891,7 @@ class Block(DataIntegrationMixin, SparkBlock):
873
891
  global_vars: Dict = None,
874
892
  logger: Logger = None,
875
893
  logging_tags: Dict = None,
894
+ execution_uuid: str = None,
876
895
  from_notebook: bool = False,
877
896
  **kwargs
878
897
  ) -> Dict:
@@ -882,6 +901,9 @@ class Block(DataIntegrationMixin, SparkBlock):
882
901
  websocket as a way to test the code in the callback. To run a block in a pipeline
883
902
  run, use a BlockExecutor.
884
903
  """
904
+ if execution_uuid:
905
+ self.execution_uuid = execution_uuid
906
+
885
907
  if logging_tags is None:
886
908
  logging_tags = dict()
887
909
 
@@ -921,17 +943,18 @@ class Block(DataIntegrationMixin, SparkBlock):
921
943
  from_notebook=from_notebook,
922
944
  **kwargs
923
945
  )
924
- except Exception as e:
946
+ except Exception as error:
925
947
  for callback_block in callback_arr:
926
948
  callback_block.execute_callback(
927
949
  'on_failure',
950
+ callback_kwargs=dict(__error=error),
951
+ from_notebook=from_notebook,
928
952
  global_vars=global_vars,
929
953
  logger=logger,
930
954
  logging_tags=logging_tags,
931
955
  parent_block=self,
932
- from_notebook=from_notebook,
933
956
  )
934
- raise e
957
+ raise
935
958
 
936
959
  for callback_block in callback_arr:
937
960
  callback_block.execute_callback(
@@ -1281,44 +1304,6 @@ class Block(DataIntegrationMixin, SparkBlock):
1281
1304
  **kwargs,
1282
1305
  )
1283
1306
 
1284
- # If block has downstream dbt block, then materialize output
1285
- if (
1286
- BlockType.DBT != self.type and
1287
- self.language in [BlockLanguage.SQL, BlockLanguage.PYTHON, BlockLanguage.R] and
1288
- any(BlockType.DBT == block.type for block in self.downstream_blocks) and
1289
- len(outputs) > 0
1290
- ):
1291
- from mage_ai.data_preparation.models.block.dbt import DBTBlock
1292
-
1293
- # normalize output
1294
- output = outputs[0]
1295
- if isinstance(output, pd.DataFrame):
1296
- df = output
1297
- elif isinstance(output, dict):
1298
- df = pd.DataFrame([output])
1299
- elif isinstance(output, list):
1300
- df = pd.DataFrame(output)
1301
- else:
1302
- df = pd.DataFrame()
1303
-
1304
- if df.empty:
1305
- if logger:
1306
- logger.info('No data for dbt to materialize.')
1307
- else:
1308
- DBTBlock.materialize_df(
1309
- df=df,
1310
- pipeline_uuid=self.pipeline.uuid,
1311
- block_uuid=self.uuid,
1312
- targets=list(set(
1313
- (block.project_path, block.target(variables=global_vars))
1314
- for _uuid, block in self.pipeline.blocks_by_uuid.items()
1315
- if isinstance(block, DBTBlock)
1316
- )),
1317
- logger=logger,
1318
- global_vars=global_vars_copy,
1319
- runtime_arguments=runtime_arguments,
1320
- )
1321
-
1322
1307
  return dict(output=outputs)
1323
1308
 
1324
1309
  @contextmanager
@@ -1442,8 +1427,7 @@ class Block(DataIntegrationMixin, SparkBlock):
1442
1427
  if logger and 'logger' not in global_vars:
1443
1428
  global_vars['logger'] = logger
1444
1429
 
1445
- track_spark = from_notebook and self.is_using_spark() and \
1446
- self.compute_management_enabled()
1430
+ track_spark = from_notebook and self.should_track_spark()
1447
1431
 
1448
1432
  if track_spark:
1449
1433
  self.clear_spark_jobs_cache()
@@ -1526,7 +1510,8 @@ class Block(DataIntegrationMixin, SparkBlock):
1526
1510
  self.module = module
1527
1511
 
1528
1512
  return block_function_updated
1529
- except Exception:
1513
+ except Exception as err:
1514
+ print(f'[WARNING] Block.initialize_decorator_modules: {err}')
1530
1515
  print('Falling back to default block execution...')
1531
1516
 
1532
1517
  return block_function
@@ -2511,6 +2496,31 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
2511
2496
  return variable_mapping
2512
2497
 
2513
2498
  def __enrich_global_vars(self, global_vars: Dict = None) -> Dict:
2499
+ """
2500
+ Enriches the provided global variables dictionary with additional context, Spark session,
2501
+ environment, configuration, and an empty context dictionary.
2502
+
2503
+ Args:
2504
+ global_vars (Optional[Dict]): A dictionary of global variables to be enriched.
2505
+ If not provided, an empty dictionary is created.
2506
+
2507
+ Returns:
2508
+ Dict: The enriched global variables dictionary.
2509
+
2510
+ This method checks if the pipeline type is DATABRICKS or if the environment is a Spark
2511
+ environment. If true, it adds the Spark session to the global variables if not already
2512
+ present.
2513
+
2514
+ If 'env' is not in the global variables, it adds the environment information using the
2515
+ 'get_env()' function.
2516
+
2517
+ Adds the block configuration to the global variables.
2518
+
2519
+ If 'context' is not in global_vars, it adds an empty context dictionary.
2520
+
2521
+ The final enriched global variables dictionary is assigned to the object's 'global_vars'
2522
+ attribute and returned.
2523
+ """
2514
2524
  if global_vars is None:
2515
2525
  global_vars = dict()
2516
2526
  if ((self.pipeline is not None and self.pipeline.type == PipelineType.DATABRICKS) or
@@ -2521,16 +2531,19 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
2521
2531
  global_vars['spark'] = spark
2522
2532
  if 'env' not in global_vars:
2523
2533
  global_vars['env'] = get_env()
2524
- if 'configuration' not in global_vars:
2525
- global_vars['configuration'] = self.configuration
2534
+ global_vars['configuration'] = self.configuration
2526
2535
  if 'context' not in global_vars:
2527
2536
  global_vars['context'] = dict()
2537
+
2538
+ self.global_vars = global_vars
2539
+
2528
2540
  return global_vars
2529
2541
 
2530
2542
  def get_spark_session(self):
2531
2543
  if self.spark_init and (not self.pipeline or
2532
2544
  not self.pipeline.spark_config):
2533
2545
  return self.spark
2546
+
2534
2547
  try:
2535
2548
  if self.pipeline and self.pipeline.spark_config:
2536
2549
  spark_config = SparkConfig.load(
@@ -2543,6 +2556,9 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
2543
2556
  except Exception:
2544
2557
  self.spark = None
2545
2558
 
2559
+ if not self.spark and self.global_vars and self.global_vars.get('spark'):
2560
+ self.spark = self.global_vars.get('spark')
2561
+
2546
2562
  self.spark_init = True
2547
2563
  return self.spark
2548
2564
 
@@ -3095,6 +3111,7 @@ class CallbackBlock(AddonBlock):
3095
3111
  def execute_callback(
3096
3112
  self,
3097
3113
  callback: str,
3114
+ callback_kwargs: Dict = None,
3098
3115
  dynamic_block_index: Union[int, None] = None,
3099
3116
  dynamic_upstream_block_uuids: Union[List[str], None] = None,
3100
3117
  execution_partition: str = None,
@@ -3109,6 +3126,8 @@ class CallbackBlock(AddonBlock):
3109
3126
  logger=logger,
3110
3127
  logging_tags=logging_tags,
3111
3128
  ):
3129
+ if callback_kwargs is None:
3130
+ callback_kwargs = dict()
3112
3131
  global_vars = self._create_global_vars(
3113
3132
  global_vars,
3114
3133
  parent_block,
@@ -3160,23 +3179,39 @@ class CallbackBlock(AddonBlock):
3160
3179
  for kwargs_var in kwargs_vars:
3161
3180
  global_vars_copy.update(kwargs_var)
3162
3181
 
3182
+ callback_kwargs = merge_dict(
3183
+ callback_kwargs,
3184
+ global_vars_copy,
3185
+ )
3186
+
3163
3187
  for callback_function in callback_functions_legacy:
3164
- callback_function(**global_vars_copy)
3188
+ callback_function(**callback_kwargs)
3165
3189
 
3166
3190
  for callback_function in callback_functions:
3167
- try:
3191
+ inner_function = callback_function(callback_status)
3192
+ if inner_function is not None:
3193
+ sig = inspect.signature(inner_function)
3168
3194
  # As of version 0.8.81, callback functions have access to the parent block’s
3169
- # data output.
3170
- callback_function(callback_status, *input_vars, **global_vars_copy)
3171
- except TypeError:
3172
- # This try except block will make the above code backwards compatible in case
3195
+ # data output. If the callback function has any positional arguments, we will
3196
+ # pass in the input variables as positional arguments.
3197
+ if not input_vars or any(
3198
+ [
3199
+ p.kind not in [p.KEYWORD_ONLY, p.VAR_KEYWORD]
3200
+ for p in sig.parameters.values()
3201
+ ]
3202
+ ):
3203
+ inner_function(
3204
+ *input_vars,
3205
+ **callback_kwargs,
3206
+ )
3207
+ # This else block will make the above code backwards compatible in case
3173
3208
  # a user has already written callback functions with only keyword arguments.
3174
- callback_function(
3175
- callback_status,
3176
- **merge_dict(global_vars_copy, dict(
3177
- __input=outputs_from_input_vars,
3178
- )),
3179
- )
3209
+ else:
3210
+ inner_function(
3211
+ **merge_dict(callback_kwargs, dict(
3212
+ __input=outputs_from_input_vars,
3213
+ )),
3214
+ )
3180
3215
 
3181
3216
  def update_content(self, content, widget=False) -> 'CallbackBlock':
3182
3217
  if not self.file.exists():
@@ -3211,9 +3246,9 @@ class CallbackBlock(AddonBlock):
3211
3246
  )
3212
3247
 
3213
3248
  def inner(function):
3214
- def func(callback_status_inner, *args, **kwargs):
3249
+ def func(callback_status_inner):
3215
3250
  if callback_status_inner == callback_status:
3216
- return function(*args, **kwargs)
3251
+ return function
3217
3252
  decorated_functions.append(func)
3218
3253
 
3219
3254
  return inner