mage-ai 0.9.56__py3-none-any.whl → 0.9.57__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 (340) hide show
  1. mage_ai/api/policies/GlobalHookPolicy.py +3 -0
  2. mage_ai/api/policies/ProjectPolicy.py +2 -0
  3. mage_ai/api/presenters/ProjectPresenter.py +3 -0
  4. mage_ai/api/resources/GlobalHookResource.py +55 -10
  5. mage_ai/api/resources/ProjectResource.py +15 -2
  6. mage_ai/cache/dbt/cache.py +1 -1
  7. mage_ai/cache/dbt/utils.py +22 -2
  8. mage_ai/data_preparation/models/block/__init__.py +15 -5
  9. mage_ai/data_preparation/models/block/dbt/block_sql.py +12 -3
  10. mage_ai/data_preparation/models/file.py +1 -1
  11. mage_ai/data_preparation/models/global_hooks/models.py +2 -2
  12. mage_ai/data_preparation/models/project/__init__.py +28 -1
  13. mage_ai/orchestration/db/models/schedules.py +64 -102
  14. mage_ai/orchestration/db/models/schedules_project_platform.py +365 -0
  15. mage_ai/orchestration/pipeline_scheduler.py +5 -1700
  16. mage_ai/orchestration/pipeline_scheduler_original.py +1635 -0
  17. mage_ai/orchestration/pipeline_scheduler_project_platform.py +1701 -0
  18. mage_ai/server/constants.py +1 -1
  19. mage_ai/server/frontend_dist/404.html +2 -2
  20. mage_ai/server/frontend_dist/_next/static/A7VXVGKgLQCukXcjdysDz/_buildManifest.js +1 -0
  21. mage_ai/server/frontend_dist/_next/static/chunks/1557-724bfc3eabd095f7.js +1 -0
  22. mage_ai/server/frontend_dist/_next/static/chunks/161-33f26e485ddef393.js +1 -0
  23. mage_ai/server/frontend_dist/_next/static/chunks/3437-ce26fc28e114b44e.js +1 -0
  24. mage_ai/server/frontend_dist/_next/static/chunks/3540-9bb48b08f439d0a0.js +1 -0
  25. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/3745-51be3a2b7cd04895.js → frontend_dist/_next/static/chunks/3745-61b1c63bb56bb670.js} +1 -1
  26. mage_ai/server/frontend_dist/_next/static/chunks/{5729.0f2748e9e6dab951.js → 5189.dca121eccea793be.js} +1 -1
  27. mage_ai/server/frontend_dist/_next/static/chunks/5457-b373ebdf4d05d8e2.js +1 -0
  28. mage_ai/server/frontend_dist/_next/static/chunks/5533-3455832bc3f8429b.js +1 -0
  29. mage_ai/server/frontend_dist/_next/static/chunks/5729-9d8204ab91da631d.js +1 -0
  30. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/5810-e26a0768db1cfdba.js → frontend_dist/_next/static/chunks/5810-addfa3491ae6b01c.js} +1 -1
  31. mage_ai/server/frontend_dist/_next/static/chunks/8264-68db2a8334ad48f1.js +1 -0
  32. mage_ai/server/frontend_dist/_next/static/chunks/8432-0ace6fb7bdbc6864.js +1 -0
  33. mage_ai/server/frontend_dist/_next/static/chunks/8731-82571147875a2d58.js +1 -0
  34. mage_ai/server/frontend_dist/_next/static/chunks/{9264-a5e8a0274efa2b14.js → 9264-5df6e4c7b1e85c02.js} +1 -1
  35. mage_ai/server/frontend_dist/_next/static/chunks/pages/{_app-cc7f5a0c2456bc03.js → _app-4c0239ca6203e827.js} +1 -1
  36. mage_ai/server/frontend_dist/_next/static/chunks/pages/compute-822e66aa2e90cf4c.js +1 -0
  37. mage_ai/server/frontend_dist/_next/static/chunks/pages/files-373217c5de51aeef.js +1 -0
  38. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/{[...slug]-1e4838e534c8f31e.js → [...slug]-0325e76a2f3e08c1.js} +1 -1
  39. mage_ai/server/frontend_dist/_next/static/chunks/pages/{global-data-products-bb38f73540efeac4.js → global-data-products-927ebbdc29529765.js} +1 -1
  40. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-a172f5a447bd8925.js +1 -0
  41. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks-97bec2ac883e0c26.js +1 -0
  42. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/files-02d001d99eeaae3f.js +1 -0
  43. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-2e577bfd4f0db2b7.js +1 -0
  44. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/[user]-1827574a4ba95a72.js +1 -0
  45. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-a913c361bcc0d1a9.js +1 -0
  46. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users-4e6fdcbbfc931d67.js +1 -0
  47. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-1c327edcf05df9c9.js +1 -0
  48. mage_ai/server/frontend_dist/_next/static/chunks/pages/{oauth-eba7027969034415.js → oauth-bd8494f8875c5c97.js} +1 -1
  49. mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-5a98e6a531410afb.js +1 -0
  50. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipeline-runs-1442183d13edec2e.js +1 -0
  51. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-b526282c8ac49986.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-38b2241cdd10320c.js} +1 -1
  52. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-515eb343210aa1fb.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-1c646dbef65d6a69.js} +1 -1
  53. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-fe4d1321da8291cb.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-35cb916a18ac4e1f.js} +1 -1
  54. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-cd1918632dfef29d.js +1 -0
  55. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{logs-c011d465f61138ee.js → logs-67b0572c84db0940.js} +1 -1
  56. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-46c0dabd155581a0.js → block-runs-40201b626ea3a664.js} +1 -1
  57. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runtime-f2a052cb8a20fe47.js → block-runtime-d1f23308effebe03.js} +1 -1
  58. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-579899cbaedcdefc.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-9a116d88f00916ff.js} +1 -1
  59. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-7a2265b7e44bed0b.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-2d5abcd019d4bea1.js} +1 -1
  60. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-9b53da919db959bd.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-5363a7ae9afe8983.js} +1 -1
  61. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{settings-1839276725bfd757.js → settings-931a1b3112866a72.js} +1 -1
  62. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-68d779bc62185470.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-5ec5367cb877db38.js} +1 -1
  63. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-01f4528602f4ba2a.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-8366661f8e2b2959.js} +1 -1
  64. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{triggers-358523847fdbf547.js → triggers-378f8dada7d0c1dd.js} +1 -1
  65. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-627be24ef4963cfb.js +1 -0
  66. mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks/[...slug]-814bbd11e10c26dc.js +1 -0
  67. mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks-021ec25e05862f8f.js +1 -0
  68. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-00393e67ab1e6788.js → frontend_dist/_next/static/chunks/pages/settings/account/profile-2b0aa123043519b8.js} +1 -1
  69. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-05186e17c94347c1.js +1 -0
  70. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/settings-efe8bf1bf3177a7e.js +1 -0
  71. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-eaeba99f9547a20a.js → [...slug]-aa5d871de1f3f7b0.js} +1 -1
  72. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{permissions-c3140516cc28e467.js → permissions-ce45aad47049d993.js} +1 -1
  73. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-1bc694b056ff0bcb.js +1 -0
  74. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-f6ff0e219a4b9ffd.js → [...slug]-88d29d1774db67e4.js} +1 -1
  75. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{roles-22ff9d862736b2ec.js → roles-d8ca763e405cd9d1.js} +1 -1
  76. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{sync-data-614925e838d1974c.js → sync-data-42bd909eb8951040.js} +1 -1
  77. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-5b88dfb1c6d0d16c.js → [...slug]-250dfdf22bfe67e9.js} +1 -1
  78. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{users-eb904db7ac7ea57c.js → users-97c4ce119f7238b5.js} +1 -1
  79. mage_ai/server/frontend_dist/_next/static/chunks/pages/{sign-in-c734db1d5834dda2.js → sign-in-1af3ba18ff646dd4.js} +1 -1
  80. mage_ai/server/frontend_dist/_next/static/chunks/pages/templates/[...slug]-ff9d49355393daea.js +1 -0
  81. mage_ai/server/frontend_dist/_next/static/chunks/pages/{templates-5ebfe79c24d8c4b4.js → templates-299a2c8f2dd89cf3.js} +1 -1
  82. mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-fb3f398009a02879.js +1 -0
  83. mage_ai/server/frontend_dist/_next/static/chunks/pages/test-59a08e06f4ef6c3a.js +1 -0
  84. mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-551b85802515e313.js +1 -0
  85. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-1362aeda4a31dd41.js +1 -0
  86. mage_ai/server/frontend_dist/_next/static/chunks/{webpack-fea697dd168c6d0c.js → webpack-17c3a8f588f14cfd.js} +1 -1
  87. mage_ai/server/frontend_dist/block-layout.html +2 -2
  88. mage_ai/server/frontend_dist/compute.html +2 -2
  89. mage_ai/server/frontend_dist/files.html +2 -2
  90. mage_ai/server/frontend_dist/global-data-products/[...slug].html +2 -2
  91. mage_ai/server/frontend_dist/global-data-products.html +2 -2
  92. mage_ai/server/frontend_dist/global-hooks/[...slug].html +2 -2
  93. mage_ai/server/frontend_dist/global-hooks.html +2 -2
  94. mage_ai/server/frontend_dist/index.html +2 -2
  95. mage_ai/server/frontend_dist/manage/files.html +2 -2
  96. mage_ai/server/frontend_dist/manage/settings.html +2 -2
  97. mage_ai/server/frontend_dist/manage/users/[user].html +2 -2
  98. mage_ai/server/frontend_dist/manage/users/new.html +2 -2
  99. mage_ai/server/frontend_dist/manage/users.html +2 -2
  100. mage_ai/server/frontend_dist/manage.html +2 -2
  101. mage_ai/server/frontend_dist/oauth.html +3 -3
  102. mage_ai/server/frontend_dist/overview.html +2 -2
  103. mage_ai/server/frontend_dist/pipeline-runs.html +2 -2
  104. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +2 -2
  105. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +2 -2
  106. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +2 -2
  107. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +2 -2
  108. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +2 -2
  109. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +2 -2
  110. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +2 -2
  111. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +2 -2
  112. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +2 -2
  113. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +2 -2
  114. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +2 -2
  115. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +2 -2
  116. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +2 -2
  117. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +2 -2
  118. mage_ai/server/frontend_dist/pipelines/[pipeline].html +2 -2
  119. mage_ai/server/frontend_dist/pipelines.html +2 -2
  120. mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +24 -0
  121. mage_ai/server/frontend_dist/platform/global-hooks.html +24 -0
  122. mage_ai/server/frontend_dist/settings/account/profile.html +2 -2
  123. mage_ai/server/frontend_dist/settings/platform/preferences.html +24 -0
  124. mage_ai/server/frontend_dist/settings/platform/settings.html +24 -0
  125. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +2 -2
  126. mage_ai/server/frontend_dist/settings/workspace/permissions.html +2 -2
  127. mage_ai/server/frontend_dist/settings/workspace/preferences.html +2 -2
  128. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +2 -2
  129. mage_ai/server/frontend_dist/settings/workspace/roles.html +2 -2
  130. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +2 -2
  131. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +2 -2
  132. mage_ai/server/frontend_dist/settings/workspace/users.html +2 -2
  133. mage_ai/server/frontend_dist/settings.html +2 -2
  134. mage_ai/server/frontend_dist/sign-in.html +5 -5
  135. mage_ai/server/frontend_dist/templates/[...slug].html +2 -2
  136. mage_ai/server/frontend_dist/templates.html +2 -2
  137. mage_ai/server/frontend_dist/terminal.html +2 -2
  138. mage_ai/server/frontend_dist/test.html +2 -2
  139. mage_ai/server/frontend_dist/triggers.html +2 -2
  140. mage_ai/server/frontend_dist/version-control.html +2 -2
  141. mage_ai/server/frontend_dist_base_path_template/404.html +4 -4
  142. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-724bfc3eabd095f7.js +1 -0
  143. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/161-33f26e485ddef393.js +1 -0
  144. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3437-ce26fc28e114b44e.js +1 -0
  145. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3540-9bb48b08f439d0a0.js +1 -0
  146. mage_ai/server/{frontend_dist/_next/static/chunks/3745-51be3a2b7cd04895.js → frontend_dist_base_path_template/_next/static/chunks/3745-61b1c63bb56bb670.js} +1 -1
  147. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{5729.0f2748e9e6dab951.js → 5189.dca121eccea793be.js} +1 -1
  148. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-b373ebdf4d05d8e2.js +1 -0
  149. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5533-3455832bc3f8429b.js +1 -0
  150. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5729-9d8204ab91da631d.js +1 -0
  151. mage_ai/server/{frontend_dist/_next/static/chunks/5810-e26a0768db1cfdba.js → frontend_dist_base_path_template/_next/static/chunks/5810-addfa3491ae6b01c.js} +1 -1
  152. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8264-68db2a8334ad48f1.js +1 -0
  153. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8432-0ace6fb7bdbc6864.js +1 -0
  154. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8731-82571147875a2d58.js +1 -0
  155. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{9264-a5e8a0274efa2b14.js → 9264-5df6e4c7b1e85c02.js} +1 -1
  156. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{_app-cc7f5a0c2456bc03.js → _app-4c0239ca6203e827.js} +1 -1
  157. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/compute-822e66aa2e90cf4c.js +1 -0
  158. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-373217c5de51aeef.js +1 -0
  159. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/{[...slug]-1e4838e534c8f31e.js → [...slug]-0325e76a2f3e08c1.js} +1 -1
  160. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{global-data-products-bb38f73540efeac4.js → global-data-products-927ebbdc29529765.js} +1 -1
  161. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-a172f5a447bd8925.js +1 -0
  162. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks-97bec2ac883e0c26.js +1 -0
  163. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/files-02d001d99eeaae3f.js +1 -0
  164. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-2e577bfd4f0db2b7.js +1 -0
  165. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-1827574a4ba95a72.js +1 -0
  166. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-a913c361bcc0d1a9.js +1 -0
  167. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users-4e6fdcbbfc931d67.js +1 -0
  168. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-1c327edcf05df9c9.js +1 -0
  169. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{oauth-eba7027969034415.js → oauth-bd8494f8875c5c97.js} +1 -1
  170. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-5a98e6a531410afb.js +1 -0
  171. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-1442183d13edec2e.js +1 -0
  172. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-b526282c8ac49986.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-38b2241cdd10320c.js} +1 -1
  173. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-515eb343210aa1fb.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-1c646dbef65d6a69.js} +1 -1
  174. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-fe4d1321da8291cb.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-35cb916a18ac4e1f.js} +1 -1
  175. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-cd1918632dfef29d.js +1 -0
  176. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{logs-c011d465f61138ee.js → logs-67b0572c84db0940.js} +1 -1
  177. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-46c0dabd155581a0.js → block-runs-40201b626ea3a664.js} +1 -1
  178. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runtime-f2a052cb8a20fe47.js → block-runtime-d1f23308effebe03.js} +1 -1
  179. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-579899cbaedcdefc.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-9a116d88f00916ff.js} +1 -1
  180. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-7a2265b7e44bed0b.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-2d5abcd019d4bea1.js} +1 -1
  181. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-9b53da919db959bd.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-5363a7ae9afe8983.js} +1 -1
  182. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{settings-1839276725bfd757.js → settings-931a1b3112866a72.js} +1 -1
  183. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-68d779bc62185470.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-5ec5367cb877db38.js} +1 -1
  184. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-01f4528602f4ba2a.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-8366661f8e2b2959.js} +1 -1
  185. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{triggers-358523847fdbf547.js → triggers-378f8dada7d0c1dd.js} +1 -1
  186. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-627be24ef4963cfb.js +1 -0
  187. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks/[...slug]-814bbd11e10c26dc.js +1 -0
  188. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks-021ec25e05862f8f.js +1 -0
  189. mage_ai/server/{frontend_dist/_next/static/chunks/pages/settings/account/profile-00393e67ab1e6788.js → frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-2b0aa123043519b8.js} +1 -1
  190. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-05186e17c94347c1.js +1 -0
  191. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-efe8bf1bf3177a7e.js +1 -0
  192. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-eaeba99f9547a20a.js → [...slug]-aa5d871de1f3f7b0.js} +1 -1
  193. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{permissions-c3140516cc28e467.js → permissions-ce45aad47049d993.js} +1 -1
  194. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-1bc694b056ff0bcb.js +1 -0
  195. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-f6ff0e219a4b9ffd.js → [...slug]-88d29d1774db67e4.js} +1 -1
  196. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{roles-22ff9d862736b2ec.js → roles-d8ca763e405cd9d1.js} +1 -1
  197. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{sync-data-614925e838d1974c.js → sync-data-42bd909eb8951040.js} +1 -1
  198. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-5b88dfb1c6d0d16c.js → [...slug]-250dfdf22bfe67e9.js} +1 -1
  199. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{users-eb904db7ac7ea57c.js → users-97c4ce119f7238b5.js} +1 -1
  200. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{sign-in-c734db1d5834dda2.js → sign-in-1af3ba18ff646dd4.js} +1 -1
  201. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates/[...slug]-ff9d49355393daea.js +1 -0
  202. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{templates-5ebfe79c24d8c4b4.js → templates-299a2c8f2dd89cf3.js} +1 -1
  203. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-fb3f398009a02879.js +1 -0
  204. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-59a08e06f4ef6c3a.js +1 -0
  205. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-551b85802515e313.js +1 -0
  206. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-1362aeda4a31dd41.js +1 -0
  207. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-d30cb09c85b4c4f0.js → webpack-b55fe1e575d8ac9d.js} +1 -1
  208. mage_ai/server/frontend_dist_base_path_template/_next/static/wSRrM15xnvA8lOWcaque7/_buildManifest.js +1 -0
  209. mage_ai/server/frontend_dist_base_path_template/block-layout.html +2 -2
  210. mage_ai/server/frontend_dist_base_path_template/compute.html +5 -5
  211. mage_ai/server/frontend_dist_base_path_template/files.html +5 -5
  212. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +5 -5
  213. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +5 -5
  214. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +5 -5
  215. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +5 -5
  216. mage_ai/server/frontend_dist_base_path_template/index.html +2 -2
  217. mage_ai/server/frontend_dist_base_path_template/manage/files.html +5 -5
  218. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +5 -5
  219. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +5 -5
  220. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +5 -5
  221. mage_ai/server/frontend_dist_base_path_template/manage/users.html +5 -5
  222. mage_ai/server/frontend_dist_base_path_template/manage.html +5 -5
  223. mage_ai/server/frontend_dist_base_path_template/oauth.html +4 -4
  224. mage_ai/server/frontend_dist_base_path_template/overview.html +5 -5
  225. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +5 -5
  226. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +5 -5
  227. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +5 -5
  228. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +5 -5
  229. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +2 -2
  230. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +5 -5
  231. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +5 -5
  232. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +5 -5
  233. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +5 -5
  234. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +5 -5
  235. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +5 -5
  236. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +5 -5
  237. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +5 -5
  238. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +5 -5
  239. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +5 -5
  240. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +2 -2
  241. mage_ai/server/frontend_dist_base_path_template/pipelines.html +5 -5
  242. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +24 -0
  243. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +24 -0
  244. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +5 -5
  245. mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +24 -0
  246. mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +24 -0
  247. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +5 -5
  248. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +5 -5
  249. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +5 -5
  250. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +5 -5
  251. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +5 -5
  252. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +5 -5
  253. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +5 -5
  254. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +5 -5
  255. mage_ai/server/frontend_dist_base_path_template/settings.html +2 -2
  256. mage_ai/server/frontend_dist_base_path_template/sign-in.html +14 -14
  257. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +5 -5
  258. mage_ai/server/frontend_dist_base_path_template/templates.html +5 -5
  259. mage_ai/server/frontend_dist_base_path_template/terminal.html +5 -5
  260. mage_ai/server/frontend_dist_base_path_template/test.html +2 -2
  261. mage_ai/server/frontend_dist_base_path_template/triggers.html +5 -5
  262. mage_ai/server/frontend_dist_base_path_template/version-control.html +5 -5
  263. mage_ai/settings/models/configuration_option.py +15 -1
  264. mage_ai/settings/platform/__init__.py +29 -7
  265. mage_ai/streaming/sinks/rabbitmq.py +3 -1
  266. mage_ai/streaming/sources/rabbitmq.py +5 -2
  267. mage_ai/tests/api/endpoints/test_pipeline_runs.py +4 -0
  268. mage_ai/tests/data_preparation/models/test_project.py +27 -7
  269. mage_ai/tests/orchestration/db/models/test_schedules.py +25 -7
  270. mage_ai/tests/orchestration/test_pipeline_scheduler.py +6 -261
  271. mage_ai/tests/orchestration/test_pipeline_scheduler_project_platform.py +286 -0
  272. mage_ai/tests/shared/mixins.py +1 -0
  273. {mage_ai-0.9.56.dist-info → mage_ai-0.9.57.dist-info}/METADATA +1 -1
  274. {mage_ai-0.9.56.dist-info → mage_ai-0.9.57.dist-info}/RECORD +280 -258
  275. mage_ai/server/frontend_dist/_next/static/4hG0vHBR7gnry-ZWEsEF3/_buildManifest.js +0 -1
  276. mage_ai/server/frontend_dist/_next/static/chunks/1125-65883c05178efca1.js +0 -1
  277. mage_ai/server/frontend_dist/_next/static/chunks/1952-c4ba37bc172d7051.js +0 -1
  278. mage_ai/server/frontend_dist/_next/static/chunks/3437-91f6098316edaf17.js +0 -1
  279. mage_ai/server/frontend_dist/_next/static/chunks/5457-6e700aadac17ceec.js +0 -1
  280. mage_ai/server/frontend_dist/_next/static/chunks/7936-e25b6058d3f9b215.js +0 -1
  281. mage_ai/server/frontend_dist/_next/static/chunks/8264-dad1f090c4278137.js +0 -1
  282. mage_ai/server/frontend_dist/_next/static/chunks/8432-ec2b97cbf32ec5a7.js +0 -1
  283. mage_ai/server/frontend_dist/_next/static/chunks/8731-9e0ad513b0dfce83.js +0 -1
  284. mage_ai/server/frontend_dist/_next/static/chunks/9626-090ff01fd210431c.js +0 -1
  285. mage_ai/server/frontend_dist/_next/static/chunks/pages/compute-5ead3afa88d14721.js +0 -1
  286. mage_ai/server/frontend_dist/_next/static/chunks/pages/files-13a4f6d00e8a1c63.js +0 -1
  287. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-a7d74042d52c3c38.js +0 -1
  288. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks-cf7f1ba0b44ec0fb.js +0 -1
  289. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/files-259dea0c7cb30d2a.js +0 -1
  290. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-1fe2dfaa456529a6.js +0 -1
  291. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/[user]-1e8731ba2559fef4.js +0 -1
  292. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-a6307396dfa82c88.js +0 -1
  293. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users-fc5aafe5085739a9.js +0 -1
  294. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-8fad54817f356e9f.js +0 -1
  295. mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-321f47b2dba4c780.js +0 -1
  296. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipeline-runs-bf4d162b5460acc6.js +0 -1
  297. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-ed8c521227dd326e.js +0 -1
  298. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-33d9fb90871be84c.js +0 -1
  299. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-f4ff09cfff8bad46.js +0 -1
  300. mage_ai/server/frontend_dist/_next/static/chunks/pages/templates/[...slug]-04b0a55e8ad6f814.js +0 -1
  301. mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-88025dd0ed3051a6.js +0 -1
  302. mage_ai/server/frontend_dist/_next/static/chunks/pages/test-5b316b190ff4b226.js +0 -1
  303. mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-e5e49ac3b9282aaa.js +0 -1
  304. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-b52d3a07a13452ff.js +0 -1
  305. mage_ai/server/frontend_dist_base_path_template/_next/static/MKDICBWwxQowqsGfMukac/_buildManifest.js +0 -1
  306. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1125-65883c05178efca1.js +0 -1
  307. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1952-c4ba37bc172d7051.js +0 -1
  308. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3437-91f6098316edaf17.js +0 -1
  309. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-6e700aadac17ceec.js +0 -1
  310. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7936-e25b6058d3f9b215.js +0 -1
  311. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8264-dad1f090c4278137.js +0 -1
  312. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8432-ec2b97cbf32ec5a7.js +0 -1
  313. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8731-9e0ad513b0dfce83.js +0 -1
  314. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9626-090ff01fd210431c.js +0 -1
  315. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/compute-5ead3afa88d14721.js +0 -1
  316. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-13a4f6d00e8a1c63.js +0 -1
  317. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-a7d74042d52c3c38.js +0 -1
  318. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks-cf7f1ba0b44ec0fb.js +0 -1
  319. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/files-259dea0c7cb30d2a.js +0 -1
  320. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-1fe2dfaa456529a6.js +0 -1
  321. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-1e8731ba2559fef4.js +0 -1
  322. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-a6307396dfa82c88.js +0 -1
  323. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users-fc5aafe5085739a9.js +0 -1
  324. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-8fad54817f356e9f.js +0 -1
  325. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-321f47b2dba4c780.js +0 -1
  326. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-bf4d162b5460acc6.js +0 -1
  327. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-ed8c521227dd326e.js +0 -1
  328. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-33d9fb90871be84c.js +0 -1
  329. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-f4ff09cfff8bad46.js +0 -1
  330. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates/[...slug]-04b0a55e8ad6f814.js +0 -1
  331. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-88025dd0ed3051a6.js +0 -1
  332. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-5b316b190ff4b226.js +0 -1
  333. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-e5e49ac3b9282aaa.js +0 -1
  334. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-b52d3a07a13452ff.js +0 -1
  335. /mage_ai/server/frontend_dist/_next/static/{4hG0vHBR7gnry-ZWEsEF3 → A7VXVGKgLQCukXcjdysDz}/_ssgManifest.js +0 -0
  336. /mage_ai/server/frontend_dist_base_path_template/_next/static/{MKDICBWwxQowqsGfMukac → wSRrM15xnvA8lOWcaque7}/_ssgManifest.js +0 -0
  337. {mage_ai-0.9.56.dist-info → mage_ai-0.9.57.dist-info}/LICENSE +0 -0
  338. {mage_ai-0.9.56.dist-info → mage_ai-0.9.57.dist-info}/WHEEL +0 -0
  339. {mage_ai-0.9.56.dist-info → mage_ai-0.9.57.dist-info}/entry_points.txt +0 -0
  340. {mage_ai-0.9.56.dist-info → mage_ai-0.9.57.dist-info}/top_level.txt +0 -0
