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,21 @@
1
+ from typing import Dict
2
+
3
+ from mage_ai.authentication.permissions.constants import EntityName
4
+ from mage_ai.data_preparation.models.global_hooks.constants import (
5
+ DISABLED_RESOURCE_TYPES,
6
+ RESTRICTED_RESOURCE_TYPES,
7
+ VALID_KEYS_FOR_INPUT_OUTPUT_DATA_ALL,
8
+ VALID_KEYS_FOR_INPUT_OUTPUT_DATA_UNRESTRICTED,
9
+ )
10
+ from mage_ai.shared.hash import extract
11
+
12
+
13
+ def extract_valid_data(resource_type: EntityName, input_data: Dict) -> Dict:
14
+ types = DISABLED_RESOURCE_TYPES + RESTRICTED_RESOURCE_TYPES
15
+ if not resource_type or resource_type in types:
16
+ return extract(input_data or {}, VALID_KEYS_FOR_INPUT_OUTPUT_DATA_UNRESTRICTED)
17
+
18
+ return extract(
19
+ input_data or {},
20
+ VALID_KEYS_FOR_INPUT_OUTPUT_DATA_ALL,
21
+ )
@@ -6,10 +6,12 @@ import shutil
6
6
  from typing import Any, Callable, Dict, List
7
7
 
8
8
  import aiofiles
9
+ import dateutil.parser
9
10
  import pytz
10
11
  import yaml
11
12
  from jinja2 import Template
12
13
 
14
+ from mage_ai.authentication.permissions.constants import EntityName
13
15
  from mage_ai.data_preparation.models.block import Block, run_blocks, run_blocks_sync
