mage-ai 0.9.45__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 (497) 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/GlobalHookPolicy.py +126 -0
  9. mage_ai/api/policies/OauthPolicy.py +56 -4
  10. mage_ai/api/policies/ProjectPolicy.py +1 -0
  11. mage_ai/api/presenters/ComputeClusterPresenter.py +19 -0
  12. mage_ai/api/presenters/ComputeConnectionPresenter.py +26 -0
  13. mage_ai/api/presenters/ComputeServicePresenter.py +15 -0
  14. mage_ai/api/presenters/DownloadPresenter.py +13 -0
  15. mage_ai/api/presenters/GlobalHookPresenter.py +74 -0
  16. mage_ai/api/presenters/PipelinePresenter.py +1 -0
  17. mage_ai/api/presenters/ProjectPresenter.py +1 -0
  18. mage_ai/api/presenters/SparkApplicationPresenter.py +2 -0
  19. mage_ai/api/presenters/WorkspacePresenter.py +22 -22
  20. mage_ai/api/resources/AsyncBaseResource.py +39 -0
  21. mage_ai/api/resources/ClusterResource.py +1 -1
  22. mage_ai/api/resources/ComputeClusterResource.py +109 -0
  23. mage_ai/api/resources/ComputeConnectionResource.py +103 -0
  24. mage_ai/api/resources/ComputeServiceResource.py +35 -0
  25. mage_ai/api/resources/DownloadResource.py +56 -0
  26. mage_ai/api/resources/ExecutionStateResource.py +1 -1
  27. mage_ai/api/resources/GlobalHookResource.py +192 -0
  28. mage_ai/api/resources/KernelResource.py +10 -0
  29. mage_ai/api/resources/OauthResource.py +28 -33
  30. mage_ai/api/resources/PipelineResource.py +4 -4
  31. mage_ai/api/resources/PipelineScheduleResource.py +37 -16
  32. mage_ai/api/resources/ProjectResource.py +5 -3
  33. mage_ai/api/resources/SessionResource.py +0 -9
  34. mage_ai/api/resources/SparkApplicationResource.py +5 -5
  35. mage_ai/api/resources/SparkEnvironmentResource.py +1 -2
  36. mage_ai/api/resources/SparkExecutorResource.py +1 -2
  37. mage_ai/api/resources/SparkJobResource.py +3 -6
  38. mage_ai/api/resources/SparkSqlResource.py +6 -11
  39. mage_ai/api/resources/SparkStageAttemptResource.py +2 -3
  40. mage_ai/api/resources/SparkStageAttemptTaskResource.py +1 -2
  41. mage_ai/api/resources/SparkStageAttemptTaskSummaryResource.py +1 -2
  42. mage_ai/api/resources/SparkStageResource.py +3 -6
  43. mage_ai/api/resources/SparkThreadResource.py +1 -2
  44. mage_ai/api/resources/mixins/spark.py +25 -4
  45. mage_ai/authentication/oauth2.py +1 -3
  46. mage_ai/authentication/permissions/constants.py +4 -0
  47. mage_ai/authentication/providers/active_directory.py +136 -0
  48. mage_ai/authentication/providers/constants.py +3 -0
  49. mage_ai/authentication/providers/ghe.py +24 -25
  50. mage_ai/authentication/providers/google.py +25 -26
  51. mage_ai/authentication/providers/oauth.py +2 -2
  52. mage_ai/authentication/providers/okta.py +28 -29
  53. mage_ai/authentication/providers/sso.py +2 -2
  54. mage_ai/cluster_manager/aws/emr_cluster_manager.py +2 -1
  55. mage_ai/cluster_manager/workspace/base.py +7 -3
  56. mage_ai/data_integrations/destinations/constants.py +1 -0
  57. mage_ai/data_preparation/executors/pipeline_executor.py +9 -0
  58. mage_ai/data_preparation/models/block/__init__.py +57 -5
  59. mage_ai/data_preparation/models/block/data_integration/data.py +1 -1
  60. mage_ai/data_preparation/models/block/spark/mixins.py +82 -34
  61. mage_ai/data_preparation/models/download/__init__.py +8 -0
  62. mage_ai/data_preparation/models/global_hooks/__init__.py +0 -0
  63. mage_ai/data_preparation/models/global_hooks/constants.py +44 -0
  64. mage_ai/data_preparation/models/global_hooks/models.py +928 -0
  65. mage_ai/data_preparation/models/global_hooks/utils.py +21 -0
  66. mage_ai/data_preparation/models/pipeline.py +82 -6
  67. mage_ai/data_preparation/models/pipelines/models.py +16 -0
  68. mage_ai/data_preparation/models/project/__init__.py +6 -0
  69. mage_ai/data_preparation/models/project/constants.py +1 -0
  70. mage_ai/data_preparation/models/project/models.py +12 -0
  71. mage_ai/data_preparation/repo_manager.py +23 -1
  72. mage_ai/data_preparation/templates/data_loaders/streaming/activemq.yaml +6 -0
  73. mage_ai/data_preparation/templates/data_loaders/streaming/nats.yaml +20 -0
  74. mage_ai/orchestration/db/models/schedules.py +2 -2
  75. mage_ai/orchestration/queue/process_queue.py +9 -1
  76. mage_ai/orchestration/triggers/api.py +11 -3
  77. mage_ai/orchestration/triggers/constants.py +1 -0
  78. mage_ai/server/active_kernel.py +37 -4
  79. mage_ai/server/api/downloads.py +76 -1
  80. mage_ai/server/constants.py +1 -1
  81. mage_ai/server/frontend_dist/404.html +2 -2
  82. mage_ai/server/frontend_dist/_next/static/9jB4XPuz6BzxBcG9VNao5/_buildManifest.js +1 -0
  83. mage_ai/server/frontend_dist/_next/static/chunks/1749-9a6276b2918fdae1.js +1 -0
  84. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/7519-8c29bbb92e03cc77.js → frontend_dist/_next/static/chunks/1845-5ce774d5ab81ed57.js} +1 -1
  85. mage_ai/server/frontend_dist/_next/static/chunks/1952-ac7722e8b1ab88fe.js +1 -0
  86. mage_ai/server/frontend_dist/_next/static/chunks/3419-f8d518d024e7b5c8.js +1 -0
  87. mage_ai/server/frontend_dist/_next/static/chunks/4267-fd4d8049e83178de.js +1 -0
  88. mage_ai/server/frontend_dist/_next/static/chunks/4366-93e09e5a4a7e182c.js +1 -0
  89. mage_ai/server/frontend_dist/_next/static/chunks/5457-949640f4037bf12f.js +1 -0
  90. mage_ai/server/frontend_dist/_next/static/chunks/5499-76cf8f023c6b0985.js +1 -0
  91. mage_ai/server/frontend_dist/_next/static/chunks/553-7f7919e14392ca67.js +1 -0
  92. mage_ai/server/frontend_dist/_next/static/chunks/5638-a65610405a70961c.js +1 -0
  93. mage_ai/server/frontend_dist/_next/static/chunks/5810-12eadc488265d55b.js +1 -0
  94. mage_ai/server/frontend_dist/_next/static/chunks/5820-28adeabb5cda2b96.js +1 -0
  95. mage_ai/server/frontend_dist/_next/static/chunks/595-0d174b1f9fbfce4f.js +1 -0
  96. mage_ai/server/frontend_dist/_next/static/chunks/600-705fe234320ec5de.js +1 -0
  97. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/3122-f27de34d0b5426af.js → frontend_dist/_next/static/chunks/6285-e9b45335bfb9ccaf.js} +1 -1
  98. mage_ai/server/frontend_dist/_next/static/chunks/6333-bc1b433b428a9095.js +1 -0
  99. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/5397-b5f2e477acc6bd6b.js → frontend_dist/_next/static/chunks/6965-c613d1834c8ed92d.js} +1 -1
  100. mage_ai/server/frontend_dist/_next/static/chunks/{7022-18fde36eb46e1d65.js → 7022-070ec0144a4d029c.js} +1 -1
  101. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/722-2a171fe616310f60.js → frontend_dist/_next/static/chunks/722-a1584445357a276c.js} +1 -1
  102. mage_ai/server/frontend_dist/_next/static/chunks/{7858-c83d25349d0e980f.js → 7858-d9df72e95e438284.js} +1 -1
  103. mage_ai/server/frontend_dist/_next/static/chunks/8264-0d582a6ca33c3dfa.js +1 -0
  104. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/3684-cbda680fd8927d07.js → frontend_dist/_next/static/chunks/8432-f191e39f9b5893f2.js} +1 -1
  105. mage_ai/server/frontend_dist/_next/static/chunks/90-a7308bae028d7001.js +1 -0
  106. mage_ai/server/frontend_dist/_next/static/chunks/9264-1d4f0327d42fed91.js +1 -0
  107. mage_ai/server/frontend_dist/_next/static/chunks/9618-2c5045255ac5a6e7.js +1 -0
  108. mage_ai/server/frontend_dist/_next/static/chunks/framework-22b71764bf44ede4.js +1 -0
  109. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-ebef928183f9a3bb.js +1 -0
  110. mage_ai/server/frontend_dist/_next/static/chunks/pages/block-layout-a24cb24b6f08bbc9.js +1 -0
  111. mage_ai/server/frontend_dist/_next/static/chunks/pages/compute-419775ca1293b354.js +1 -0
  112. mage_ai/server/frontend_dist/_next/static/chunks/pages/files-0f2d4be6fdca86ca.js +1 -0
  113. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/{[...slug]-3f6fc312f67ff72e.js → [...slug]-cfd68e760ae00958.js} +1 -1
  114. mage_ai/server/frontend_dist/_next/static/chunks/pages/{global-data-products-f4cd03036c3e8723.js → global-data-products-c3b79ef31007f95b.js} +1 -1
  115. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-77edfa32d000e88b.js +1 -0
  116. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks-e561ae38cf5592e8.js +1 -0
  117. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/files-449a022f2f0f2d94.js +1 -0
  118. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-60845f0b59142f32.js +1 -0
  119. 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
  120. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-abd8571907664fdf.js +1 -0
  121. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/{users-a7c970122a10afdc.js → users-28a930b148d99766.js} +1 -1
  122. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-f83deb790548693b.js +1 -0
  123. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/overview-a4647a274cf4dffa.js → frontend_dist/_next/static/chunks/pages/overview-f0c40645f385f23f.js} +1 -1
  124. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-c79819d6826e5416.js → frontend_dist/_next/static/chunks/pages/pipeline-runs-b35d37bfba8fbccc.js} +1 -1
  125. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/{[...slug]-b4c0a36c69c346a4.js → [...slug]-10e9a2d19541caa2.js} +1 -1
  126. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-c8d3a5289ab93f88.js +1 -0
  127. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-571c0962333b92f0.js +1 -0
  128. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-ff7e9108502f5716.js +1 -0
  129. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{logs-a52d2d3e0c2978f4.js → logs-ef680455ae54ccbe.js} +1 -1
  130. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-ddddcddd2f74b4f6.js +1 -0
  131. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-4a238307feddb522.js +1 -0
  132. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-e051057d9fe94f23.js +1 -0
  133. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-b0a508aa52914dad.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-0691711636fa95c7.js} +1 -1
  134. 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
  135. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-2914e326a5f1ffe0.js +1 -0
  136. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-b75bf17498e87354.js +1 -0
  137. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-3a7500e6e53084d3.js +1 -0
  138. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{triggers-95394769a783c6c7.js → triggers-c0e551d265a8d467.js} +1 -1
  139. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/{[pipeline]-35fe7762cb83a733.js → [pipeline]-02c843b9c8418bb5.js} +1 -1
  140. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-e47db5c3eaf683af.js +1 -0
  141. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-55ac955dfa9a5a8d.js +1 -0
  142. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-d6a62284c7c99cb3.js → [...slug]-b78b1be5b9ed84b9.js} +1 -1
  143. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{permissions-b1389695f758c32b.js → permissions-37b78a436eeab258.js} +1 -1
  144. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-29c92a9bc54ae5cd.js +1 -0
  145. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-0bdb66265286ab22.js → [...slug]-db05a80d18c168e5.js} +1 -1
  146. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{roles-e04e18fc295ca76a.js → roles-f55c77e4f46c8d33.js} +1 -1
  147. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-2a1f8737561fdd94.js +1 -0
  148. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-0267358c91122109.js → [...slug]-e3bf6e5d8bb250c4.js} +1 -1
  149. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{users-50fed18bb9b8d142.js → users-20f0a050a42a015d.js} +1 -1
  150. mage_ai/server/frontend_dist/_next/static/chunks/pages/{settings-56f83205752b1323.js → settings-0f0121db7f5ff93d.js} +1 -1
  151. mage_ai/server/frontend_dist/_next/static/chunks/pages/sign-in-99e2748e3c1d57a3.js +1 -0
  152. 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
  153. 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
  154. mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-ed121e305169cf1c.js +1 -0
  155. mage_ai/server/frontend_dist/_next/static/chunks/pages/test-9ae68758102cc843.js +1 -0
  156. mage_ai/server/frontend_dist/_next/static/chunks/pages/{triggers-ffaab4c013e62ba1.js → triggers-572d82d6eb7a5d43.js} +1 -1
  157. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-2d26d80370a2e481.js +1 -0
  158. mage_ai/server/frontend_dist/_next/static/chunks/{webpack-8af2b89c5a3779fc.js → webpack-fea697dd168c6d0c.js} +1 -1
  159. mage_ai/server/frontend_dist/block-layout.html +2 -2
  160. mage_ai/server/frontend_dist/compute.html +2 -2
  161. mage_ai/server/frontend_dist/files.html +2 -2
  162. mage_ai/server/frontend_dist/global-data-products/[...slug].html +2 -2
  163. mage_ai/server/frontend_dist/global-data-products.html +2 -2
  164. mage_ai/server/frontend_dist/global-hooks/[...slug].html +24 -0
  165. mage_ai/server/frontend_dist/global-hooks.html +24 -0
  166. mage_ai/server/frontend_dist/index.html +2 -2
  167. mage_ai/server/frontend_dist/manage/files.html +2 -2
  168. mage_ai/server/frontend_dist/manage/settings.html +2 -2
  169. mage_ai/server/frontend_dist/manage/users/[user].html +2 -2
  170. mage_ai/server/frontend_dist/manage/users/new.html +2 -2
  171. mage_ai/server/frontend_dist/manage/users.html +2 -2
  172. mage_ai/server/frontend_dist/manage.html +2 -2
  173. mage_ai/server/frontend_dist/oauth.html +3 -3
  174. mage_ai/server/frontend_dist/overview.html +2 -2
  175. mage_ai/server/frontend_dist/pipeline-runs.html +2 -2
  176. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +2 -2
  177. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +2 -2
  178. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +2 -2
  179. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +2 -2
  180. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +2 -2
  181. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +2 -2
  182. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +2 -2
  183. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +2 -2
  184. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +2 -2
  185. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +2 -2
  186. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +2 -2
  187. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +2 -2
  188. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +2 -2
  189. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +2 -2
  190. mage_ai/server/frontend_dist/pipelines/[pipeline].html +2 -2
  191. mage_ai/server/frontend_dist/pipelines.html +2 -2
  192. mage_ai/server/frontend_dist/settings/account/profile.html +2 -2
  193. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +2 -2
  194. mage_ai/server/frontend_dist/settings/workspace/permissions.html +2 -2
  195. mage_ai/server/frontend_dist/settings/workspace/preferences.html +2 -2
  196. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +2 -2
  197. mage_ai/server/frontend_dist/settings/workspace/roles.html +2 -2
  198. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +2 -2
  199. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +2 -2
  200. mage_ai/server/frontend_dist/settings/workspace/users.html +2 -2
  201. mage_ai/server/frontend_dist/settings.html +2 -2
  202. mage_ai/server/frontend_dist/sign-in.html +10 -11
  203. mage_ai/server/frontend_dist/templates/[...slug].html +2 -2
  204. mage_ai/server/frontend_dist/templates.html +2 -2
  205. mage_ai/server/frontend_dist/terminal.html +2 -2
  206. mage_ai/server/frontend_dist/test.html +14 -14
  207. mage_ai/server/frontend_dist/triggers.html +2 -2
  208. mage_ai/server/frontend_dist/version-control.html +2 -2
  209. mage_ai/server/frontend_dist_base_path_template/404.html +2 -2
  210. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1749-9a6276b2918fdae1.js +1 -0
  211. mage_ai/server/{frontend_dist/_next/static/chunks/7519-8c29bbb92e03cc77.js → frontend_dist_base_path_template/_next/static/chunks/1845-5ce774d5ab81ed57.js} +1 -1
  212. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1952-ac7722e8b1ab88fe.js +1 -0
  213. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3419-f8d518d024e7b5c8.js +1 -0
  214. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4267-fd4d8049e83178de.js +1 -0
  215. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4366-93e09e5a4a7e182c.js +1 -0
  216. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-949640f4037bf12f.js +1 -0
  217. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5499-76cf8f023c6b0985.js +1 -0
  218. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/553-7f7919e14392ca67.js +1 -0
  219. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5638-a65610405a70961c.js +1 -0
  220. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5810-12eadc488265d55b.js +1 -0
  221. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5820-28adeabb5cda2b96.js +1 -0
  222. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/595-0d174b1f9fbfce4f.js +1 -0
  223. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/600-705fe234320ec5de.js +1 -0
  224. mage_ai/server/{frontend_dist/_next/static/chunks/3122-f27de34d0b5426af.js → frontend_dist_base_path_template/_next/static/chunks/6285-e9b45335bfb9ccaf.js} +1 -1
  225. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6333-bc1b433b428a9095.js +1 -0
  226. mage_ai/server/{frontend_dist/_next/static/chunks/5397-b5f2e477acc6bd6b.js → frontend_dist_base_path_template/_next/static/chunks/6965-c613d1834c8ed92d.js} +1 -1
  227. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{7022-18fde36eb46e1d65.js → 7022-070ec0144a4d029c.js} +1 -1
  228. mage_ai/server/{frontend_dist/_next/static/chunks/722-2a171fe616310f60.js → frontend_dist_base_path_template/_next/static/chunks/722-a1584445357a276c.js} +1 -1
  229. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{7858-c83d25349d0e980f.js → 7858-d9df72e95e438284.js} +1 -1
  230. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8264-0d582a6ca33c3dfa.js +1 -0
  231. mage_ai/server/{frontend_dist/_next/static/chunks/3684-cbda680fd8927d07.js → frontend_dist_base_path_template/_next/static/chunks/8432-f191e39f9b5893f2.js} +1 -1
  232. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/90-a7308bae028d7001.js +1 -0
  233. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9264-1d4f0327d42fed91.js +1 -0
  234. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9618-2c5045255ac5a6e7.js +1 -0
  235. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/framework-22b71764bf44ede4.js +1 -0
  236. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-ebef928183f9a3bb.js +1 -0
  237. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/block-layout-a24cb24b6f08bbc9.js +1 -0
  238. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/compute-419775ca1293b354.js +1 -0
  239. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-0f2d4be6fdca86ca.js +1 -0
  240. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/{[...slug]-3f6fc312f67ff72e.js → [...slug]-cfd68e760ae00958.js} +1 -1
  241. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{global-data-products-f4cd03036c3e8723.js → global-data-products-c3b79ef31007f95b.js} +1 -1
  242. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-77edfa32d000e88b.js +1 -0
  243. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks-e561ae38cf5592e8.js +1 -0
  244. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/files-449a022f2f0f2d94.js +1 -0
  245. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-60845f0b59142f32.js +1 -0
  246. 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
  247. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-abd8571907664fdf.js +1 -0
  248. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/{users-a7c970122a10afdc.js → users-28a930b148d99766.js} +1 -1
  249. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-f83deb790548693b.js +1 -0
  250. mage_ai/server/{frontend_dist/_next/static/chunks/pages/overview-a4647a274cf4dffa.js → frontend_dist_base_path_template/_next/static/chunks/pages/overview-f0c40645f385f23f.js} +1 -1
  251. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipeline-runs-c79819d6826e5416.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-b35d37bfba8fbccc.js} +1 -1
  252. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/{[...slug]-b4c0a36c69c346a4.js → [...slug]-10e9a2d19541caa2.js} +1 -1
  253. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-c8d3a5289ab93f88.js +1 -0
  254. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-571c0962333b92f0.js +1 -0
  255. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-ff7e9108502f5716.js +1 -0
  256. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{logs-a52d2d3e0c2978f4.js → logs-ef680455ae54ccbe.js} +1 -1
  257. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-ddddcddd2f74b4f6.js +1 -0
  258. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-4a238307feddb522.js +1 -0
  259. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-e051057d9fe94f23.js +1 -0
  260. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-b0a508aa52914dad.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-0691711636fa95c7.js} +1 -1
  261. 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
  262. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-2914e326a5f1ffe0.js +1 -0
  263. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-b75bf17498e87354.js +1 -0
  264. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-3a7500e6e53084d3.js +1 -0
  265. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{triggers-95394769a783c6c7.js → triggers-c0e551d265a8d467.js} +1 -1
  266. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/{[pipeline]-35fe7762cb83a733.js → [pipeline]-02c843b9c8418bb5.js} +1 -1
  267. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-e47db5c3eaf683af.js +1 -0
  268. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-55ac955dfa9a5a8d.js +1 -0
  269. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-d6a62284c7c99cb3.js → [...slug]-b78b1be5b9ed84b9.js} +1 -1
  270. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{permissions-b1389695f758c32b.js → permissions-37b78a436eeab258.js} +1 -1
  271. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-29c92a9bc54ae5cd.js +1 -0
  272. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-0bdb66265286ab22.js → [...slug]-db05a80d18c168e5.js} +1 -1
  273. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{roles-e04e18fc295ca76a.js → roles-f55c77e4f46c8d33.js} +1 -1
  274. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-2a1f8737561fdd94.js +1 -0
  275. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-0267358c91122109.js → [...slug]-e3bf6e5d8bb250c4.js} +1 -1
  276. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{users-50fed18bb9b8d142.js → users-20f0a050a42a015d.js} +1 -1
  277. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{settings-56f83205752b1323.js → settings-0f0121db7f5ff93d.js} +1 -1
  278. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-99e2748e3c1d57a3.js +1 -0
  279. 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
  280. 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
  281. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-ed121e305169cf1c.js +1 -0
  282. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-9ae68758102cc843.js +1 -0
  283. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{triggers-ffaab4c013e62ba1.js → triggers-572d82d6eb7a5d43.js} +1 -1
  284. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-2d26d80370a2e481.js +1 -0
  285. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-074f3eb2281fba79.js → webpack-d30cb09c85b4c4f0.js} +1 -1
  286. mage_ai/server/frontend_dist_base_path_template/_next/static/uPDjJYpJMst1q6psbRyte/_buildManifest.js +1 -0
  287. mage_ai/server/frontend_dist_base_path_template/block-layout.html +2 -2
  288. mage_ai/server/frontend_dist_base_path_template/compute.html +5 -5
  289. mage_ai/server/frontend_dist_base_path_template/files.html +5 -5
  290. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +5 -5
  291. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +5 -5
  292. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +24 -0
  293. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +24 -0
  294. mage_ai/server/frontend_dist_base_path_template/index.html +2 -2
  295. mage_ai/server/frontend_dist_base_path_template/manage/files.html +5 -5
  296. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +5 -5
  297. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +5 -5
  298. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +5 -5
  299. mage_ai/server/frontend_dist_base_path_template/manage/users.html +5 -5
  300. mage_ai/server/frontend_dist_base_path_template/manage.html +5 -5
  301. mage_ai/server/frontend_dist_base_path_template/oauth.html +4 -4
  302. mage_ai/server/frontend_dist_base_path_template/overview.html +5 -5
  303. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +5 -5
  304. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +5 -5
  305. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +5 -5
  306. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +5 -5
  307. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +2 -2
  308. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +5 -5
  309. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +5 -5
  310. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +5 -5
  311. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +5 -5
  312. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +5 -5
  313. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +5 -5
  314. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +5 -5
  315. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +5 -5
  316. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +5 -5
  317. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +5 -5
  318. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +2 -2
  319. mage_ai/server/frontend_dist_base_path_template/pipelines.html +5 -5
  320. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +5 -5
  321. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +5 -5
  322. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +5 -5
  323. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +5 -5
  324. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +5 -5
  325. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +5 -5
  326. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +5 -5
  327. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +5 -5
  328. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +5 -5
  329. mage_ai/server/frontend_dist_base_path_template/settings.html +2 -2
  330. mage_ai/server/frontend_dist_base_path_template/sign-in.html +18 -19
  331. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +5 -5
  332. mage_ai/server/frontend_dist_base_path_template/templates.html +5 -5
  333. mage_ai/server/frontend_dist_base_path_template/terminal.html +5 -5
  334. mage_ai/server/frontend_dist_base_path_template/test.html +15 -15
  335. mage_ai/server/frontend_dist_base_path_template/triggers.html +5 -5
  336. mage_ai/server/frontend_dist_base_path_template/version-control.html +5 -5
  337. mage_ai/server/server.py +35 -9
  338. mage_ai/server/utils/output_display.py +6 -0
  339. mage_ai/server/websocket_server.py +14 -0
  340. mage_ai/services/aws/emr/config.py +1 -0
  341. mage_ai/services/aws/emr/constants.py +1 -0
  342. mage_ai/services/aws/emr/emr.py +20 -7
  343. mage_ai/services/compute/__init__.py +0 -0
  344. mage_ai/services/compute/aws/__init__.py +0 -0
  345. mage_ai/services/compute/aws/constants.py +21 -0
  346. mage_ai/services/compute/aws/models.py +459 -0
  347. mage_ai/services/compute/aws/steps.py +482 -0
  348. mage_ai/services/compute/constants.py +27 -0
  349. mage_ai/services/compute/models.py +212 -0
  350. mage_ai/services/k8s/job_manager.py +3 -0
  351. mage_ai/services/spark/api/aws_emr.py +38 -0
  352. mage_ai/services/spark/api/base.py +7 -4
  353. mage_ai/services/spark/api/constants.py +4 -0
  354. mage_ai/services/spark/api/local.py +25 -24
  355. mage_ai/services/spark/api/service.py +15 -5
  356. mage_ai/services/spark/constants.py +1 -1
  357. mage_ai/services/spark/models/applications.py +45 -3
  358. mage_ai/services/spark/models/base.py +3 -19
  359. mage_ai/services/spark/models/environments.py +16 -11
  360. mage_ai/services/spark/models/executors.py +2 -2
  361. mage_ai/services/spark/models/sqls.py +46 -15
  362. mage_ai/services/spark/models/stages.py +55 -32
  363. mage_ai/services/spark/models/threads.py +2 -2
  364. mage_ai/services/spark/utils.py +22 -6
  365. mage_ai/services/ssh/__init__.py +0 -0
  366. mage_ai/services/ssh/aws/__init__.py +0 -0
  367. mage_ai/services/ssh/aws/emr/__init__.py +0 -0
  368. mage_ai/services/ssh/aws/emr/constants.py +10 -0
  369. mage_ai/services/ssh/aws/emr/models.py +326 -0
  370. mage_ai/services/ssh/aws/emr/utils.py +151 -0
  371. mage_ai/settings/__init__.py +8 -1
  372. mage_ai/settings/secret_generation.py +7 -0
  373. mage_ai/settings/sso.py +8 -0
  374. mage_ai/shared/hash.py +16 -0
  375. mage_ai/shared/models.py +253 -0
  376. mage_ai/streaming/constants.py +2 -0
  377. mage_ai/streaming/sources/activemq.py +89 -0
  378. mage_ai/streaming/sources/nats_js.py +182 -0
  379. mage_ai/streaming/sources/source_factory.py +8 -0
  380. mage_ai/tests/ai/test_ai_functions.py +53 -8
  381. mage_ai/tests/api/endpoints/test_oauths.py +33 -0
  382. mage_ai/tests/api/endpoints/test_projects.py +1 -0
  383. mage_ai/tests/api/endpoints/test_workspaces.py +55 -0
  384. mage_ai/tests/api/operations/test_base.py +7 -5
  385. mage_ai/tests/api/operations/test_operations.py +0 -1
  386. mage_ai/tests/api/operations/test_operations_with_hooks.py +577 -0
  387. mage_ai/tests/api/operations/test_syncs.py +0 -1
  388. mage_ai/tests/api/operations/test_users.py +13 -2
  389. mage_ai/tests/data_preparation/models/global_hooks/__init__.py +0 -0
  390. mage_ai/tests/data_preparation/models/global_hooks/test_global_hooks.py +575 -0
  391. mage_ai/tests/data_preparation/models/global_hooks/test_hook.py +760 -0
  392. mage_ai/tests/data_preparation/models/global_hooks/test_utils.py +33 -0
  393. mage_ai/tests/data_preparation/models/test_pipeline.py +5 -0
  394. mage_ai/tests/data_preparation/test_repo_manager.py +11 -0
  395. mage_ai/tests/factory.py +65 -3
  396. mage_ai/tests/orchestration/queue/test_process_queue.py +15 -2
  397. mage_ai/tests/services/k8s/test_job_manager.py +22 -1
  398. mage_ai/tests/shared/mixins.py +291 -0
  399. mage_ai/tests/shared/test_hash.py +17 -1
  400. mage_ai/tests/streaming/sources/test_activemq.py +32 -0
  401. mage_ai/tests/streaming/sources/test_nats_js.py +32 -0
  402. mage_ai/tests/streaming/sources/test_source_factory.py +26 -1
  403. {mage_ai-0.9.45.dist-info → mage_ai-0.9.46.dist-info}/METADATA +8 -1
  404. {mage_ai-0.9.45.dist-info → mage_ai-0.9.46.dist-info}/RECORD +410 -343
  405. mage_ai/authentication/oauth/active_directory.py +0 -17
  406. mage_ai/server/frontend_dist/_next/static/chunks/1125-91d3ce33140ef041.js +0 -1
  407. mage_ai/server/frontend_dist/_next/static/chunks/1749-607014ecf28268bf.js +0 -1
  408. mage_ai/server/frontend_dist/_next/static/chunks/1952-573c7fc7ad84da6e.js +0 -1
  409. mage_ai/server/frontend_dist/_next/static/chunks/3004-231cad9039ae5dcb.js +0 -1
  410. mage_ai/server/frontend_dist/_next/static/chunks/3419-0873e170ef7d6303.js +0 -1
  411. mage_ai/server/frontend_dist/_next/static/chunks/3932-0ceca9599d6e6d00.js +0 -1
  412. mage_ai/server/frontend_dist/_next/static/chunks/4267-335766a915ee2fa9.js +0 -1
  413. mage_ai/server/frontend_dist/_next/static/chunks/5457-8be2e0a3fe0ba64b.js +0 -1
  414. mage_ai/server/frontend_dist/_next/static/chunks/5499-bca977f466e259e1.js +0 -1
  415. mage_ai/server/frontend_dist/_next/static/chunks/553-edf533e634e85192.js +0 -1
  416. mage_ai/server/frontend_dist/_next/static/chunks/5810-37c6091b29a1fe53.js +0 -1
  417. mage_ai/server/frontend_dist/_next/static/chunks/600-0733eb84f0a0a9e0.js +0 -1
  418. mage_ai/server/frontend_dist/_next/static/chunks/6333-95ad799d13326dce.js +0 -1
  419. mage_ai/server/frontend_dist/_next/static/chunks/8224-39a93ee1058b6069.js +0 -1
  420. mage_ai/server/frontend_dist/_next/static/chunks/8264-6ef8fdb195694807.js +0 -1
  421. mage_ai/server/frontend_dist/_next/static/chunks/9264-1b5c4b071ed544c3.js +0 -1
  422. mage_ai/server/frontend_dist/_next/static/chunks/framework-7c365855dab1bf41.js +0 -1
  423. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-1203afde83fa2d6e.js +0 -1
  424. mage_ai/server/frontend_dist/_next/static/chunks/pages/block-layout-c465c14d48392b11.js +0 -1
  425. mage_ai/server/frontend_dist/_next/static/chunks/pages/compute-b1f8d5a7a9a30f2d.js +0 -1
  426. mage_ai/server/frontend_dist/_next/static/chunks/pages/files-93c094bad0f299fb.js +0 -1
  427. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/files-891e5bd5935f7473.js +0 -1
  428. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-d2e4ee4e68d36807.js +0 -1
  429. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-4a49126fcfe8ced0.js +0 -1
  430. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-5f8c5d0bc6ad1113.js +0 -1
  431. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-a9266d353f288e8c.js +0 -1
  432. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-b5c29c852262312e.js +0 -1
  433. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-9f233917aa72ad82.js +0 -1
  434. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-5af599da035252a7.js +0 -1
  435. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-8597f8e13d80ee48.js +0 -1
  436. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-5e0d047a6c9cb1fc.js +0 -1
  437. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-074c32397d341de9.js +0 -1
  438. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-50f5d8706ed0bc73.js +0 -1
  439. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-e151c1552fcb67bd.js +0 -1
  440. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-8336c4326f1e7d96.js +0 -1
  441. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-01dd679e4a21e0d9.js +0 -1
  442. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-4d9051c073a9b2ff.js +0 -1
  443. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-5a306deca6717862.js +0 -1
  444. mage_ai/server/frontend_dist/_next/static/chunks/pages/sign-in-0dbc5b11019e78a0.js +0 -1
  445. mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-578d862f3e56e6e6.js +0 -1
  446. mage_ai/server/frontend_dist/_next/static/chunks/pages/test-1c0588d685b909b9.js +0 -1
  447. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-114000e84313994f.js +0 -1
  448. mage_ai/server/frontend_dist/_next/static/icIDjCezcfhiKL87kgeSY/_buildManifest.js +0 -1
  449. mage_ai/server/frontend_dist_base_path_template/_next/static/_O1kJQLGtZmoBMyWpQrea/_buildManifest.js +0 -1
  450. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1125-91d3ce33140ef041.js +0 -1
  451. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1749-607014ecf28268bf.js +0 -1
  452. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1952-573c7fc7ad84da6e.js +0 -1
  453. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3004-231cad9039ae5dcb.js +0 -1
  454. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3419-0873e170ef7d6303.js +0 -1
  455. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3932-0ceca9599d6e6d00.js +0 -1
  456. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4267-335766a915ee2fa9.js +0 -1
  457. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-8be2e0a3fe0ba64b.js +0 -1
  458. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5499-bca977f466e259e1.js +0 -1
  459. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/553-edf533e634e85192.js +0 -1
  460. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5810-37c6091b29a1fe53.js +0 -1
  461. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/600-0733eb84f0a0a9e0.js +0 -1
  462. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6333-95ad799d13326dce.js +0 -1
  463. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8224-39a93ee1058b6069.js +0 -1
  464. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8264-6ef8fdb195694807.js +0 -1
  465. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9264-1b5c4b071ed544c3.js +0 -1
  466. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/framework-7c365855dab1bf41.js +0 -1
  467. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-1203afde83fa2d6e.js +0 -1
  468. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/block-layout-c465c14d48392b11.js +0 -1
  469. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/compute-b1f8d5a7a9a30f2d.js +0 -1
  470. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-93c094bad0f299fb.js +0 -1
  471. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/files-891e5bd5935f7473.js +0 -1
  472. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-d2e4ee4e68d36807.js +0 -1
  473. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-4a49126fcfe8ced0.js +0 -1
  474. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-5f8c5d0bc6ad1113.js +0 -1
  475. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-a9266d353f288e8c.js +0 -1
  476. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-b5c29c852262312e.js +0 -1
  477. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-9f233917aa72ad82.js +0 -1
  478. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-5af599da035252a7.js +0 -1
  479. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-8597f8e13d80ee48.js +0 -1
  480. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-5e0d047a6c9cb1fc.js +0 -1
  481. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-074c32397d341de9.js +0 -1
  482. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-50f5d8706ed0bc73.js +0 -1
  483. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-e151c1552fcb67bd.js +0 -1
  484. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-8336c4326f1e7d96.js +0 -1
  485. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-01dd679e4a21e0d9.js +0 -1
  486. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-4d9051c073a9b2ff.js +0 -1
  487. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-5a306deca6717862.js +0 -1
  488. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-0dbc5b11019e78a0.js +0 -1
  489. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-578d862f3e56e6e6.js +0 -1
  490. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-1c0588d685b909b9.js +0 -1
  491. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-114000e84313994f.js +0 -1
  492. /mage_ai/server/frontend_dist/_next/static/{icIDjCezcfhiKL87kgeSY → 9jB4XPuz6BzxBcG9VNao5}/_ssgManifest.js +0 -0
  493. /mage_ai/server/frontend_dist_base_path_template/_next/static/{_O1kJQLGtZmoBMyWpQrea → uPDjJYpJMst1q6psbRyte}/_ssgManifest.js +0 -0
  494. {mage_ai-0.9.45.dist-info → mage_ai-0.9.46.dist-info}/LICENSE +0 -0
  495. {mage_ai-0.9.45.dist-info → mage_ai-0.9.46.dist-info}/WHEEL +0 -0
  496. {mage_ai-0.9.45.dist-info → mage_ai-0.9.46.dist-info}/entry_points.txt +0 -0
  497. {mage_ai-0.9.45.dist-info → mage_ai-0.9.46.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,103 @@
1
+ from mage_ai.api.errors import ApiError
2
+ from mage_ai.api.resources.GenericResource import GenericResource
3
+ from mage_ai.services.compute.constants import (
4
+ ComputeConnectionActionUUID,
5
+ ComputeConnectionState,
6
+ )
7
+ from mage_ai.services.compute.models import ComputeConnection, ComputeService
8
+ from mage_ai.services.spark.constants import ComputeServiceUUID
9
+ from mage_ai.services.ssh.aws.emr.models import SSHTunnel, create_tunnel
10
+ from mage_ai.services.ssh.aws.emr.utils import should_tunnel, tunnel
11
+ from mage_ai.shared.array import find
12
+
13
+
14
+ class ComputeConnectionResource(GenericResource):
15
+ @classmethod
16
+ async def collection(self, query_arg, _meta, user, **kwargs):
17
+ parent_model = kwargs.get('parent_model')
18
+
19
+ arr = []
20
+
21
+ if parent_model and isinstance(parent_model, ComputeService):
22
+ if ComputeServiceUUID.AWS_EMR == parent_model.uuid:
23
+ arr.extend(parent_model.compute_connections())
24
+
25
+ return self.build_result_set(
26
+ arr,
27
+ user,
28
+ **kwargs,
29
+ )
30
+
31
+ @classmethod
32
+ async def member(self, pk, user, **kwargs):
33
+ parent_model = kwargs.get('parent_model')
34
+
35
+ model = ComputeConnection.load(name=pk, uuid=pk)
36
+ if parent_model and isinstance(parent_model, ComputeService):
37
+ if ComputeServiceUUID.AWS_EMR == parent_model.uuid:
38
+ model = find(lambda x: x.uuid == pk, parent_model.compute_connections())
39
+
40
+ return self(model, user, **kwargs)
41
+
42
+ async def update(self, payload, **kwargs):
43
+ parent_model = kwargs.get('parent_model')
44
+
45
+ action_uuid = payload.get('action')
46
+
47
+ if not action_uuid:
48
+ return
49
+
50
+ if parent_model and isinstance(parent_model, ComputeService):
51
+ if ComputeServiceUUID.AWS_EMR == parent_model.uuid:
52
+ from mage_ai.services.compute.aws.steps import SetupStepUUID
53
+
54
+ if SetupStepUUID.OBSERVABILITY == self.model.uuid:
55
+ action_valid = action_uuid in [
56
+ ComputeConnectionActionUUID.CREATE,
57
+ ComputeConnectionActionUUID.DELETE,
58
+ ComputeConnectionActionUUID.DESELECT,
59
+ ComputeConnectionActionUUID.UPDATE,
60
+ ]
61
+
62
+ if action_valid:
63
+ if ComputeConnectionActionUUID.CREATE == action_uuid:
64
+ try:
65
+ should_tunnel(
66
+ ignore_active_kernel=True,
67
+ raise_error=True,
68
+ )
69
+
70
+ ssh_tunnel = create_tunnel(
71
+ connect=False,
72
+ fresh=True,
73
+ reconnect=False,
74
+ stop=False,
75
+ )
76
+ if ssh_tunnel:
77
+ ssh_tunnel.precheck_access(raise_error=True)
78
+ ssh_tunnel.connect()
79
+ else:
80
+ raise Exception('Cannot create SSH tunnel instance.')
81
+ except Exception as err:
82
+ error = ApiError.UNAUTHORIZED_ACCESS.copy()
83
+ error.update(message=str(err))
84
+ raise ApiError(error)
85
+
86
+ def _callback(
87
+ action_uuid=action_uuid,
88
+ *args,
89
+ **kwargs,
90
+ ):
91
+ ssh_tunnel = SSHTunnel()
92
+
93
+ if ComputeConnectionActionUUID.CREATE == action_uuid:
94
+ tunnel(ignore_active_kernel=True)
95
+ elif ComputeConnectionActionUUID.DELETE == action_uuid:
96
+ ssh_tunnel.close()
97
+ elif ComputeConnectionActionUUID.DESELECT == action_uuid:
98
+ ssh_tunnel.stop()
99
+ elif ComputeConnectionActionUUID.UPDATE == action_uuid:
100
+ ssh_tunnel.reconnect()
101
+
102
+ self.model.state = ComputeConnectionState.PENDING
103
+ self.on_update_callback = _callback
@@ -0,0 +1,35 @@
1
+ from mage_ai.api.resources.GenericResource import GenericResource
2
+ from mage_ai.data_preparation.models.project import Project
3
+ from mage_ai.services.compute.models import ComputeService
4
+
5
+
6
+ class ComputeServiceResource(GenericResource):
7
+ @classmethod
8
+ async def collection(self, _query, _meta, user, **kwargs):
9
+ resource = await self.member(None, user, **kwargs)
10
+
11
+ return self.build_result_set(
12
+ [
13
+ resource.model,
14
+ ],
15
+ user,
16
+ **kwargs,
17
+ )
18
+
19
+ @classmethod
20
+ def get_model(self, _pk):
21
+ return ComputeService.build(Project())
22
+
23
+ @classmethod
24
+ async def member(self, pk, user, **kwargs):
25
+ query_arg = kwargs.get('query', {})
26
+
27
+ with_clusters = query_arg.get('with_clusters', [False])
28
+ if with_clusters:
29
+ with_clusters = with_clusters[0]
30
+
31
+ compute_service = self.get_model(pk)
32
+ if with_clusters:
33
+ compute_service.with_clusters = with_clusters
34
+
35
+ return self(compute_service, user, **kwargs)
@@ -0,0 +1,56 @@
1
+ import datetime
2
+ from typing import Dict
3
+
4
+ import jwt
5
+
6
+ from mage_ai.api.constants import DOWNLOAD_TOKEN_LIFESPAN
7
+ from mage_ai.api.resources.GenericResource import GenericResource
8
+ from mage_ai.data_preparation.models.download import Download
9
+ from mage_ai.data_preparation.models.file import File
10
+ from mage_ai.data_preparation.models.pipeline import Pipeline
11
+ from mage_ai.orchestration.db import safe_db_query
12
+ from mage_ai.settings import JWT_DOWNLOAD_SECRET
13
+
14
+
15
+ class DownloadResource(GenericResource):
16
+
17
+ @classmethod
18
+ @safe_db_query
19
+ async def create(self, payload: Dict, user, **kwargs) -> 'DownloadResource':
20
+ parent_model = kwargs.get('parent_model')
21
+
22
+ ignore_folder_structure = payload.get('ignore_folder_structure', False)
23
+
24
+ file_list = []
25
+
26
+ if isinstance(parent_model, Pipeline):
27
+ file_name, file_list = self.fetch_pipeline_files(parent_model)
28
+ elif isinstance(parent_model, File):
29
+ if not parent_model.exists():
30
+ raise Exception(f'File {parent_model.filename} does not exist.')
31
+ file_name = parent_model.filename
32
+ file_list.append(parent_model.file_path)
33
+
34
+ token = self.generate_download_token(file_name, file_list, ignore_folder_structure)
35
+ download = Download(token)
36
+
37
+ return self(download, user)
38
+
39
+ def fetch_pipeline_files(pipeline: Pipeline):
40
+ config_path = pipeline.config_path
41
+
42
+ zip_name = f'{pipeline.uuid}.zip'
43
+ file_list = [config_path] + [block.file_path for block in pipeline.blocks_by_uuid.values()]
44
+
45
+ return [zip_name, file_list]
46
+
47
+ def generate_download_token(file_name, file_list, ignore_folder_structure):
48
+ now = datetime.datetime.utcnow()
49
+ payload = {
50
+ 'file_name': file_name,
51
+ 'file_list': file_list,
52
+ 'ignore_folder_structure': ignore_folder_structure,
53
+ 'iat': now,
54
+ 'exp': now + datetime.timedelta(seconds=DOWNLOAD_TOKEN_LIFESPAN)
55
+ }
56
+ return jwt.encode(payload, JWT_DOWNLOAD_SECRET, algorithm="HS256")
@@ -18,7 +18,7 @@ class ExecutionStateResource(GenericResource):
18
18
 
19
19
  if pipeline_uuid and block_uuid:
20
20
  pipeline = await Pipeline.get_async(pipeline_uuid)
21
- if pipeline and PipelineType.PYTHON == pipeline.type:
21
+ if pipeline and pipeline.type in [PipelineType.PYTHON, PipelineType.PYSPARK]:
22
22
  block = pipeline.get_block(block_uuid)
23
23
  if block and block.compute_management_enabled() and block.is_using_spark():
24
24
  arr.append(dict(
@@ -0,0 +1,192 @@
1
+ import asyncio
2
+ from typing import Dict, List
3
+
4
+ from mage_ai.api.errors import ApiError
5
+ from mage_ai.api.resources.AsyncBaseResource import AsyncBaseResource
6
+ from mage_ai.api.resources.PipelineResource import PipelineResource
7
+ from mage_ai.authentication.permissions.constants import EntityName
8
+ from mage_ai.data_preparation.models.global_hooks.constants import (
9
+ DISABLED_RESOURCE_TYPES,
10
+ )
11
+ from mage_ai.data_preparation.models.global_hooks.models import (
12
+ GlobalHooks,
13
+ Hook,
14
+ HookOperation,
15
+ )
16
+ from mage_ai.data_preparation.models.pipeline import Pipeline
17
+ from mage_ai.orchestration.db.models.oauth import User
18
+ from mage_ai.shared.array import find
19
+ from mage_ai.shared.hash import ignore_keys
20
+
21
+
22
+ class GlobalHookResource(AsyncBaseResource):
23
+ @classmethod
24
+ async def collection(self, query: Dict, _meta: Dict, user: User, **kwargs):
25
+ operation_types = query.get('operation_type[]', [])
26
+ if operation_types:
27
+ operation_types = operation_types[0]
28
+ if isinstance(operation_types, str):
29
+ operation_types = [HookOperation(m) for m in operation_types.split(',') if m]
30
+
31
+ resource_types = query.get('resource_type[]', [])
32
+ if resource_types:
33
+ resource_types = resource_types[0]
34
+ if isinstance(resource_types, str):
35
+ resource_types = [EntityName(m) for m in resource_types.split(',') if m]
36
+
37
+ global_hooks = GlobalHooks.load_from_file()
38
+
39
+ return self.build_result_set(
40
+ global_hooks.hooks(
41
+ operation_types=operation_types,
42
+ resource_types=resource_types,
43
+ ),
44
+ user,
45
+ **kwargs,
46
+ )
47
+
48
+ @classmethod
49
+ async def create(self, payload: Dict, user: User, **kwargs) -> 'GlobalHookResource':
50
+ if user and user.id:
51
+ payload['metadata'] = dict(
52
+ user=dict(
53
+ id=user.id,
54
+ ),
55
+ )
56
+
57
+ hook = Hook.load(**payload)
58
+
59
+ if not hook.uuid or not hook.resource_type or not hook.operation_type:
60
+ missing = []
61
+ if not hook.resource_type:
62
+ missing.append('resource_type')
63
+ if not hook.operation_type:
64
+ missing.append('operation_type')
65
+ if not hook.uuid:
66
+ missing.append('uuid')
67
+
68
+ error = ApiError.RESOURCE_INVALID.copy()
69
+ error.update(
70
+ message=f'Hook is missing the following required attributes: {", ".join(missing)}.',
71
+ )
72
+ raise ApiError(error)
73
+
74
+ if hook.resource_type and hook.resource_type in DISABLED_RESOURCE_TYPES:
75
+ error = ApiError.RESOURCE_INVALID.copy()
76
+ error.update(
77
+ message=f'Hooks cannot be created for resource type {hook.resource_type.value}.',
78
+ )
79
+ raise ApiError(error)
80
+
81
+ global_hooks = GlobalHooks.load_from_file()
82
+ if global_hooks.get_hook(
83
+ operation_type=hook.operation_type,
84
+ resource_type=hook.resource_type,
85
+ uuid=hook.uuid,
86
+ ):
87
+ error = ApiError.RESOURCE_INVALID.copy()
88
+ error.update(
89
+ message=f'Hook {hook.uuid} already exists for resource '
90
+ f'{hook.resource_type} and operation {hook.operation_type}.',
91
+ )
92
+ raise ApiError(error)
93
+
94
+ global_hooks.add_hook(hook, snapshot=True)
95
+ global_hooks.save()
96
+
97
+ return self(hook, user, **kwargs)
98
+
99
+ @classmethod
100
+ async def member(self, pk: str, user: User, **kwargs):
101
+ query = kwargs.get('query') or {}
102
+
103
+ resource_type = query.get('resource_type', [None])
104
+ if resource_type:
105
+ resource_type = resource_type[0]
106
+
107
+ operation_type = query.get('operation_type', [None])
108
+ if operation_type:
109
+ operation_type = operation_type[0]
110
+
111
+ include_operation_types = query.get('include_operation_types', [None])
112
+ if include_operation_types:
113
+ include_operation_types = include_operation_types[0]
114
+
115
+ include_resource_types = query.get('include_resource_types', [None])
116
+ if include_resource_types:
117
+ include_resource_types = include_resource_types[0]
118
+
119
+ global_hooks = GlobalHooks.load_from_file()
120
+ hook = global_hooks.get_hook(
121
+ operation_type=HookOperation(operation_type) if operation_type else operation_type,
122
+ resource_type=EntityName(resource_type) if resource_type else resource_type,
123
+ uuid=pk,
124
+ )
125
+
126
+ if not hook and not include_operation_types and not include_resource_types:
127
+ raise ApiError(ApiError.RESOURCE_NOT_FOUND)
128
+
129
+ return self(hook, user, **kwargs)
130
+
131
+ async def update(self, payload: Dict, **kwargs):
132
+ global_hooks = GlobalHooks.load_from_file()
133
+ self.model = global_hooks.add_hook(
134
+ self.model,
135
+ payload=ignore_keys(payload, ['snapshot']),
136
+ snapshot=payload.get('snapshot') or False,
137
+ update=True,
138
+ )
139
+ global_hooks.save()
140
+
141
+ async def delete(self, **kwargs):
142
+ global_hooks = GlobalHooks.load_from_file()
143
+ global_hooks.remove_hook(self.model)
144
+ global_hooks.save()
145
+
146
+
147
+ async def __load_pipelines(resource: GlobalHookResource):
148
+ pipeline_uuids = []
149
+ for res in resource.result_set():
150
+ if res.model.pipeline_settings and res.model.pipeline_settings.get('uuid'):
151
+ pipeline_uuid = res.model.pipeline_settings.get('uuid')
152
+ if pipeline_uuid:
153
+ pipeline_uuids.append(pipeline_uuid)
154
+
155
+ async def get_pipeline(uuid):
156
+ try:
157
+ return await Pipeline.get_async(uuid)
158
+ except Exception as err:
159
+ err_message = f'Error loading pipeline {uuid}: {err}.'
160
+ if err.__class__.__name__ == 'OSError' and 'Too many open files' in err.strerror:
161
+ raise Exception(err_message)
162
+ else:
163
+ print(err_message)
164
+ return None
165
+
166
+ pipelines = await asyncio.gather(
167
+ *[get_pipeline(uuid) for uuid in pipeline_uuids]
168
+ )
169
+ pipelines = [p for p in pipelines if p is not None]
170
+
171
+ return PipelineResource.build_result_set(pipelines, resource.current_user)
172
+
173
+
174
+ async def __find_pipeline(resource: GlobalHookResource, arr: List[PipelineResource]):
175
+ pipeline_uuid = resource.model.pipeline_settings and resource.model.pipeline_settings.get(
176
+ 'uuid',
177
+ )
178
+
179
+ if not pipeline_uuid:
180
+ return
181
+
182
+ return find(
183
+ lambda x, pipeline_uuid=pipeline_uuid: x.uuid == pipeline_uuid,
184
+ arr,
185
+ )
186
+
187
+
188
+ GlobalHookResource.register_collective_loader(
189
+ 'pipeline_details',
190
+ load=__load_pipelines,
191
+ select=__find_pipeline,
192
+ )
@@ -7,6 +7,7 @@ from mage_ai.server.active_kernel import (
7
7
  switch_active_kernel,
8
8
  )
9
9
  from mage_ai.server.kernels import DEFAULT_KERNEL_NAME, KernelName, kernel_managers
10
+ from mage_ai.services.ssh.aws.emr.utils import tunnel
10
11
 
11
12
 
12
13
  class KernelResource(GenericResource):
@@ -56,4 +57,13 @@ class KernelResource(GenericResource):
56
57
  if 'start_kernel' in str(e):
57
58
  start_kernel()
58
59
 
60
+ def _callback(*args, **kwargs):
61
+ tunnel(
62
+ kernel_name=self.model.kernel_name,
63
+ reconnect=True,
64
+ validate_conditions=True,
65
+ )
66
+
67
+ self.on_update_callback = _callback
68
+
59
69
  return self
@@ -1,4 +1,3 @@
1
- import json
2
1
  import urllib.parse
3
2
  from datetime import datetime, timedelta
4
3
  from urllib.parse import parse_qs, urlparse
@@ -7,10 +6,8 @@ from mage_ai.api.errors import ApiError
7
6
  from mage_ai.api.resources.GenericResource import GenericResource
8
7
  from mage_ai.authentication.oauth2 import generate_access_token
9
8
  from mage_ai.authentication.oauth.constants import (
10
- ACTIVE_DIRECTORY_CLIENT_ID,
11
9
  GITHUB_CLIENT_ID,
12
10
  GITHUB_STATE,
13
- OAUTH_PROVIDER_ACTIVE_DIRECTORY,
14
11
  OAUTH_PROVIDER_GHE,
15
12
  OAUTH_PROVIDER_GITHUB,
16
13
  VALID_OAUTH_PROVIDERS,
@@ -24,10 +21,31 @@ from mage_ai.authentication.providers.constants import NAME_TO_PROVIDER
24
21
  from mage_ai.data_preparation.git.api import get_oauth_client_id
25
22
  from mage_ai.orchestration.db import safe_db_query
26
23
  from mage_ai.orchestration.db.models.oauth import Oauth2AccessToken, Oauth2Application
27
- from mage_ai.settings import ACTIVE_DIRECTORY_DIRECTORY_ID
28
24
 
29
25
 
30
26
  class OauthResource(GenericResource):
27
+ @classmethod
28
+ @safe_db_query
29
+ async def collection(self, query, meta, user, **kwargs):
30
+ redirect_uri = query.get('redirect_uri', [None])
31
+ if redirect_uri:
32
+ redirect_uri = redirect_uri[0]
33
+
34
+ oauths = []
35
+ for provider, provider_class in NAME_TO_PROVIDER.items():
36
+ try:
37
+ provider_instance = provider_class()
38
+ auth_url_response = provider_instance.get_auth_url_response(
39
+ redirect_uri=redirect_uri
40
+ )
41
+ if auth_url_response:
42
+ auth_url_response['provider'] = provider
43
+ oauths.append(auth_url_response)
44
+ except Exception:
45
+ continue
46
+
47
+ return self.build_result_set(oauths, user, **kwargs)
48
+
31
49
  @classmethod
32
50
  @safe_db_query
33
51
  def create(self, payload, user, **kwargs):
@@ -171,36 +189,13 @@ class OauthResource(GenericResource):
171
189
  for k, v in query.items():
172
190
  query_strings.append(f'{k}={v}')
173
191
 
174
- model['url'] = f"https://github.com/login/oauth/authorize?{'&'.join(query_strings)}"
175
- elif OAUTH_PROVIDER_ACTIVE_DIRECTORY == pk:
176
- ad_directory_id = ACTIVE_DIRECTORY_DIRECTORY_ID
177
- if ad_directory_id:
178
- from requests.models import PreparedRequest
179
-
180
- req = PreparedRequest()
181
- req.prepare_url(redirect_uri, dict(provider=pk))
182
- query = dict(
183
- client_id=ACTIVE_DIRECTORY_CLIENT_ID,
184
- redirect_uri=f'https://api.mage.ai/v1/oauth/{pk}',
185
- response_type='code',
186
- scope='User.Read',
187
- state=urllib.parse.quote_plus(
188
- json.dumps(
189
- dict(
190
- redirect_uri=req.url,
191
- tenant_id=ad_directory_id,
192
- )
193
- )
194
- ),
195
- )
196
- query_strings = []
197
- for k, v in query.items():
198
- query_strings.append(f'{k}={v}')
199
- model[
200
- 'url'
201
- ] = f"https://login.microsoftonline.com/{ad_directory_id}/oauth2/v2.0/authorize?{'&'.join(query_strings)}" # noqa: E501
192
+ model[
193
+ 'url'
194
+ ] = f"https://github.com/login/oauth/authorize?{'&'.join(query_strings)}"
202
195
  elif provider_instance is not None:
203
- resp = provider_instance.get_auth_url_response(redirect_uri=redirect_uri)
196
+ resp = provider_instance.get_auth_url_response(
197
+ redirect_uri=redirect_uri
198
+ )
204
199
  if resp:
205
200
  model.update(resp)
206
201
 
@@ -67,15 +67,15 @@ class PipelineResource(BaseResource):
67
67
  tags = new_tags
68
68
 
69
69
  pipeline_types = query.get('type[]', [])
70
- if pipeline_types:
70
+ if pipeline_types and len(pipeline_types) == 1:
71
71
  pipeline_types = pipeline_types[0]
72
- if pipeline_types:
72
+ if pipeline_types and isinstance(pipeline_types, str):
73
73
  pipeline_types = pipeline_types.split(',')
74
74
 
75
75
  pipeline_statuses = query.get('status[]', [])
76
- if pipeline_statuses:
76
+ if pipeline_statuses and len(pipeline_statuses) == 1:
77
77
  pipeline_statuses = pipeline_statuses[0]
78
- if pipeline_statuses:
78
+ if pipeline_statuses and isinstance(pipeline_statuses, str):
79
79
  pipeline_statuses = pipeline_statuses.split(',')
80
80
 
81
81
  from_history_days = query.get('from_history_days', [None])
@@ -3,6 +3,7 @@ import uuid
3
3
  from sqlalchemy.orm import selectinload
4
4
 
5
5
  from mage_ai.api.resources.DatabaseResource import DatabaseResource
6
+ from mage_ai.data_preparation.models.pipeline import Pipeline
6
7
  from mage_ai.data_preparation.models.triggers import (
7
8
  Trigger,
8
9
  add_or_update_trigger_for_pipeline_and_persist,
@@ -146,6 +147,20 @@ class PipelineScheduleResource(DatabaseResource):
146
147
  if 'token' not in payload:
147
148
  payload['token'] = uuid.uuid4().hex
148
149
 
150
+ if pipeline.should_save_trigger_in_code_automatically():
151
+ def _callback(resource, kwargs=kwargs, user=user):
152
+ from mage_ai.api.resources.PipelineTriggerResource import (
153
+ PipelineTriggerResource,
154
+ )
155
+
156
+ PipelineTriggerResource.create(
157
+ dict(pipeline_schedule_id=resource.id),
158
+ user,
159
+ **kwargs,
160
+ )
161
+
162
+ self.on_create_callback = _callback
163
+
149
164
  return super().create(payload, user, **kwargs)
150
165
 
151
166
  @safe_db_query
@@ -257,22 +272,28 @@ class PipelineScheduleResource(DatabaseResource):
257
272
 
258
273
  resource = super().update(payload)
259
274
  updated_model = resource.model
260
- trigger = Trigger(
261
- name=updated_model.name,
262
- pipeline_uuid=updated_model.pipeline_uuid,
263
- schedule_interval=updated_model.schedule_interval,
264
- schedule_type=updated_model.schedule_type,
265
- settings=updated_model.settings,
266
- sla=updated_model.sla,
267
- start_time=updated_model.start_time,
268
- status=updated_model.status,
269
- variables=updated_model.variables,
270
- )
271
- add_or_update_trigger_for_pipeline_and_persist(
272
- trigger,
273
- updated_model.pipeline_uuid,
274
- update_only_if_exists=True,
275
- )
275
+
276
+ pipeline = Pipeline.get(updated_model.pipeline_uuid)
277
+ if pipeline:
278
+ trigger = Trigger(
279
+ name=updated_model.name,
280
+ pipeline_uuid=updated_model.pipeline_uuid,
281
+ schedule_interval=updated_model.schedule_interval,
282
+ schedule_type=updated_model.schedule_type,
283
+ settings=updated_model.settings,
284
+ sla=updated_model.sla,
285
+ start_time=updated_model.start_time,
286
+ status=updated_model.status,
287
+ variables=updated_model.variables,
288
+ )
289
+
290
+ update_only_if_exists = not pipeline.should_save_trigger_in_code_automatically()
291
+
292
+ add_or_update_trigger_for_pipeline_and_persist(
293
+ trigger,
294
+ pipeline.uuid,
295
+ update_only_if_exists=update_only_if_exists,
296
+ )
276
297
 
277
298
  return self
278
299
 
@@ -86,6 +86,9 @@ class ProjectResource(GenericResource):
86
86
  if 'emr_config' in payload:
87
87
  data['emr_config'] = payload['emr_config']
88
88
 
89
+ if 'pipelines' in payload:
90
+ data['pipelines'] = payload['pipelines']
91
+
89
92
  if 'spark_config' in payload:
90
93
  data['spark_config'] = payload['spark_config']
91
94
 
@@ -100,9 +103,8 @@ class ProjectResource(GenericResource):
100
103
  if should_log_project:
101
104
  await UsageStatisticLogger().project_impression()
102
105
 
103
- if Project(repo_config=repo_config).is_feature_enabled(
104
- FeatureUUID.DATA_INTEGRATION_IN_BATCH_PIPELINE,
105
- ):
106
+ project = Project(repo_config=repo_config)
107
+ if project.is_feature_enabled(FeatureUUID.DATA_INTEGRATION_IN_BATCH_PIPELINE):
106
108
  await BlockActionObjectCache.initialize_cache(replace=True)
107
109
 
108
110
  return self
@@ -4,8 +4,6 @@ from mage_ai.api.errors import ApiError
4
4
  from mage_ai.api.resources.BaseResource import BaseResource
5
5
  from mage_ai.authentication.ldap import new_ldap_connection
6
6
  from mage_ai.authentication.oauth2 import encode_token, generate_access_token
7
- from mage_ai.authentication.oauth.active_directory import get_user_info
8
- from mage_ai.authentication.oauth.constants import OAUTH_PROVIDER_ACTIVE_DIRECTORY
9
7
  from mage_ai.authentication.passwords import verify_password
10
8
  from mage_ai.authentication.providers.constants import NAME_TO_PROVIDER
11
9
  from mage_ai.orchestration.db import safe_db_query
@@ -30,15 +28,8 @@ class SessionResource(BaseResource):
30
28
  if token and provider:
31
29
  roles = []
32
30
  provider_class = NAME_TO_PROVIDER.get(provider)
33
- provider_instance = None
34
31
  if provider_class is not None:
35
32
  provider_instance = provider_class()
36
-
37
- if provider == OAUTH_PROVIDER_ACTIVE_DIRECTORY:
38
- user_info = get_user_info(token)
39
- username = user_info.get('userPrincipalName')
40
- email = user_info.get('userPrincipalName')
41
- elif provider_instance is not None:
42
33
  user_info = await provider_instance.get_user_info(access_token=token)
43
34
  email = user_info.get('email')
44
35
  username = user_info.get('username')