@@ -45,7 +45,6 @@ from mage_ai.data_preparation.models.constants import (
45
45
  PipelineType,
46
46
  )
47
47
  from mage_ai.data_preparation.models.pipeline import Pipeline
48
- from mage_ai.data_preparation.models.project import Project
49
48
  from mage_ai.data_preparation.models.triggers import (
50
49
  ScheduleInterval,
51
50
  ScheduleStatus,
@@ -57,16 +56,15 @@ from mage_ai.data_preparation.variable_manager import get_global_variables
57
56
  from mage_ai.orchestration.db import db_connection, safe_db_query
58
57
  from mage_ai.orchestration.db.errors import ValidationError
59
58
  from mage_ai.orchestration.db.models.base import Base, BaseModel, classproperty
59
+ from mage_ai.orchestration.db.models.schedules_project_platform import (
60
+ BlockRunProjectPlatformMixin,
61
+ PipelineRunProjectPlatformMixin,
62
+ PipelineScheduleProjectPlatformMixin,
63
+ )
60
64
  from mage_ai.orchestration.db.models.tags import Tag, TagAssociation
61
65
  from mage_ai.server.kernel_output_parser import DataType
62
- from mage_ai.settings.platform import (
63
- build_repo_path_for_all_projects,
64
- project_platform_activated,
65
- )
66
- from mage_ai.settings.platform.utils import (
67
- get_pipeline_from_platform,
68
- get_pipeline_from_platform_async,
69
- )
66
+ from mage_ai.settings.platform import project_platform_activated
67
+ from mage_ai.settings.repo import get_repo_path
70
68
  from mage_ai.shared.array import find
71
69
  from mage_ai.shared.constants import ENV_PROD
72
70
  from mage_ai.shared.dates import compare
@@ -81,7 +79,7 @@ pipeline_schedule_event_matcher_association_table = Table(
81
79
  )
82
80
 
83
81
 
84
- class PipelineSchedule(BaseModel):
82
+ class PipelineSchedule(PipelineScheduleProjectPlatformMixin, BaseModel):
85
83
  name = Column(String(255))
86
84
  description = Column(Text)
87
85
  pipeline_uuid = Column(String(255), index=True)
@@ -107,20 +105,12 @@ class PipelineSchedule(BaseModel):
107
105
 
108
106
  @classproperty
109
107
  def repo_query(cls):
110
- repo_paths = []
111
-
112
- queries = Project().repo_path_for_database_query('pipeline_schedules')
113
- if queries:
114
- repo_paths.extend(queries)
115
-
116
108
  if project_platform_activated():
117
- repo_paths.extend([d.get(
118
- 'full_path',
119
- ) for d in build_repo_path_for_all_projects(mage_projects_only=True).values()])
109
+ return cls.repo_query_project_platform
120
110
 
121
111
  return cls.query.filter(
122
112
  or_(
123
- PipelineSchedule.repo_path.in_(repo_paths),
113
+ PipelineSchedule.repo_path == get_repo_path(),
124
114
  PipelineSchedule.repo_path.is_(None),
125
115
  )
126
116
  )
@@ -160,38 +150,24 @@ class PipelineSchedule(BaseModel):
160
150
 
161
151
  @property
162
152
  def pipeline(self) -> 'Pipeline':
163
- return get_pipeline_from_platform(
164
- self.pipeline_uuid,
165
- check_if_exists=True,
166
- repo_path=self.repo_path,
167
- )
153
+ if project_platform_activated():
154
+ return self.pipeline_project_platform
155
+
156
+ return Pipeline.get(self.pipeline_uuid)
168
157
 
169
158
  @property
170
159
  def pipeline_in_progress_runs_count(self) -> int:
171
- return (
172
- PipelineRun.select(func.count(PipelineRun.id))
173
- .filter(
174
- PipelineRun.pipeline_schedule_id == self.id,
175
- PipelineRun.status.in_(
176
- [
177
- PipelineRun.PipelineRunStatus.INITIAL,
178
- PipelineRun.PipelineRunStatus.RUNNING,
179
- ]
180
- ),
181
- (coalesce(PipelineRun.passed_sla, False).is_(False)),
182
- )
183
- .scalar()
184
- )
160
+ if project_platform_activated():
161
+ return self.pipeline_in_progress_runs_count_project_platform
162
+
163
+ return len(PipelineRun.in_progress_runs([self.id]))
185
164
 
186
165
  @property
187
166
  def pipeline_runs_count(self) -> int:
188
- return (
189
- PipelineRun.select(func.count(PipelineRun.id))
190
- .filter(
191
- PipelineRun.pipeline_schedule_id == self.id,
192
- )
193
- .scalar()
194
- )
167
+ if project_platform_activated():
168
+ return self.pipeline_runs_count_project_platform
169
+
170
+ return len(self.fetch_pipeline_runs([self.id]))
195
171
 
196
172
  @property
197
173
  def timeout(self) -> int:
@@ -199,9 +175,8 @@ class PipelineSchedule(BaseModel):
199
175
 
200
176
  @validates('schedule_interval')
201
177
  def validate_schedule_interval(self, key, schedule_interval):
202
- if schedule_interval and schedule_interval not in [
203
- e.value for e in ScheduleInterval
204
- ]:
178
+ if schedule_interval and schedule_interval not in \
179
+ [e.value for e in ScheduleInterval]:
205
180
  if not croniter.is_valid(schedule_interval):
206
181
  raise ValueError('Cron expression is invalid.')
207
182
 
@@ -209,21 +184,12 @@ class PipelineSchedule(BaseModel):
209
184
 
210
185
  @property
211
186
  def last_pipeline_run_status(self) -> str:
212
- query_result = (
213
- PipelineRun.select(PipelineRun.id, PipelineRun.status)
214
- .filter(
215
- PipelineRun.pipeline_schedule_id == self.id,
216
- )
217
- .order_by(
218
- PipelineRun.created_at.desc(),
219
- )
220
- .first()
221
- )
187
+ if project_platform_activated():
188
+ return self.last_pipeline_run_status_project_platform
222
189
 
223
- if query_result is None:
190
+ if len(self.fetch_pipeline_runs([self.id])) == 0:
224
191
  return None
225
-
226
- return query_result.status
192
+ return sorted(self.fetch_pipeline_runs([self.id]), key=lambda x: x.created_at)[-1].status
227
193
 
228
194
  @property
229
195
  def tag_associations(self):
@@ -477,6 +443,12 @@ class PipelineSchedule(BaseModel):
477
443
  schedule interval, and previous runtimes. It returns True if the schedule should be
478
444
  executed and False otherwise.
479
445
  """
446
+ if project_platform_activated():
447
+ return self.should_schedule_project_platform(
448
+ previous_runtimes=previous_runtimes,
449
+ pipeline=pipeline,
450
+ )
451
+
480
452
  now = datetime.now(tz=pytz.UTC)
481
453
 
482
454
  if self.status != ScheduleStatus.ACTIVE:
@@ -487,27 +459,25 @@ class PipelineSchedule(BaseModel):
487
459
  compare(now, self.start_time.replace(tzinfo=pytz.UTC)) == -1:
488
460
  return False
489
461
 
490
- pipeline_use = pipeline or self.pipeline
491
- if not pipeline_use:
492
- try:
493
- Pipeline.get(self.pipeline_uuid)
494
- except Exception:
495
- print(
496
- f'[WARNING] Pipeline {self.pipeline_uuid} cannot be found '
497
- + f'for pipeline schedule ID {self.id}.',
498
- )
499
- return False
462
+ try:
463
+ Pipeline.get(self.pipeline_uuid)
464
+ except Exception:
465
+ print(
466
+ f'[WARNING] Pipeline {self.pipeline_uuid} cannot be found '
467
+ + f'for pipeline schedule ID {self.id}.',
468
+ )
469
+ return False
500
470
 
501
471
  if self.schedule_interval == ScheduleInterval.ONCE:
502
- pipeline_run_count = self.pipeline_runs_count
472
+ pipeline_run_count = len(self.fetch_pipeline_runs([self.id]))
503
473
  if pipeline_run_count == 0:
504
474
  return True
505
- executor_count = pipeline_use.executor_count
475
+ executor_count = self.pipeline.executor_count
506
476
  # Used by streaming pipeline to launch multiple executors
507
477
  if executor_count > 1 and pipeline_run_count < executor_count:
508
478
  return True
509
479
  elif self.schedule_interval == ScheduleInterval.ALWAYS_ON:
510
- if self.pipeline_runs_count == 0:
480
+ if len(self.fetch_pipeline_runs([self.id])) == 0:
511
481
  return True
512
482
  else:
513
483
  return self.last_pipeline_run_status not in [
@@ -655,7 +625,7 @@ class PipelineSchedule(BaseModel):
655
625
  return round(sum(previous_runtimes) / len(previous_runtimes), 2)
656
626
 
657
627
 
658
- class PipelineRun(BaseModel):
628
+ class PipelineRun(PipelineRunProjectPlatformMixin, BaseModel):
659
629
  class PipelineRunStatus(str, enum.Enum):
660
630
  INITIAL = 'initial'
661
631
  RUNNING = 'running'
@@ -743,10 +713,10 @@ class PipelineRun(BaseModel):
743
713
 
744
714
  @property
745
715
  def pipeline(self) -> 'Pipeline':
746
- return get_pipeline_from_platform(
747
- self.pipeline_uuid,
748
- repo_path=self.pipeline_schedule.repo_path if self.pipeline_schedule else None,
749
- )
716
+ if project_platform_activated():
717
+ return self.pipeline_project_platform
718
+
719
+ return Pipeline.get(self.pipeline_uuid)
750
720
 
751
721
  @property
752
722
  def pipeline_type(self) -> PipelineType:
@@ -800,19 +770,13 @@ class PipelineRun(BaseModel):
800
770
  return pipeline_runs
801
771
 
802
772
  async def logs_async(self):
803
- repo_path = None
804
- if self.pipeline_schedule:
805
- repo_path = self.pipeline_schedule.repo_path
806
-
807
- pipeline = await get_pipeline_from_platform_async(
808
- self.pipeline_uuid,
809
- repo_path=repo_path,
810
- )
773
+ if project_platform_activated():
774
+ return await self.logs_async_project_platform()
811
775
 
812
776
  return await LoggerManagerFactory.get_logger_manager(
813
777
  pipeline_uuid=self.pipeline_uuid,
814
778
  partition=self.execution_partition,
815
- repo_config=pipeline.repo_config,
779
+ repo_config=self.pipeline.repo_config,
816
780
  ).get_logs_async()
817
781
 
818
782
  @property
@@ -1318,6 +1282,12 @@ class PipelineRun(BaseModel):
1318
1282
  return all(b.status in statuses for b in self.block_runs)
1319
1283
 
1320
1284
  def get_variables(self, extra_variables: Dict = None, pipeline_uuid: str = None) -> Dict:
1285
+ if project_platform_activated():
1286
+ return self.get_variables_project_platform(
1287
+ extra_variables=extra_variables,
1288
+ pipeline_uuid=pipeline_uuid,
1289
+ )
1290
+
1321
1291
  if extra_variables is None:
1322
1292
  extra_variables = dict()
1323
1293
 
@@ -1326,10 +1296,7 @@ class PipelineRun(BaseModel):
1326
1296
 
1327
1297
  variables = merge_dict(
1328
1298
  merge_dict(
1329
- get_global_variables(
1330
- pipeline_uuid or self.pipeline_uuid,
1331
- pipeline=self.pipeline,
1332
- ) or dict(),
1299
+ get_global_variables(pipeline_uuid or self.pipeline_uuid) or dict(),
1333
1300
  self.pipeline_schedule.variables or dict(),
1334
1301
  ),
1335
1302
  pipeline_run_variables,
@@ -1419,7 +1386,7 @@ class PipelineRun(BaseModel):
1419
1386
  return variables
1420
1387
 
1421
1388
 
1422
- class BlockRun(BaseModel):
1389
+ class BlockRun(BlockRunProjectPlatformMixin, BaseModel):
1423
1390
  class BlockRunStatus(str, enum.Enum):
1424
1391
  INITIAL = 'initial'
1425
1392
  QUEUED = 'queued'
@@ -1450,15 +1417,10 @@ class BlockRun(BaseModel):
1450
1417
  ).get_logs()
1451
1418
 
1452
1419
  async def logs_async(self):
1453
- repo_path = None
1454
- if self.pipeline_run and self.pipeline_run.pipeline_schedule:
1455
- repo_path = self.pipeline_run.pipeline_schedule.repo_path
1456
-
1457
- pipeline = await get_pipeline_from_platform_async(
1458
- self.pipeline_run.pipeline_uuid,
1459
- repo_path=repo_path,
1460
- )
1420
+ if project_platform_activated():
1421
+ return await self.logs_async_project_platform()
1461
1422
 
1423
+ pipeline = await Pipeline.get_async(self.pipeline_run.pipeline_uuid)
1462
1424
  return await LoggerManagerFactory.get_logger_manager(
1463
1425
  pipeline_uuid=pipeline.uuid,
1464
1426
  block_uuid=clean_name(self.block_uuid),
@@ -0,0 +1,365 @@
1
+ from datetime import datetime, timedelta, timezone
2
+ from math import ceil
3
+ from statistics import stdev
4
+ from typing import Dict, List
5
+
6
+ import dateutil.parser
7
+ import pytz
8
+ from dateutil.relativedelta import relativedelta
9
+ from sqlalchemy import or_
10
+ from sqlalchemy.sql import func
11
+ from sqlalchemy.sql.functions import coalesce
12
+
13
+ from mage_ai.data_preparation.logging.logger_manager_factory import LoggerManagerFactory
14
+ from mage_ai.data_preparation.models.pipeline import Pipeline
15
+ from mage_ai.data_preparation.models.project import Project
16
+ from mage_ai.data_preparation.models.triggers import (
17
+ ScheduleInterval,
18
+ ScheduleStatus,
19
+ ScheduleType,
20
+ )
21
+ from mage_ai.data_preparation.variable_manager import get_global_variables
22
+ from mage_ai.orchestration.db import safe_db_query
23
+ from mage_ai.orchestration.db.models.base import classproperty
24
+ from mage_ai.settings.platform import build_repo_path_for_all_projects
25
+ from mage_ai.settings.platform.utils import (
26
+ get_pipeline_from_platform,
27
+ get_pipeline_from_platform_async,
28
+ )
29
+ from mage_ai.shared.array import find
30
+ from mage_ai.shared.constants import ENV_PROD
31
+ from mage_ai.shared.dates import compare
32
+ from mage_ai.shared.hash import merge_dict
33
+ from mage_ai.shared.utils import clean_name
34
+
35
+
36
+ class PipelineScheduleProjectPlatformMixin:
37
+ @classproperty
38
+ def repo_query_project_platform(cls):
39
+ repo_paths = []
40
+
41
+ queries = Project().repo_path_for_database_query('pipeline_schedules')
42
+ if queries:
43
+ repo_paths.extend(queries)
44
+
45
+ repo_paths.extend([d.get(
46
+ 'full_path',
47
+ ) for d in build_repo_path_for_all_projects(mage_projects_only=True).values()])
48
+
49
+ return cls.query.filter(
50
+ or_(
51
+ cls.repo_path.in_(repo_paths),
52
+ cls.repo_path.is_(None),
53
+ )
54
+ )
55
+
56
+ @property
57
+ def pipeline_project_platform(self) -> 'Pipeline':
58
+ return get_pipeline_from_platform(
59
+ self.pipeline_uuid,
60
+ check_if_exists=True,
61
+ repo_path=self.repo_path,
62
+ )
63
+
64
+ @property
65
+ def pipeline_in_progress_runs_count_project_platform(self) -> int:
66
+ from mage_ai.orchestration.db.models.schedules import PipelineRun
67
+
68
+ return (
69
+ PipelineRun.select(func.count(PipelineRun.id))
70
+ .filter(
71
+ PipelineRun.pipeline_schedule_id == self.id,
72
+ PipelineRun.status.in_(
73
+ [
74
+ PipelineRun.PipelineRunStatus.INITIAL,
75
+ PipelineRun.PipelineRunStatus.RUNNING,
76
+ ]
77
+ ),
78
+ (coalesce(PipelineRun.passed_sla, False).is_(False)),
79
+ )
80
+ .scalar()
81
+ )
82
+
83
+ @property
84
+ def pipeline_runs_count_project_platform(self) -> int:
85
+ from mage_ai.orchestration.db.models.schedules import PipelineRun
86
+
87
+ return (
88
+ PipelineRun.select(func.count(PipelineRun.id))
89
+ .filter(
90
+ PipelineRun.pipeline_schedule_id == self.id,
91
+ )
92
+ .scalar()
93
+ )
94
+
95
+ @property
96
+ def last_pipeline_run_status_project_platform(self) -> str:
97
+ from mage_ai.orchestration.db.models.schedules import PipelineRun
98
+
99
+ query_result = (
100
+ PipelineRun.select(PipelineRun.id, PipelineRun.status)
101
+ .filter(
102
+ PipelineRun.pipeline_schedule_id == self.id,
103
+ )
104
+ .order_by(
105
+ PipelineRun.created_at.desc(),
106
+ )
107
+ .first()
108
+ )
109
+
110
+ if query_result is None:
111
+ return None
112
+
113
+ return query_result.status
114
+
115
+ @safe_db_query
116
+ def should_schedule_project_platform(
117
+ self,
118
+ previous_runtimes: List[int] = None,
119
+ pipeline: Pipeline = None,
120
+ ) -> bool:
121
+ """
122
+ Determine whether a pipeline schedule should be executed based on its configuration and
123
+ history.
124
+
125
+ Args:
126
+ previous_runtimes (List[int], optional): A list of previous execution runtimes,
127
+ in seconds, used for decision-making when scheduling based on landing time.
128
+ Defaults to None.
129
+
130
+ Returns:
131
+ bool: True if the schedule should be executed; False otherwise.
132
+
133
+ Note:
134
+ This method evaluates whether a pipeline schedule should be executed, taking into
135
+ account various factors such as the schedule's status, start time, landing time,
136
+ schedule interval, and previous runtimes. It returns True if the schedule should be
137
+ executed and False otherwise.
138
+ """
139
+ now = datetime.now(tz=pytz.UTC)
140
+
141
+ if self.status != ScheduleStatus.ACTIVE:
142
+ return False
143
+
144
+ if not self.landing_time_enabled() and \
145
+ self.start_time is not None and \
146
+ compare(now, self.start_time.replace(tzinfo=pytz.UTC)) == -1:
147
+ return False
148
+
149
+ pipeline_use = pipeline or self.pipeline
150
+ if not pipeline_use:
151
+ try:
152
+ Pipeline.get(self.pipeline_uuid)
153
+ except Exception:
154
+ print(
155
+ f'[WARNING] Pipeline {self.pipeline_uuid} cannot be found '
156
+ + f'for pipeline schedule ID {self.id}.',
157
+ )
158
+ return False
159
+
160
+ if self.schedule_interval == ScheduleInterval.ONCE:
161
+ pipeline_run_count = self.pipeline_runs_count
162
+ if pipeline_run_count == 0:
163
+ return True
164
+ executor_count = pipeline_use.executor_count
165
+ # Used by streaming pipeline to launch multiple executors
166
+ if executor_count > 1 and pipeline_run_count < executor_count:
167
+ return True
168
+ elif self.schedule_interval == ScheduleInterval.ALWAYS_ON:
169
+ if self.pipeline_runs_count == 0:
170
+ return True
171
+ else:
172
+ from mage_ai.orchestration.db.models.schedules import PipelineRun
173
+
174
+ return self.last_pipeline_run_status not in [
175
+ PipelineRun.PipelineRunStatus.RUNNING,
176
+ PipelineRun.PipelineRunStatus.INITIAL,
177
+ ]
178
+ else:
179
+ current_execution_date = self.current_execution_date()
180
+ if current_execution_date is None:
181
+ return False
182
+
183
+ # If the execution date is before start time, don't schedule it
184
+ if self.start_time is not None and \
185
+ compare(current_execution_date, self.start_time.replace(tzinfo=pytz.UTC)) == -1:
186
+ return False
187
+
188
+ # If there is a pipeline_run with an execution_date the same as the
189
+ # current_execution_date, then don’t schedule
190
+ if not find(
191
+ lambda x: compare(
192
+ x.execution_date.replace(tzinfo=pytz.UTC),
193
+ current_execution_date,
194
+ ) == 0,
195
+ self.fetch_pipeline_runs([self.id])
196
+ ):
197
+ if self.landing_time_enabled():
198
+ if not previous_runtimes or len(previous_runtimes) == 0:
199
+ return True
200
+ else:
201
+ runtime = ceil(sum(previous_runtimes) / len(previous_runtimes))
202
+
203
+ if len(previous_runtimes) >= 2:
204
+ sd = ceil(stdev(previous_runtimes) / 2)
205
+ else:
206
+ sd = 0
207
+
208
+ # This may cause duplicate pipeline runs to be scheduled if
209
+ # there is more than 1 scheduler running.
210
+ if datetime.now(timezone.utc) >= current_execution_date - timedelta(
211
+ seconds=runtime + sd,
212
+ ):
213
+ return True
214
+ else:
215
+ return True
216
+ return False
217
+
218
+
219
+ class PipelineRunProjectPlatformMixin:
220
+ @property
221
+ def pipeline_project_platform(self) -> 'Pipeline':
222
+ return get_pipeline_from_platform(
223
+ self.pipeline_uuid,
224
+ repo_path=self.pipeline_schedule.repo_path if self.pipeline_schedule else None,
225
+ )
226
+
227
+ def get_variables_project_platform(
228
+ self,
229
+ extra_variables: Dict = None,
230
+ pipeline_uuid: str = None,
231
+ ) -> Dict:
232
+ if extra_variables is None:
233
+ extra_variables = dict()
234
+
235
+ pipeline_run_variables = self.variables or {}
236
+ event_variables = self.event_variables or {}
237
+
238
+ variables = merge_dict(
239
+ merge_dict(
240
+ get_global_variables(
241
+ pipeline_uuid or self.pipeline_uuid,
242
+ pipeline=self.pipeline,
243
+ ) or dict(),
244
+ self.pipeline_schedule.variables or dict(),
245
+ ),
246
+ pipeline_run_variables,
247
+ )
248
+
249
+ # For backwards compatibility
250
+ for k, v in event_variables.items():
251
+ if k not in variables:
252
+ variables[k] = v
253
+
254
+ if self.execution_date:
255
+ variables['ds'] = self.execution_date.strftime('%Y-%m-%d')
256
+ variables['hr'] = self.execution_date.strftime('%H')
257
+
258
+ variables['env'] = ENV_PROD
259
+ variables['event'] = merge_dict(variables.get('event', {}), event_variables)
260
+ variables['execution_date'] = self.execution_date
261
+ variables['execution_partition'] = self.execution_partition
262
+
263
+ interval_end_datetime = variables.get('interval_end_datetime')
264
+ interval_seconds = variables.get('interval_seconds')
265
+ interval_start_datetime = variables.get('interval_start_datetime')
266
+ interval_start_datetime_previous = variables.get('interval_start_datetime_previous')
267
+
268
+ if interval_end_datetime or \
269
+ interval_seconds or \
270
+ interval_start_datetime or \
271
+ interval_start_datetime_previous:
272
+ if interval_end_datetime:
273
+ try:
274
+ variables['interval_end_datetime'] = dateutil.parser.parse(
275
+ interval_end_datetime,
276
+ )
277
+ except Exception as err:
278
+ print(f'[ERROR] PipelineRun.get_variables: {err}')
279
+
280
+ if interval_start_datetime:
281
+ try:
282
+ variables['interval_start_datetime'] = dateutil.parser.parse(
283
+ interval_start_datetime,
284
+ )
285
+ except Exception as err:
286
+ print(f'[ERROR] PipelineRun.get_variables: {err}')
287
+
288
+ if interval_start_datetime_previous:
289
+ try:
290
+ variables['interval_start_datetime_previous'] = dateutil.parser.parse(
291
+ interval_start_datetime_previous,
292
+ )
293
+ except Exception as err:
294
+ print(f'[ERROR] PipelineRun.get_variables: {err}')
295
+ elif self.execution_date and ScheduleType.TIME == self.pipeline_schedule.schedule_type:
296
+ interval_end_datetime = None
297
+ interval_seconds = None
298
+ interval_start_datetime = self.execution_date
299
+ interval_start_datetime_previous = None
300
+
301
+ if ScheduleInterval.DAILY == self.pipeline_schedule.schedule_interval:
302
+ interval_seconds = 60 * 60 * 24
303
+ elif ScheduleInterval.HOURLY == self.pipeline_schedule.schedule_interval:
304
+ interval_seconds = 60 * 60 * 1
305
+ elif ScheduleInterval.MONTHLY == self.pipeline_schedule.schedule_interval:
306
+ interval_end_datetime = interval_start_datetime + relativedelta(months=1)
307
+ interval_seconds = (
308
+ interval_end_datetime.timestamp() - interval_start_datetime.timestamp()
309
+ )
310
+ elif ScheduleInterval.WEEKLY == self.pipeline_schedule.schedule_interval:
311
+ interval_seconds = 60 * 60 * 24 * 7
312
+
313
+ if interval_seconds and not interval_end_datetime:
314
+ interval_end_datetime = interval_start_datetime + timedelta(
315
+ seconds=interval_seconds,
316
+ )
317
+
318
+ if interval_seconds and interval_start_datetime:
319
+ interval_start_datetime_previous = interval_start_datetime - timedelta(
320
+ seconds=interval_seconds,
321
+ )
322
+
323
+ variables['interval_end_datetime'] = interval_end_datetime
324
+ variables['interval_seconds'] = interval_seconds
325
+ variables['interval_start_datetime'] = interval_start_datetime
326
+ variables['interval_start_datetime_previous'] = interval_start_datetime_previous
327
+
328
+ variables.update(extra_variables)
329
+
330
+ return variables
331
+
332
+ async def logs_async_project_platform(self):
333
+ repo_path = None
334
+ if self.pipeline_schedule:
335
+ repo_path = self.pipeline_schedule.repo_path
336
+
337
+ pipeline = await get_pipeline_from_platform_async(
338
+ self.pipeline_uuid,
339
+ repo_path=repo_path,
340
+ )
341
+
342
+ return await LoggerManagerFactory.get_logger_manager(
343
+ pipeline_uuid=self.pipeline_uuid,
344
+ partition=self.execution_partition,
345
+ repo_config=pipeline.repo_config,
346
+ ).get_logs_async()
347
+
348
+
349
+ class BlockRunProjectPlatformMixin:
350
+ async def logs_async_project_platform(self):
351
+ repo_path = None
352
+ if self.pipeline_run and self.pipeline_run.pipeline_schedule:
353
+ repo_path = self.pipeline_run.pipeline_schedule.repo_path
354
+
355
+ pipeline = await get_pipeline_from_platform_async(
356
+ self.pipeline_run.pipeline_uuid,
357
+ repo_path=repo_path,
358
+ )
359
+
360
+ return await LoggerManagerFactory.get_logger_manager(
361
+ pipeline_uuid=pipeline.uuid,
362
+ block_uuid=clean_name(self.block_uuid),
363
+ partition=self.pipeline_run.execution_partition,
364
+ repo_config=pipeline.repo_config,
365
+ ).get_logs_async()