14
16
  from mage_ai.data_preparation.models.block.data_integration.utils import (
15
17
  convert_outputs_to_data,
@@ -30,6 +32,9 @@ from mage_ai.data_preparation.models.constants import (
30
32
  )
31
33
  from mage_ai.data_preparation.models.errors import SerializationError
32
34
  from mage_ai.data_preparation.models.file import File
35
+ from mage_ai.data_preparation.models.pipelines.models import PipelineSettings
36
+ from mage_ai.data_preparation.models.project import Project
37
+ from mage_ai.data_preparation.models.project.constants import FeatureUUID
33
38
  from mage_ai.data_preparation.models.utils import is_yaml_serializable
34
39
  from mage_ai.data_preparation.models.variable import Variable
35
40
  from mage_ai.data_preparation.repo_manager import (
@@ -72,22 +77,21 @@ class Pipeline:
72
77
  self.retry_config = {}
73
78
  self.run_pipeline_in_one_process = False
74
79
  self.schedules = []
80
+ self.settings = {}
75
81
  self.tags = []
76
82
  self.type = PipelineType.PYTHON
77
- self.updated_at = datetime.datetime.now(tz=pytz.UTC)
83
+ self.updated_at = datetime.datetime.utcnow().replace(tzinfo=pytz.UTC)
78
84
  self.uuid = uuid
79
85
  self.widget_configs = []
80
86
  self._executor_count = 1 # Used by streaming pipeline to launch multiple executors
81
- if config is None:
82
- self.load_config_from_yaml()
83
- else:
84
- self.load_config(config, catalog=catalog)
87
+
85
88
  if repo_config is None:
86
89
  self.repo_config = get_repo_config(repo_path=self.repo_path)
87
90
  elif type(repo_config) is dict:
88
91
  self.repo_config = RepoConfig.from_dict(repo_config)
89
92
  else:
90
93
  self.repo_config = repo_config
94
+
91
95
  self.variable_manager = VariableManager.get_manager(
92
96
  self.repo_path,
93
97
  self.remote_variables_dir or self.variables_dir,
@@ -96,6 +100,11 @@ class Pipeline:
96
100
  # Used for showing the operation history. For example: recently viewed pipelines.
97
101
  self.history = []
98
102
 
103
+ if config is None:
104
+ self.load_config_from_yaml()
105
+ else:
106
+ self.load_config(config, catalog=catalog)
107
+
99
108
  @property
100
109
  def config_path(self):
101
110
  return os.path.join(
@@ -421,6 +430,7 @@ class Pipeline:
421
430
  global_vars=None,
422
431
  run_sensors: bool = True,
423
432
  run_tests: bool = True,
433
+ update_status: bool = True,
424
434
  ) -> None:
425
435
  """
426
436
  Function for synchronous block processing.
@@ -454,6 +464,7 @@ class Pipeline:
454
464
  global_vars=global_vars,
455
465
  run_sensors=run_sensors,
456
466
  run_tests=run_tests,
467
+ update_status=update_status,
457
468
  )
458
469
 
459
470
  def get_config_from_yaml(self):
@@ -491,6 +502,8 @@ class Pipeline:
491
502
  pass
492
503
  self.created_at = config.get('created_at')
493
504
  self.updated_at = config.get('updated_at')
505
+ if self.updated_at and isinstance(self.updated_at, str):
506
+ self.updated_at = dateutil.parser.parse(self.updated_at).replace(tzinfo=pytz.UTC)
494
507
  self.type = config.get('type') or self.type
495
508
 
496
509
  self.block_configs = config.get('blocks') or []
@@ -502,6 +515,7 @@ class Pipeline:
502
515
  self.notification_config = config.get('notification_config') or {}
503
516
  self.retry_config = config.get('retry_config') or {}
504
517
  self.run_pipeline_in_one_process = config.get('run_pipeline_in_one_process', False)
518
+ self.settings = PipelineSettings.load(**config.get('settings') or {})
505
519
  self.spark_config = config.get('spark_config') or {}
506
520
  self.tags = config.get('tags') or []
507
521
  self.widget_configs = config.get('widgets') or []
@@ -525,6 +539,7 @@ class Pipeline:
525
539
  language=c.get('language'),
526
540
  pipeline=self,
527
541
  replicated_block=c.get('replicated_block'),
542
+ repo_config=self.repo_config,
528
543
  retry_config=c.get('retry_config'),
529
544
  status=c.get('status'),
530
545
  timeout=c.get('timeout'),
@@ -614,6 +629,10 @@ class Pipeline:
614
629
  return blocks_by_uuid
615
630
 
616
631
  def to_dict_base(self, exclude_data_integration=False) -> Dict:
632
+ updated_at = self.updated_at
633
+ if updated_at and hasattr(updated_at, 'isoformat'):
634
+ updated_at = updated_at.isoformat()
635
+
617
636
  base = dict(
618
637
  concurrency_config=self.concurrency_config,
619
638
  created_at=self.created_at,
@@ -626,9 +645,10 @@ class Pipeline:
626
645
  notification_config=self.notification_config,
627
646
  retry_config=self.retry_config,
628
647
  run_pipeline_in_one_process=self.run_pipeline_in_one_process,
648
+ settings=self.settings.to_dict() if self.settings else self.settings,
629
649
  tags=self.tags,
630
650
  type=self.type.value if type(self.type) is not str else self.type,
631
- updated_at=self.updated_at,
651
+ updated_at=updated_at,
632
652
  uuid=self.uuid,
633
653
  )
634
654
 
@@ -852,6 +872,10 @@ class Pipeline:
852
872
  setattr(self, key, data.get(key))
853
873
  should_save = True
854
874
 
875
+ if 'settings' in data:
876
+ self.settings = PipelineSettings.load(**(data.get('settings') or {}))
877
+ should_save = True
878
+
855
879
  blocks = data.get('blocks', [])
856
880
 
857
881
  if blocks:
@@ -888,6 +912,16 @@ class Pipeline:
888
912
  self.extensions.get(extension_uuid, {}).get('blocks_by_uuid', {}),
889
913
  ))
890
914
 
915
+ global_hooks = None
916
+ if len(arr) >= 1:
917
+ project = Project(self.repo_config)
918
+ if project.is_feature_enabled(FeatureUUID.GLOBAL_HOOKS):
919
+ from mage_ai.data_preparation.models.global_hooks.models import (
920
+ GlobalHooks,
921
+ )
922
+
923
+ global_hooks = GlobalHooks.load_from_file()
924
+
891
925
  for tup in arr:
892
926
  key, blocks_arr, mapping = tup
893
927
  widget = key == 'widgets'
@@ -901,6 +935,32 @@ class Pipeline:
901
935
  block = mapping.get(block_data['uuid'])
902
936
  if block is None:
903
937
  continue
938
+
939
+ if global_hooks:
940
+ from mage_ai.data_preparation.models.global_hooks.models import (
941
+ HookOperation,
942
+ HookStage,
943
+ )
944
+
945
+ hooks = global_hooks.get_and_run_hooks(
946
+ operation_resource=block,
947
+ operation_types=[HookOperation.UPDATE_ANYWHERE],
948
+ resource_type=EntityName.Block,
949
+ stage=HookStage.BEFORE,
950
+ payload=block_data,
951
+ )
952
+
953
+ if hooks:
954
+ for hook in (hooks or []):
955
+ output = hook.output
956
+ if not output:
957
+ continue
958
+
959
+ if output.get('payload'):
960
+ value = output.get('payload') or {}
961
+ if isinstance(value, dict):
962
+ block_data = merge_dict(block_data, value)
963
+
904
964
  if 'content' in block_data:
905
965
  from mage_ai.cache.block_action_object import (
906
966
  BlockActionObjectCache,
@@ -1677,6 +1737,22 @@ class Pipeline:
1677
1737
  file_version_only=True,
1678
1738
  )
1679
1739
 
1740
+ def should_save_trigger_in_code_automatically(self) -> bool:
1741
+ from mage_ai.data_preparation.models.project import Project
1742
+
1743
+ if self.settings and \
1744
+ self.settings.triggers and \
1745
+ self.settings.triggers.save_in_code_automatically is not None:
1746
+
1747
+ return self.settings.triggers.save_in_code_automatically
1748
+
1749
+ project = Project(self.repo_config)
1750
+
1751
+ return project.pipelines and \
1752
+ project.pipelines.settings and \
1753
+ project.pipelines.settings.triggers and \
1754
+ project.pipelines.settings.triggers.save_in_code_automatically
1755
+
1680
1756
  async def save_async(
1681
1757
  self,
1682
1758
  block_type: str = None,
@@ -0,0 +1,16 @@
1
+ from dataclasses import dataclass
2
+
3
+ from mage_ai.shared.models import BaseDataClass
4
+
5
+
6
+ @dataclass
7
+ class PipelineSettingsTriggers(BaseDataClass):
8
+ save_in_code_automatically: bool = None
9
+
10
+
11
+ @dataclass
12
+ class PipelineSettings(BaseDataClass):
13
+ triggers: PipelineSettingsTriggers = None
14
+
15
+ def __post_init__(self):
16
+ self.serialize_attribute_class('triggers', PipelineSettingsTriggers)
@@ -35,6 +35,8 @@ class Project():
35
35
  features = self.repo_config.features
36
36
 
37
37
  for uuid in FeatureUUID:
38
+ if FeatureUUID.GLOBAL_HOOKS == uuid:
39
+ continue
38
40
  key = uuid.value
39
41
  data[key] = features.get(key) if features else None
40
42
 
@@ -52,6 +54,10 @@ class Project():
52
54
  def remote_variables_dir(self) -> Dict:
53
55
  return self.repo_config.remote_variables_dir
54
56
 
57
+ @property
58
+ def pipelines(self) -> Dict:
59
+ return self.repo_config.pipelines
60
+
55
61
  def is_feature_enabled(self, feature_name: FeatureUUID) -> str:
56
62
  feature_enabled = self.repo_config.features.get(feature_name.value, False)
57
63
 
@@ -5,6 +5,7 @@ class FeatureUUID(str, Enum):
5
5
  ADD_NEW_BLOCK_V2 = 'add_new_block_v2'
6
6
  COMPUTE_MANAGEMENT = 'compute_management'
7
7
  DATA_INTEGRATION_IN_BATCH_PIPELINE = 'data_integration_in_batch_pipeline'
8
+ GLOBAL_HOOKS = 'global_hooks'
8
9
  INTERACTIONS = 'interactions'
9
10
  LOCAL_TIMEZONE = 'display_local_timezone'
10
11
  NOTEBOOK_BLOCK_OUTPUT_SPLIT_VIEW = 'notebook_block_output_split_view'
@@ -0,0 +1,12 @@
1
+ from dataclasses import dataclass
2
+
3
+ from mage_ai.data_preparation.models.pipelines.models import PipelineSettings
4
+ from mage_ai.shared.models import BaseDataClass
5
+
6
+
7
+ @dataclass
8
+ class ProjectPipelines(BaseDataClass):
9
+ settings: PipelineSettings = None
10
+
11
+ def __post_init__(self):
12
+ self.serialize_attribute_class('settings', PipelineSettings)
@@ -57,6 +57,7 @@ class RepoConfig:
57
57
  self.queue_config = None
58
58
  self.help_improve_mage = None
59
59
  self.openai_api_key = None
60
+ self._pipelines = None
60
61
  self.retry_config = None
61
62
  self.ldap_config = None
62
63
  self.s3_bucket = None
@@ -117,6 +118,7 @@ class RepoConfig:
117
118
  self.project_uuid = repo_config.get('project_uuid')
118
119
  self.help_improve_mage = repo_config.get('help_improve_mage')
119
120
  self.openai_api_key = repo_config.get('openai_api_key')
121
+ self.pipelines = repo_config.get('pipelines')
120
122
  self.retry_config = repo_config.get('retry_config')
121
123
 
122
124
  self.ldap_config = repo_config.get('ldap_config')
@@ -149,6 +151,22 @@ class RepoConfig:
149
151
  else:
150
152
  return get_metadata_path()
151
153
 
154
+ @property
155
+ def pipelines(self):
156
+ if isinstance(self._pipelines, dict):
157
+ self.pipelines = self._pipelines
158
+
159
+ return self._pipelines
160
+
161
+ @pipelines.setter
162
+ def pipelines(self, pipelines: Dict = None) -> None:
163
+ from mage_ai.data_preparation.models.project.models import ProjectPipelines
164
+
165
+ if isinstance(pipelines, dict):
166
+ self._pipelines = ProjectPipelines.load(**(pipelines or {}))
167
+ else:
168
+ self._pipelines = pipelines
169
+
152
170
  def to_dict(self, remote: bool = False) -> Dict:
153
171
  return dict(
154
172
  ai_config=self.ai_config,
@@ -160,6 +178,7 @@ class RepoConfig:
160
178
  help_improve_mage=self.help_improve_mage,
161
179
  notification_config=self.notification_config,
162
180
  openai_api_key=self.openai_api_key,
181
+ pipelines=self.pipelines.to_dict() if self.pipelines else self.pipelines,
163
182
  project_type=self.project_type,
164
183
  project_uuid=self.project_uuid,
165
184
  queue_config=self.queue_config,
@@ -179,7 +198,10 @@ class RepoConfig:
179
198
 
180
199
  for key, value in kwargs.items():
181
200
  data[key] = value
182
- if hasattr(self, key):
201
+
202
+ if 'pipelines' == key:
203
+ self.pipelines = value
204
+ elif hasattr(self, key):
183
205
  setattr(self, key, value)
184
206
 
185
207
  with open(self.metadata_path, 'w') as f:
@@ -0,0 +1,6 @@
1
+ connector_type: 'activemq'
2
+ connection_host: 'localhost'
3
+ connection_port: 61613
4
+ queue_name: 'default'
5
+ username: 'admin'
6
+ password: 'admin'
@@ -0,0 +1,20 @@
1
+ connector_type: nats
2
+ server_url: "nats://localhost:4222"
3
+ subject: subject_name
4
+ stream_name: stream_name
5
+
6
+ # Optional: Batch size and timeout for reading messages
7
+ batch_size: 100
8
+ timeout: 5
9
+
10
+ # Optional: TLS configuration
11
+ use_tls: false
12
+ # cafile: "path/to/ca.pem"
13
+ # certfile: "path/to/client-cert.pem"
14
+ # keyfile: "path/to/client-key.pem"
15
+
16
+ # Optional: NKEY seed string
17
+ # nkeys_seed_str: "SUAPAEYJQOQHJ4"
18
+
19
+ # Optional: Consumer name for pull-based subscription
20
+ consumer_name: "my_consumer"
@@ -657,7 +657,7 @@ class PipelineRun(BaseModel):
657
657
  def pipeline_type(self) -> PipelineType:
658
658
  pipeline = Pipeline.get(self.pipeline_uuid, check_if_exists=True)
659
659
 
660
- return self.pipeline.type if pipeline is not None else None
660
+ return pipeline.type if pipeline is not None else None
661
661
 
662
662
  @property
663
663
  def logs(self):
@@ -690,7 +690,7 @@ class PipelineRun(BaseModel):
690
690
  def pipeline_tags(self):
691
691
  pipeline = Pipeline.get(self.pipeline_uuid, check_if_exists=True)
692
692
 
693
- return self.pipeline.tags if pipeline is not None else []
693
+ return pipeline.tags if pipeline is not None else []
694
694
 
695
695
  def executable_block_runs(
696
696
  self,
@@ -116,7 +116,15 @@ class ProcessQueue(Queue):
116
116
  if job_client_id != self.client_id and self.redis_client.get(job_client_id):
117
117
  return True
118
118
  job = self.job_dict.get(job_id)
119
- return job is not None and (job == JobStatus.QUEUED or isinstance(job, int))
119
+ return (
120
+ job is not None and
121
+ (
122
+ # In queue
123
+ (job == JobStatus.QUEUED and not self.queue.empty()) or
124
+ # Running
125
+ isinstance(job, int)
126
+ )
127
+ )
120
128
 
121
129
  def kill_job(self, job_id: str):
122
130
  """
@@ -22,18 +22,21 @@ def trigger_pipeline(
22
22
  error_on_failure: bool = False,
23
23
  poll_interval: float = DEFAULT_POLL_INTERVAL,
24
24
  poll_timeout: Optional[float] = None,
25
+ schedule_name: str = None,
25
26
  verbose: bool = True,
27
+ _should_schedule: bool = False, # For internal use only (e.g. running hooks from notebook).
26
28
  ) -> PipelineRun:
27
29
  if variables is None:
28
30
  variables = {}
29
31
  pipeline = Pipeline.get(pipeline_uuid)
30
32
 
31
- pipeline_schedule = __fetch_or_create_pipeline_schedule(pipeline)
33
+ pipeline_schedule = __fetch_or_create_pipeline_schedule(pipeline, schedule_name=schedule_name)
32
34
 
33
35
  pipeline_run = create_and_start_pipeline_run(
34
36
  pipeline,
35
37
  pipeline_schedule,
36
38
  dict(variables=variables),
39
+ should_schedule=_should_schedule,
37
40
  )
38
41
 
39
42
  if check_status:
@@ -48,9 +51,14 @@ def trigger_pipeline(
48
51
  return pipeline_run
49
52
 
50
53
 
51
- def __fetch_or_create_pipeline_schedule(pipeline: Pipeline) -> PipelineSchedule:
54
+ def __fetch_or_create_pipeline_schedule(
55
+ pipeline: Pipeline,
56
+ schedule_name: str = None,
57
+ ) -> PipelineSchedule:
58
+ if schedule_name is None:
59
+ schedule_name = TRIGGER_NAME_FOR_TRIGGER_CREATED_FROM_CODE
60
+
52
61
  pipeline_uuid = pipeline.uuid
53
- schedule_name = TRIGGER_NAME_FOR_TRIGGER_CREATED_FROM_CODE
54
62
  schedule_type = ScheduleType.API
55
63
 
56
64
  pipeline_schedule = PipelineSchedule.repo_query.filter(
@@ -1,3 +1,4 @@
1
1
  DEFAULT_POLL_INTERVAL = 60
2
2
  TRIGGER_NAME_FOR_GLOBAL_DATA_PRODUCT = 'GLOBAL_DATA_PRODUCT_TRIGGER'
3
+ TRIGGER_NAME_FOR_GLOBAL_HOOK = 'GLOBAL_HOOK_TRIGGER'
3
4
  TRIGGER_NAME_FOR_TRIGGER_CREATED_FROM_CODE = 'API_TRIGGER_CREATED_FROM_CODE'
@@ -3,8 +3,13 @@ from typing import Dict
3
3
  from jupyter_client import KernelClient, KernelManager
4
4
  from jupyter_client.kernelspec import NoSuchKernel
5
5
 
6
+ from mage_ai.data_preparation.models.project import Project
7
+ from mage_ai.data_preparation.models.project.constants import FeatureUUID
6
8
  from mage_ai.server.kernels import DEFAULT_KERNEL_NAME, KernelName, kernel_managers
7
9
  from mage_ai.server.logger import Logger
10
+ from mage_ai.services.spark.constants import ComputeServiceUUID
11
+ from mage_ai.services.spark.utils import get_compute_service
12
+ from mage_ai.services.ssh.aws.emr.utils import cluster_info_from_tunnel
8
13
 
9
14
  logger = Logger().new_server_logger(__name__)
10
15
 
@@ -68,10 +73,38 @@ def switch_active_kernel(
68
73
  from mage_ai.cluster_manager.aws.emr_cluster_manager import (
69
74
  emr_cluster_manager,
70
75
  )
71
- emr_cluster_manager.set_active_cluster(
72
- auto_selection=True,
73
- emr_config=emr_config,
74
- )
76
+
77
+ should_set_active = True
78
+ auto_creation = True
79
+ cluster_id = None
80
+ project = Project()
81
+
82
+ if project.is_feature_enabled(FeatureUUID.COMPUTE_MANAGEMENT):
83
+ if ComputeServiceUUID.AWS_EMR == get_compute_service(
84
+ emr_config=emr_config,
85
+ kernel_name=kernel_name,
86
+ ):
87
+ auto_creation = False
88
+ should_set_active = False
89
+
90
+ cluster_info = cluster_info_from_tunnel()
91
+
92
+ if cluster_info:
93
+ from mage_ai.services.compute.models import ComputeService
94
+
95
+ cluster_id = cluster_info.get('id') or None
96
+ compute_service = ComputeService(project=project)
97
+ cluster = compute_service.get_cluster_details(cluster_id=cluster_id)
98
+
99
+ should_set_active = cluster.has_dns_name if cluster else False
100
+
101
+ if should_set_active:
102
+ emr_cluster_manager.set_active_cluster(
103
+ auto_creation=auto_creation,
104
+ auto_selection=True,
105
+ cluster_id=cluster_id,
106
+ emr_config=emr_config,
107
+ )
75
108
  except NoSuchKernel as e:
76
109
  if kernel_name == KernelName.PYSPARK:
77
110
  raise Exception(
@@ -1,3 +1,8 @@
1
+ import os
2
+ import tempfile
3
+ import zipfile
4
+
5
+ import jwt
1
6
  from tornado import gen, iostream
2
7
 
3
8
  from mage_ai.api.utils import authenticate_client_and_token
@@ -6,7 +11,8 @@ from mage_ai.data_preparation.models.variable import VariableType
6
11
  from mage_ai.orchestration.db.models.oauth import Oauth2Application
7
12
  from mage_ai.orchestration.db.models.schedules import PipelineRun
8
13
  from mage_ai.server.api.base import BaseHandler
9
- from mage_ai.settings import REQUIRE_USER_AUTHENTICATION
14
+ from mage_ai.settings import JWT_DOWNLOAD_SECRET, REQUIRE_USER_AUTHENTICATION
15
+ from mage_ai.settings.repo import get_repo_path
10
16
 
11
17
 
12
18
  class ApiDownloadHandler(BaseHandler):
@@ -62,3 +68,72 @@ class ApiDownloadHandler(BaseHandler):
62
68
  await self.flush()
63
69
  # Sleep for a nanosecond so other handlers can run and avoid blocking
64
70
  await gen.sleep(0.000000001)
71
+
72
+
73
+ class ApiResourceDownloadHandler(BaseHandler):
74
+
75
+ def get(self, token):
76
+ try:
77
+ decoded_payload = jwt.decode(token, JWT_DOWNLOAD_SECRET, algorithms=['HS256'])
78
+
79
+ file_name = decoded_payload['file_name']
80
+ file_list = decoded_payload['file_list']
81
+ self.ignore_folder_structure = decoded_payload['ignore_folder_structure']
82
+
83
+ self.abs_repo_path = os.path.abspath(get_repo_path())
84
+
85
+ relative_file_list = list(map(self.relative_path_mapping, file_list))
86
+
87
+ try:
88
+ file_pointer = self.get_file_pointer(file_list, relative_file_list)
89
+
90
+ while True:
91
+ _buffer = file_pointer.read(4096)
92
+ if not _buffer:
93
+ break
94
+ self.write(_buffer)
95
+ except Exception as e:
96
+ self.set_status(400)
97
+ self.write(f'Error fetching file {file_name}.\n{e}')
98
+ finally:
99
+ file_pointer.close()
100
+
101
+ self.set_header('Content-Type', 'application/force-download')
102
+ self.set_header('Content-Disposition', f'attachment; filename={file_name}')
103
+ self.flush()
104
+ except jwt.exceptions.ExpiredSignatureError:
105
+ self.set_status(400)
106
+ self.write('Download token is expired.')
107
+ except (jwt.exceptions.InvalidSignatureError, jwt.exceptions.DecodeError):
108
+ self.set_status(400)
109
+ self.write('Download token is invalid.')
110
+ except ValueError as e:
111
+ self.set_status(400)
112
+ self.write(f'Attepmt at fetching file outside of project folder: {e}')
113
+
114
+ # file pointer points to either a singular file or a temporary zip
115
+ def get_file_pointer(self, file_list, relative_file_list):
116
+ if len(file_list) == 1:
117
+ return open(file_list[0])
118
+ return self.zip_files(file_list, relative_file_list)
119
+
120
+ # creates a temporary zip and returns the (open) file pointer
121
+ def zip_files(self, file_list, relative_file_list):
122
+ zip_file = tempfile.NamedTemporaryFile(suffix='.zip', mode='w+b')
123
+ with zipfile.ZipFile(zip_file, 'w') as zipf:
124
+ for path, relative in zip(file_list, relative_file_list):
125
+ zipf.write(path, relative)
126
+ zip_file.seek(0) # set cursor to start of file to prepare for content extraction
127
+ return zip_file
128
+
129
+ def relative_path_mapping(self, path):
130
+ abs_path = os.path.abspath(path)
131
+ common_ground = os.path.commonpath([self.abs_repo_path, abs_path])
132
+
133
+ # trying to access files outside of the project folder
134
+ if common_ground != self.abs_repo_path:
135
+ raise ValueError(abs_path)
136
+
137
+ return (os.path.basename(abs_path)
138
+ if self.ignore_folder_structure
139
+ else os.path.relpath(abs_path, common_ground))
@@ -12,4 +12,4 @@ DATAFRAME_OUTPUT_SAMPLE_COUNT = 10
12
12
  # Dockerfile depends on it because it runs ./scripts/install_mage.sh and uses
13
13
  # the last line to determine the version to install.
14
14
  VERSION = \
15
- '0.9.45'
15
+ '0.9.46'