mage-ai 0.9.46__py3-none-any.whl → 0.9.47__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.
Files changed (309) hide show
  1. mage_ai/api/operations/base.py +27 -5
  2. mage_ai/api/policies/GlobalHookPolicy.py +1 -1
  3. mage_ai/api/policies/IntegrationSourcePolicy.py +62 -0
  4. mage_ai/api/policies/OauthPolicy.py +6 -6
  5. mage_ai/api/presenters/GlobalHookPresenter.py +1 -1
  6. mage_ai/api/presenters/IntegrationSourcePresenter.py +9 -2
  7. mage_ai/api/presenters/PipelinePresenter.py +2 -0
  8. mage_ai/api/presenters/PipelineRunPresenter.py +8 -3
  9. mage_ai/api/presenters/PipelineSchedulePresenter.py +22 -1
  10. mage_ai/api/resources/BlockResource.py +5 -0
  11. mage_ai/api/resources/DataProviderResource.py +2 -0
  12. mage_ai/api/resources/IntegrationSourceResource.py +149 -2
  13. mage_ai/data_integrations/sources/constants.py +5 -0
  14. mage_ai/data_integrations/utils/scheduler.py +57 -2
  15. mage_ai/data_preparation/executors/block_executor.py +9 -1
  16. mage_ai/data_preparation/models/block/__init__.py +25 -12
  17. mage_ai/data_preparation/models/block/data_integration/constants.py +3 -0
  18. mage_ai/data_preparation/models/block/data_integration/utils.py +196 -37
  19. mage_ai/data_preparation/models/block/sql/utils/shared.py +18 -1
  20. mage_ai/data_preparation/models/block/utils.py +28 -13
  21. mage_ai/data_preparation/models/global_hooks/constants.py +50 -1
  22. mage_ai/data_preparation/models/global_hooks/models.py +148 -84
  23. mage_ai/data_preparation/models/global_hooks/predicates.py +316 -0
  24. mage_ai/data_preparation/models/pipeline.py +2 -0
  25. mage_ai/data_preparation/models/pipelines/integration_pipeline.py +0 -1
  26. mage_ai/data_preparation/preferences.py +29 -18
  27. mage_ai/data_preparation/repo_manager.py +12 -2
  28. mage_ai/data_preparation/sync/__init__.py +2 -0
  29. mage_ai/data_preparation/templates/constants.py +14 -0
  30. mage_ai/data_preparation/templates/data_exporters/chroma.py +24 -0
  31. mage_ai/data_preparation/templates/data_exporters/streaming/rabbitmq.yaml +7 -0
  32. mage_ai/data_preparation/templates/data_loaders/chroma.py +27 -0
  33. mage_ai/data_preparation/templates/repo/io_config.yaml +3 -0
  34. mage_ai/io/base.py +1 -0
  35. mage_ai/io/chroma.py +153 -0
  36. mage_ai/io/config.py +8 -0
  37. mage_ai/orchestration/db/models/schedules.py +98 -34
  38. mage_ai/orchestration/pipeline_scheduler.py +58 -19
  39. mage_ai/server/constants.py +1 -1
  40. mage_ai/server/frontend_dist/404.html +2 -2
  41. mage_ai/server/frontend_dist/_next/static/N3FS4bHv0jpYeeg672uYK/_buildManifest.js +1 -0
  42. mage_ai/server/frontend_dist/_next/static/chunks/{1749-9a6276b2918fdae1.js → 1749-bf512b4dabbab7fa.js} +1 -1
  43. mage_ai/server/frontend_dist/_next/static/chunks/{1952-ac7722e8b1ab88fe.js → 1952-57858e7445d24413.js} +1 -1
  44. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/2714-1e79e9f2e998b544.js → frontend_dist/_next/static/chunks/2714-68fef54789d7eaeb.js} +1 -1
  45. mage_ai/server/frontend_dist/_next/static/chunks/2717-92cdffd87b6f6e05.js +1 -0
  46. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/3419-f8d518d024e7b5c8.js → frontend_dist/_next/static/chunks/3419-715ca383fa15a5ef.js} +1 -1
  47. mage_ai/server/frontend_dist/_next/static/chunks/3437-b4d6a037cf5781f8.js +1 -0
  48. mage_ai/server/frontend_dist/_next/static/chunks/3943-c9fb980f03df6450.js +1 -0
  49. mage_ai/server/frontend_dist/_next/static/chunks/4267-cb102e060a43d9bd.js +1 -0
  50. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/4366-93e09e5a4a7e182c.js → frontend_dist/_next/static/chunks/4366-3e52497942acbafe.js} +1 -1
  51. mage_ai/server/frontend_dist/_next/static/chunks/{4783-1a21d9be47574bba.js → 4783-422429203610c318.js} +1 -1
  52. mage_ai/server/frontend_dist/_next/static/chunks/5810-e26a0768db1cfdba.js +1 -0
  53. mage_ai/server/frontend_dist/_next/static/chunks/{5896-14e5a23b1c6a0769.js → 5896-7b8e36634d7d94eb.js} +1 -1
  54. mage_ai/server/frontend_dist/_next/static/chunks/{6285-e9b45335bfb9ccaf.js → 6285-648f9a732e100b2f.js} +1 -1
  55. mage_ai/server/frontend_dist/_next/static/chunks/6798-b904395b0c18647b.js +1 -0
  56. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/7022-070ec0144a4d029c.js → frontend_dist/_next/static/chunks/7022-e76cae3ba5ee5312.js} +1 -1
  57. mage_ai/server/frontend_dist/_next/static/chunks/722-900f786d24f91b2e.js +1 -0
  58. mage_ai/server/frontend_dist/_next/static/chunks/{7361-694e1e4fb9c97d68.js → 7361-6c5c9063b9f91700.js} +1 -1
  59. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/8146-92e7ccfed169ee9c.js → frontend_dist/_next/static/chunks/8146-27f0e31f309897a5.js} +1 -1
  60. mage_ai/server/frontend_dist/_next/static/chunks/845-9a73c65fe3fdc328.js +1 -0
  61. mage_ai/server/frontend_dist/_next/static/chunks/8487-8e1c09546dff4dbf.js +1 -0
  62. mage_ai/server/frontend_dist/_next/static/chunks/9264-cc44b07f248707b0.js +1 -0
  63. mage_ai/server/frontend_dist/_next/static/chunks/9618-4eb49cdbd1ba11d7.js +1 -0
  64. mage_ai/server/frontend_dist/_next/static/chunks/{976-18c98af60b76f1a7.js → 976-0a8c2c4d7acd957b.js} +1 -1
  65. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-78c4a077a2f279c2.js +1 -0
  66. mage_ai/server/frontend_dist/_next/static/chunks/pages/files-b37d221eb5ddc248.js +1 -0
  67. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-7adc543fc490367a.js +1 -0
  68. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks-51d366993f6dd449.js +1 -0
  69. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/{files-449a022f2f0f2d94.js → files-fe6e73463a20d67c.js} +1 -1
  70. mage_ai/server/frontend_dist/_next/static/chunks/pages/{manage-f83deb790548693b.js → manage-d8a38b5d1f50e798.js} +1 -1
  71. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-9adc2974aada27ba.js +1 -0
  72. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-51b1311dff2a974e.js +1 -0
  73. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-2333e524d34b474a.js +1 -0
  74. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-e051057d9fe94f23.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-6d1afeb4a84f50f7.js} +1 -1
  75. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1ff9bb8e22ca1e75.js +1 -0
  76. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-11363aa58d51f4e1.js +1 -0
  77. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-779c3ef0676a12ac.js +1 -0
  78. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-bbea9a088657404a.js +1 -0
  79. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-3737f2b0afc2ede3.js +1 -0
  80. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-3c8f062913c66f3e.js +1 -0
  81. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-c1f4ed17d501ccca.js +1 -0
  82. mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-8bdd858240d5dbf6.js +1 -0
  83. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-dd4fb405695f74bf.js +1 -0
  84. mage_ai/server/frontend_dist/block-layout.html +2 -2
  85. mage_ai/server/frontend_dist/compute.html +5 -5
  86. mage_ai/server/frontend_dist/files.html +5 -5
  87. mage_ai/server/frontend_dist/global-data-products/[...slug].html +5 -5
  88. mage_ai/server/frontend_dist/global-data-products.html +5 -5
  89. mage_ai/server/frontend_dist/global-hooks/[...slug].html +5 -5
  90. mage_ai/server/frontend_dist/global-hooks.html +5 -5
  91. mage_ai/server/frontend_dist/index.html +2 -2
  92. mage_ai/server/frontend_dist/manage/files.html +5 -5
  93. mage_ai/server/frontend_dist/manage/settings.html +5 -5
  94. mage_ai/server/frontend_dist/manage/users/[user].html +5 -5
  95. mage_ai/server/frontend_dist/manage/users/new.html +5 -5
  96. mage_ai/server/frontend_dist/manage/users.html +5 -5
  97. mage_ai/server/frontend_dist/manage.html +5 -5
  98. mage_ai/server/frontend_dist/oauth.html +4 -4
  99. mage_ai/server/frontend_dist/overview.html +5 -5
  100. mage_ai/server/frontend_dist/pipeline-runs.html +5 -5
  101. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +5 -5
  102. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +5 -5
  103. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +5 -5
  104. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +2 -2
  105. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +5 -5
  106. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +5 -5
  107. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +5 -5
  108. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +5 -5
  109. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +5 -5
  110. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +5 -5
  111. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +5 -5
  112. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +5 -5
  113. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +5 -5
  114. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +5 -5
  115. mage_ai/server/frontend_dist/pipelines/[pipeline].html +2 -2
  116. mage_ai/server/frontend_dist/pipelines.html +5 -5
  117. mage_ai/server/frontend_dist/settings/account/profile.html +5 -5
  118. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +5 -5
  119. mage_ai/server/frontend_dist/settings/workspace/permissions.html +5 -5
  120. mage_ai/server/frontend_dist/settings/workspace/preferences.html +5 -5
  121. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +5 -5
  122. mage_ai/server/frontend_dist/settings/workspace/roles.html +5 -5
  123. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +5 -5
  124. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +5 -5
  125. mage_ai/server/frontend_dist/settings/workspace/users.html +5 -5
  126. mage_ai/server/frontend_dist/settings.html +2 -2
  127. mage_ai/server/frontend_dist/sign-in.html +20 -20
  128. mage_ai/server/frontend_dist/templates/[...slug].html +5 -5
  129. mage_ai/server/frontend_dist/templates.html +5 -5
  130. mage_ai/server/frontend_dist/terminal.html +5 -5
  131. mage_ai/server/frontend_dist/test.html +5 -5
  132. mage_ai/server/frontend_dist/triggers.html +5 -5
  133. mage_ai/server/frontend_dist/version-control.html +5 -5
  134. mage_ai/server/frontend_dist_base_path_template/404.html +2 -2
  135. mage_ai/server/frontend_dist_base_path_template/_next/static/aoO6jYZLVlUGCCdY-wmy8/_buildManifest.js +1 -0
  136. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{1749-9a6276b2918fdae1.js → 1749-bf512b4dabbab7fa.js} +1 -1
  137. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{1952-ac7722e8b1ab88fe.js → 1952-57858e7445d24413.js} +1 -1
  138. mage_ai/server/{frontend_dist/_next/static/chunks/2714-1e79e9f2e998b544.js → frontend_dist_base_path_template/_next/static/chunks/2714-68fef54789d7eaeb.js} +1 -1
  139. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2717-92cdffd87b6f6e05.js +1 -0
  140. mage_ai/server/{frontend_dist/_next/static/chunks/3419-f8d518d024e7b5c8.js → frontend_dist_base_path_template/_next/static/chunks/3419-715ca383fa15a5ef.js} +1 -1
  141. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3437-b4d6a037cf5781f8.js +1 -0
  142. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3943-c9fb980f03df6450.js +1 -0
  143. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4267-cb102e060a43d9bd.js +1 -0
  144. mage_ai/server/{frontend_dist/_next/static/chunks/4366-93e09e5a4a7e182c.js → frontend_dist_base_path_template/_next/static/chunks/4366-3e52497942acbafe.js} +1 -1
  145. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{4783-1a21d9be47574bba.js → 4783-422429203610c318.js} +1 -1
  146. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5810-e26a0768db1cfdba.js +1 -0
  147. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{5896-14e5a23b1c6a0769.js → 5896-7b8e36634d7d94eb.js} +1 -1
  148. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{6285-e9b45335bfb9ccaf.js → 6285-648f9a732e100b2f.js} +1 -1
  149. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6798-b904395b0c18647b.js +1 -0
  150. mage_ai/server/{frontend_dist/_next/static/chunks/7022-070ec0144a4d029c.js → frontend_dist_base_path_template/_next/static/chunks/7022-e76cae3ba5ee5312.js} +1 -1
  151. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/722-900f786d24f91b2e.js +1 -0
  152. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{7361-694e1e4fb9c97d68.js → 7361-6c5c9063b9f91700.js} +1 -1
  153. mage_ai/server/{frontend_dist/_next/static/chunks/8146-92e7ccfed169ee9c.js → frontend_dist_base_path_template/_next/static/chunks/8146-27f0e31f309897a5.js} +1 -1
  154. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/845-9a73c65fe3fdc328.js +1 -0
  155. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8487-8e1c09546dff4dbf.js +1 -0
  156. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9264-cc44b07f248707b0.js +1 -0
  157. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9618-4eb49cdbd1ba11d7.js +1 -0
  158. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{976-18c98af60b76f1a7.js → 976-0a8c2c4d7acd957b.js} +1 -1
  159. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-78c4a077a2f279c2.js +1 -0
  160. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-b37d221eb5ddc248.js +1 -0
  161. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-7adc543fc490367a.js +1 -0
  162. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks-51d366993f6dd449.js +1 -0
  163. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/{files-449a022f2f0f2d94.js → files-fe6e73463a20d67c.js} +1 -1
  164. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{manage-f83deb790548693b.js → manage-d8a38b5d1f50e798.js} +1 -1
  165. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-9adc2974aada27ba.js +1 -0
  166. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-51b1311dff2a974e.js +1 -0
  167. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-2333e524d34b474a.js +1 -0
  168. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-e051057d9fe94f23.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-6d1afeb4a84f50f7.js} +1 -1
  169. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1ff9bb8e22ca1e75.js +1 -0
  170. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-11363aa58d51f4e1.js +1 -0
  171. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-779c3ef0676a12ac.js +1 -0
  172. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-bbea9a088657404a.js +1 -0
  173. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-3737f2b0afc2ede3.js +1 -0
  174. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-3c8f062913c66f3e.js +1 -0
  175. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-c1f4ed17d501ccca.js +1 -0
  176. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-8bdd858240d5dbf6.js +1 -0
  177. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-dd4fb405695f74bf.js +1 -0
  178. mage_ai/server/frontend_dist_base_path_template/block-layout.html +2 -2
  179. mage_ai/server/frontend_dist_base_path_template/compute.html +5 -5
  180. mage_ai/server/frontend_dist_base_path_template/files.html +5 -5
  181. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +5 -5
  182. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +5 -5
  183. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +5 -5
  184. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +5 -5
  185. mage_ai/server/frontend_dist_base_path_template/index.html +2 -2
  186. mage_ai/server/frontend_dist_base_path_template/manage/files.html +5 -5
  187. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +5 -5
  188. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +5 -5
  189. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +5 -5
  190. mage_ai/server/frontend_dist_base_path_template/manage/users.html +5 -5
  191. mage_ai/server/frontend_dist_base_path_template/manage.html +5 -5
  192. mage_ai/server/frontend_dist_base_path_template/oauth.html +4 -4
  193. mage_ai/server/frontend_dist_base_path_template/overview.html +5 -5
  194. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +5 -5
  195. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +5 -5
  196. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +5 -5
  197. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +5 -5
  198. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +2 -2
  199. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +5 -5
  200. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +5 -5
  201. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +5 -5
  202. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +5 -5
  203. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +5 -5
  204. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +5 -5
  205. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +5 -5
  206. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +5 -5
  207. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +5 -5
  208. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +5 -5
  209. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +2 -2
  210. mage_ai/server/frontend_dist_base_path_template/pipelines.html +5 -5
  211. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +5 -5
  212. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +5 -5
  213. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +5 -5
  214. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +5 -5
  215. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +5 -5
  216. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +5 -5
  217. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +5 -5
  218. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +5 -5
  219. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +5 -5
  220. mage_ai/server/frontend_dist_base_path_template/settings.html +2 -2
  221. mage_ai/server/frontend_dist_base_path_template/sign-in.html +23 -23
  222. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +5 -5
  223. mage_ai/server/frontend_dist_base_path_template/templates.html +5 -5
  224. mage_ai/server/frontend_dist_base_path_template/terminal.html +5 -5
  225. mage_ai/server/frontend_dist_base_path_template/test.html +5 -5
  226. mage_ai/server/frontend_dist_base_path_template/triggers.html +5 -5
  227. mage_ai/server/frontend_dist_base_path_template/version-control.html +5 -5
  228. mage_ai/server/server.py +9 -3
  229. mage_ai/services/k8s/job_manager.py +1 -0
  230. mage_ai/settings/repo.py +3 -0
  231. mage_ai/shared/files.py +47 -0
  232. mage_ai/shared/models.py +1 -0
  233. mage_ai/streaming/constants.py +1 -0
  234. mage_ai/streaming/sinks/postgres.py +2 -0
  235. mage_ai/streaming/sinks/rabbitmq.py +76 -0
  236. mage_ai/streaming/sinks/sink_factory.py +4 -0
  237. mage_ai/tests/api/operations/test_operations_with_hooks.py +136 -91
  238. mage_ai/tests/api/policies/test_oauth_policy.py +38 -0
  239. mage_ai/tests/data_preparation/models/global_hooks/test_global_hooks.py +33 -8
  240. mage_ai/tests/data_preparation/models/global_hooks/test_hook.py +82 -38
  241. mage_ai/tests/data_preparation/models/global_hooks/test_predicates.py +803 -0
  242. mage_ai/tests/data_preparation/models/global_hooks/test_utils.py +6 -1
  243. mage_ai/tests/data_preparation/models/test_block.py +26 -0
  244. mage_ai/tests/data_preparation/models/test_pipeline.py +10 -0
  245. mage_ai/tests/factory.py +40 -2
  246. mage_ai/tests/orchestration/test_pipeline_scheduler.py +82 -1
  247. mage_ai/tests/services/k8s/test_job_manager.py +16 -0
  248. mage_ai/tests/shared/mixins.py +60 -23
  249. mage_ai/tests/streaming/sinks/test_rabbitmq.py +36 -0
  250. {mage_ai-0.9.46.dist-info → mage_ai-0.9.47.dist-info}/METADATA +7 -4
  251. {mage_ai-0.9.46.dist-info → mage_ai-0.9.47.dist-info}/RECORD +257 -243
  252. {mage_ai-0.9.46.dist-info → mage_ai-0.9.47.dist-info}/WHEEL +1 -1
  253. mage_ai/server/frontend_dist/_next/static/9jB4XPuz6BzxBcG9VNao5/_buildManifest.js +0 -1
  254. mage_ai/server/frontend_dist/_next/static/chunks/3943-9e1105393a3be0de.js +0 -1
  255. mage_ai/server/frontend_dist/_next/static/chunks/4267-fd4d8049e83178de.js +0 -1
  256. mage_ai/server/frontend_dist/_next/static/chunks/5810-12eadc488265d55b.js +0 -1
  257. mage_ai/server/frontend_dist/_next/static/chunks/595-0d174b1f9fbfce4f.js +0 -1
  258. mage_ai/server/frontend_dist/_next/static/chunks/6333-bc1b433b428a9095.js +0 -1
  259. mage_ai/server/frontend_dist/_next/static/chunks/722-a1584445357a276c.js +0 -1
  260. mage_ai/server/frontend_dist/_next/static/chunks/8487-032ef9b17d20aad9.js +0 -1
  261. mage_ai/server/frontend_dist/_next/static/chunks/9264-1d4f0327d42fed91.js +0 -1
  262. mage_ai/server/frontend_dist/_next/static/chunks/9618-2c5045255ac5a6e7.js +0 -1
  263. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-ebef928183f9a3bb.js +0 -1
  264. mage_ai/server/frontend_dist/_next/static/chunks/pages/files-0f2d4be6fdca86ca.js +0 -1
  265. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-77edfa32d000e88b.js +0 -1
  266. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks-e561ae38cf5592e8.js +0 -1
  267. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-10e9a2d19541caa2.js +0 -1
  268. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-c8d3a5289ab93f88.js +0 -1
  269. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-ff7e9108502f5716.js +0 -1
  270. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-0691711636fa95c7.js +0 -1
  271. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-2914e326a5f1ffe0.js +0 -1
  272. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-3a7500e6e53084d3.js +0 -1
  273. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-c0e551d265a8d467.js +0 -1
  274. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-e47db5c3eaf683af.js +0 -1
  275. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-55ac955dfa9a5a8d.js +0 -1
  276. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-29c92a9bc54ae5cd.js +0 -1
  277. mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-572d82d6eb7a5d43.js +0 -1
  278. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-2d26d80370a2e481.js +0 -1
  279. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3943-9e1105393a3be0de.js +0 -1
  280. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4267-fd4d8049e83178de.js +0 -1
  281. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5810-12eadc488265d55b.js +0 -1
  282. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/595-0d174b1f9fbfce4f.js +0 -1
  283. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6333-bc1b433b428a9095.js +0 -1
  284. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/722-a1584445357a276c.js +0 -1
  285. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8487-032ef9b17d20aad9.js +0 -1
  286. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9264-1d4f0327d42fed91.js +0 -1
  287. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9618-2c5045255ac5a6e7.js +0 -1
  288. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-ebef928183f9a3bb.js +0 -1
  289. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-0f2d4be6fdca86ca.js +0 -1
  290. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-77edfa32d000e88b.js +0 -1
  291. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks-e561ae38cf5592e8.js +0 -1
  292. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-10e9a2d19541caa2.js +0 -1
  293. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-c8d3a5289ab93f88.js +0 -1
  294. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-ff7e9108502f5716.js +0 -1
  295. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-0691711636fa95c7.js +0 -1
  296. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-2914e326a5f1ffe0.js +0 -1
  297. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-3a7500e6e53084d3.js +0 -1
  298. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-c0e551d265a8d467.js +0 -1
  299. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-e47db5c3eaf683af.js +0 -1
  300. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-55ac955dfa9a5a8d.js +0 -1
  301. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-29c92a9bc54ae5cd.js +0 -1
  302. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-572d82d6eb7a5d43.js +0 -1
  303. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-2d26d80370a2e481.js +0 -1
  304. mage_ai/server/frontend_dist_base_path_template/_next/static/uPDjJYpJMst1q6psbRyte/_buildManifest.js +0 -1
  305. /mage_ai/server/frontend_dist/_next/static/{9jB4XPuz6BzxBcG9VNao5 → N3FS4bHv0jpYeeg672uYK}/_ssgManifest.js +0 -0
  306. /mage_ai/server/frontend_dist_base_path_template/_next/static/{uPDjJYpJMst1q6psbRyte → aoO6jYZLVlUGCCdY-wmy8}/_ssgManifest.js +0 -0
  307. {mage_ai-0.9.46.dist-info → mage_ai-0.9.47.dist-info}/LICENSE +0 -0
  308. {mage_ai-0.9.46.dist-info → mage_ai-0.9.47.dist-info}/entry_points.txt +0 -0
  309. {mage_ai-0.9.46.dist-info → mage_ai-0.9.47.dist-info}/top_level.txt +0 -0
@@ -16,6 +16,7 @@ from mage_ai.data_preparation.models.block.dynamic import (
16
16
  from mage_ai.data_preparation.models.constants import (
17
17
  DATAFRAME_ANALYSIS_MAX_COLUMNS,
18
18
  BlockType,
19
+ PipelineType,
19
20
  )
20
21
  from mage_ai.server.kernel_output_parser import DataType
21
22
  from mage_ai.shared.array import find, unique_by
@@ -200,6 +201,14 @@ def create_block_runs_from_dynamic_block(
200
201
  else:
201
202
  arr.append(upstream_block.uuid)
202
203
 
204
+ if metadata.get('upstream_blocks'):
205
+ for up_uuid in (metadata.get('upstream_blocks') or []):
206
+ up_block = block.pipeline.get_block(up_uuid)
207
+ if up_block:
208
+ arr.append(up_uuid)
209
+ else:
210
+ arr.append(f'{downstream_block.uuid}:{up_uuid}')
211
+
203
212
  block_run = create_block_run_from_dynamic_child(
204
213
  downstream_block,
205
214
  pipeline_run,
@@ -513,22 +522,28 @@ def output_variables(
513
522
  partition=execution_partition,
514
523
  )
515
524
 
525
+ if should_reduce_output(block):
526
+ all_variables = all_variable_uuids(
527
+ block,
528
+ partition=execution_partition,
529
+ )
530
+ else:
531
+ all_variables = block.get_variables_by_block(
532
+ block_uuid=block_uuid,
533
+ partition=execution_partition,
534
+ )
535
+ output_variables = [v for v in all_variables
536
+ if is_output_variable(v, include_df=include_df)]
537
+
516
538
  if block and di_settings:
517
539
  streams = get_selected_streams(di_settings.get('catalog'))
518
- output_variables = [s.get('tap_stream_id') for s in streams]
519
- else:
520
- if should_reduce_output(block):
521
- all_variables = all_variable_uuids(
522
- block,
523
- partition=execution_partition,
524
- )
540
+ tap_stream_ids = [s.get('tap_stream_id') for s in streams]
541
+ # For integration pipelines, we want to include variables with the "output" prefix
542
+ # to view sample data for the selected streams.
543
+ if pipeline.type == PipelineType.INTEGRATION:
544
+ output_variables.extend(tap_stream_ids)
525
545
  else:
526
- all_variables = block.get_variables_by_block(
527
- block_uuid=block_uuid,
528
- partition=execution_partition,
529
- )
530
- output_variables = [v for v in all_variables
531
- if is_output_variable(v, include_df=include_df)]
546
+ output_variables = tap_stream_ids
532
547
 
533
548
  output_variables.sort()
534
549
 
@@ -39,6 +39,55 @@ class HookOutputKey(str, Enum):
39
39
 
40
40
 
41
41
  VALID_KEYS_FOR_INPUT_OUTPUT_DATA_RESTRICTED = [key.value for key in HookOutputKey]
42
- VALID_KEYS_FOR_INPUT_OUTPUT_DATA_UNRESTRICTED = ['hook']
42
+ VALID_KEYS_FOR_INPUT_OUTPUT_DATA_UNRESTRICTED = [
43
+ 'hook',
44
+ 'resource_id',
45
+ 'resource_parent_id',
46
+ 'user',
47
+ ]
43
48
  VALID_KEYS_FOR_INPUT_OUTPUT_DATA_ALL = \
44
49
  VALID_KEYS_FOR_INPUT_OUTPUT_DATA_RESTRICTED + VALID_KEYS_FOR_INPUT_OUTPUT_DATA_UNRESTRICTED
50
+
51
+ INTERNAL_DEFAULT_PREDICATE_VALUE = '__INTERNAL_DEFAULT_PREDICATE_VALUE__'
52
+
53
+
54
+ class PredicateAndOrOperator(str, Enum):
55
+ AND = 'and'
56
+ OR = 'or'
57
+
58
+
59
+ class PredicateObjectType(str, Enum):
60
+ ERROR = HookOutputKey.ERROR.value
61
+ HOOK = 'hook'
62
+ META = HookOutputKey.META.value
63
+ METADATA = HookOutputKey.METADATA.value
64
+ OPERATION_RESOURCE = 'operation_resource'
65
+ PAYLOAD = HookOutputKey.PAYLOAD.value
66
+ QUERY = HookOutputKey.QUERY.value
67
+ RESOURCE = HookOutputKey.RESOURCE.value
68
+ RESOURCES = HookOutputKey.RESOURCES.value
69
+ RESOURCE_ID = 'resource_id'
70
+ RESOURCE_PARENT_ID = 'resource_parent_id'
71
+ USER = 'user'
72
+
73
+
74
+ class PredicateOperator(str, Enum):
75
+ EQUALS = 'EQUALS'
76
+ GREATER_THAN = 'GREATER_THAN'
77
+ GREATER_THAN_OR_EQUALS = 'GREATER_THAN_OR_EQUALS'
78
+ INCLUDES = 'INCLUDES'
79
+ LESS_THAN = 'LESS_THAN'
80
+ LESS_THAN_OR_EQUALS = 'LESS_THAN_OR_EQUALS'
81
+ NOT_EQUALS = 'NOT_EQUALS'
82
+ NOT_INCLUDES = 'NOT_INCLUDES'
83
+ NOT_PRESENT = 'NOT_PRESENT'
84
+ PRESENT = 'PRESENT'
85
+
86
+
87
+ class PredicateValueDataType(str, Enum):
88
+ BOOLEAN = 'BOOLEAN'
89
+ DICTIONARY = 'DICTIONARY'
90
+ FLOAT = 'FLOAT'
91
+ INTEGER = 'INTEGER'
92
+ LIST = 'LIST'
93
+ STRING = 'STRING'
@@ -1,22 +1,23 @@
1
1
  import hashlib
2
2
  import os
3
- from collections.abc import Iterable
4
3
  from dataclasses import dataclass, field, make_dataclass
5
4
  from datetime import datetime
6
5
  from enum import Enum
7
- from typing import Any, Dict, List, Tuple, Union
6
+ from typing import Dict, List, Tuple, Union
8
7
 
9
8
  import yaml
10
9
 
11
10
  from mage_ai.api.operations.constants import OperationType
12
11
  from mage_ai.api.resources.BaseResource import BaseResource
13
12
  from mage_ai.authentication.permissions.constants import EntityName
13
+ from mage_ai.data_preparation.executors.pipeline_executor import PipelineExecutor
14
14
  from mage_ai.data_preparation.models.block import Block
15
15
  from mage_ai.data_preparation.models.block.utils import fetch_input_variables
16
16
  from mage_ai.data_preparation.models.global_hooks.constants import (
17
17
  RESOURCE_TYPES,
18
18
  HookOutputKey,
19
19
  )
20
+ from mage_ai.data_preparation.models.global_hooks.predicates import HookPredicate
20
21
  from mage_ai.data_preparation.models.global_hooks.utils import extract_valid_data
21
22
  from mage_ai.data_preparation.models.pipeline import Pipeline
22
23
  from mage_ai.orchestration.db.models.schedules import PipelineRun
@@ -24,6 +25,7 @@ from mage_ai.orchestration.triggers.api import trigger_pipeline
24
25
  from mage_ai.orchestration.triggers.constants import TRIGGER_NAME_FOR_GLOBAL_HOOK
25
26
  from mage_ai.settings.repo import get_repo_path
26
27
  from mage_ai.shared.array import find, find_index, flatten
28
+ from mage_ai.shared.environments import is_debug, is_test
27
29
  from mage_ai.shared.hash import (
28
30
  dig,
29
31
  extract,
@@ -75,6 +77,7 @@ class HookStrategies(BaseDataClass):
75
77
 
76
78
  @dataclass
77
79
  class HookRunSettings(BaseDataClass):
80
+ asynchronous: bool = False
78
81
  with_trigger: bool = False
79
82
 
80
83
 
@@ -109,11 +112,6 @@ class HookOutputSettings(BaseDataClass):
109
112
  return merge_dict(ignore_keys_with_blank_values(super().to_dict(**kwargs)), data)
110
113
 
111
114
 
112
- @dataclass
113
- class HookPredicate(BaseDataClass):
114
- resource: Dict = field(default_factory=dict)
115
-
116
-
117
115
  @dataclass
118
116
  class MetadataUser(BaseDataClass):
119
117
  id: int = None
@@ -144,7 +142,7 @@ class Hook(BaseDataClass):
144
142
  output: Dict = field(default=None)
145
143
  output_settings: List[HookOutputSettings] = None
146
144
  pipeline_settings: Dict = field(default=None)
147
- predicates: List[List[HookPredicate]] = None
145
+ predicate: HookPredicate = None
148
146
  resource_type: EntityName = None
149
147
  run_settings: HookRunSettings = None
150
148
  stages: List[HookStage] = None
@@ -156,6 +154,7 @@ class Hook(BaseDataClass):
156
154
  self._pipeline = None
157
155
 
158
156
  self.serialize_attribute_class('metadata', HookMetadata)
157
+ self.serialize_attribute_class('predicate', HookPredicate)
159
158
  self.serialize_attribute_class('run_settings', HookRunSettings)
160
159
  self.serialize_attribute_class('status', HookStatus)
161
160
  self.serialize_attribute_class('strategies', HookStrategies)
@@ -165,16 +164,6 @@ class Hook(BaseDataClass):
165
164
  self.serialize_attribute_enums('conditions', HookCondition)
166
165
  self.serialize_attribute_enums('stages', HookStage)
167
166
 
168
- if self.predicates and isinstance(self.predicates, list):
169
- rows = []
170
- for predicates in self.predicates:
171
- row = []
172
- if predicates and isinstance(predicates, list):
173
- for predicate in predicates:
174
- row.append(HookPredicate.load(**predicate))
175
- rows.append(row)
176
- self.predicates = rows
177
-
178
167
  def to_dict(
179
168
  self,
180
169
  include_all: bool = False,
@@ -185,6 +174,7 @@ class Hook(BaseDataClass):
185
174
  arr = [
186
175
  'conditions',
187
176
  'metadata',
177
+ 'predicate',
188
178
  'run_settings',
189
179
  'stages',
190
180
  'strategies',
@@ -211,20 +201,6 @@ class Hook(BaseDataClass):
211
201
  if self.pipeline_settings:
212
202
  data['pipeline'] = self.pipeline_settings
213
203
 
214
- if self.predicates:
215
- rows = []
216
- for predicates in self.predicates:
217
- if predicates:
218
- row = []
219
- for predicate in predicates:
220
- row.append(predicate.to_dict())
221
-
222
- if len(row) >= 1:
223
- rows.append(row)
224
-
225
- if len(rows) >= 1:
226
- data['predicates'] = rows
227
-
228
204
  if include_snapshot_validation:
229
205
  key = 'snapshot_valid'
230
206
  if data.get('metadata'):
@@ -360,7 +336,10 @@ class Hook(BaseDataClass):
360
336
  check_status: bool = True,
361
337
  error_on_failure: bool = True,
362
338
  poll_timeout: int = None,
339
+ resource_id: Union[int, str] = None,
340
+ resource_parent_id: Union[int, str] = None,
363
341
  should_schedule: bool = False,
342
+ user: Dict = None,
364
343
  with_trigger: bool = False,
365
344
  **kwargs,
366
345
  ) -> None:
@@ -375,7 +354,10 @@ class Hook(BaseDataClass):
375
354
  payload=kwargs.get('payload'),
376
355
  query=kwargs.get('query'),
377
356
  resource=kwargs.get('resource'),
357
+ resource_id=resource_id,
358
+ resource_parent_id=resource_parent_id,
378
359
  resources=kwargs.get('resources'),
360
+ user=user,
379
361
  ))
380
362
  variables = merge_dict(
381
363
  self.pipeline_settings.get('variables') or {},
@@ -388,11 +370,14 @@ class Hook(BaseDataClass):
388
370
  )
389
371
 
390
372
  pipeline_run = None
373
+
374
+ asynchronous = self.run_settings.asynchronous if self.run_settings else False
375
+
391
376
  if with_trigger or (self.run_settings and self.run_settings.with_trigger):
392
377
  pipeline_run = trigger_pipeline(
393
378
  self.pipeline.uuid,
394
379
  variables=variables,
395
- check_status=check_status,
380
+ check_status=check_status and not asynchronous,
396
381
  error_on_failure=error_on_failure,
397
382
  poll_interval=1,
398
383
  poll_timeout=poll_timeout,
@@ -400,6 +385,10 @@ class Hook(BaseDataClass):
400
385
  verbose=True,
401
386
  _should_schedule=should_schedule,
402
387
  )
388
+ elif asynchronous:
389
+ # TODO: invoking the below method will still block the current
390
+ # operation from completing
391
+ PipelineExecutor(self.pipeline).execute(global_vars=variables, update_status=False)
403
392
  else:
404
393
  self.pipeline.execute_sync(global_vars=variables, update_status=False)
405
394
 
@@ -417,13 +406,26 @@ class Hook(BaseDataClass):
417
406
  elif HookStrategy.CONTINUE in self.strategies:
418
407
  self.status.strategy = HookStrategy.CONTINUE
419
408
 
409
+ if is_debug() or is_test():
410
+ print(f'[ERROR] Hook.run: {err}')
411
+
420
412
  def should_run(
421
413
  self,
422
414
  operation_types: List[HookOperation],
423
415
  resource_type: EntityName,
424
416
  stage: HookStage,
425
417
  conditions: List[HookCondition] = None,
418
+ error: Dict = None,
419
+ meta: Dict = None,
420
+ metadata: Dict = None,
426
421
  operation_resource: Union[BaseResource, Block, Dict, List[BaseResource], Pipeline] = None,
422
+ payload: Dict = None,
423
+ query: Dict = None,
424
+ resource: Dict = None,
425
+ resource_id: Union[int, str] = None,
426
+ resource_parent_id: Union[int, str] = None,
427
+ resources: Dict = None,
428
+ user: Dict = None,
427
429
  ) -> bool:
428
430
  if self.operation_type not in operation_types:
429
431
  return False
@@ -440,7 +442,19 @@ class Hook(BaseDataClass):
440
442
  if not self.__validate_snapshot():
441
443
  return False
442
444
 
443
- if not self.__matches_any_predicate(operation_resource):
445
+ if not self.__matches_predicate(
446
+ operation_resource,
447
+ error=error,
448
+ meta=meta,
449
+ metadata=metadata,
450
+ payload=payload,
451
+ query=query,
452
+ resource=resource,
453
+ resource_id=resource_id,
454
+ resource_parent_id=resource_parent_id,
455
+ resources=resources,
456
+ user=user,
457
+ ):
444
458
  return False
445
459
 
446
460
  return True
@@ -490,52 +504,37 @@ class Hook(BaseDataClass):
490
504
 
491
505
  return any([condition in (self.conditions or []) for condition in conditions])
492
506
 
493
- def __matches_any_predicate(
507
+ def __matches_predicate(
494
508
  self,
495
509
  operation_resource: Union[BaseResource, Block, Dict, List[BaseResource], Pipeline],
510
+ error: Dict = None,
511
+ meta: Dict = None,
512
+ metadata: Dict = None,
513
+ payload: Dict = None,
514
+ query: Dict = None,
515
+ resource: Dict = None,
516
+ resource_id: Union[int, str] = None,
517
+ resource_parent_id: Union[int, str] = None,
518
+ resources: Dict = None,
519
+ user: Dict = None,
496
520
  ) -> bool:
497
- if not operation_resource or not self.predicates:
521
+ if not operation_resource or not self.predicate:
498
522
  return True
499
523
 
500
- return any([all([self.__validate_predicate(
501
- predicate,
524
+ return self.predicate.validate(
502
525
  operation_resource,
503
- ) for predicate in predicates]) for predicates in self.predicates])
504
-
505
- def __validate_predicate(
506
- self,
507
- predicate: HookPredicate,
508
- operation_resource: Union[BaseResource, Block, Dict, List[BaseResource], Pipeline],
509
- ) -> bool:
510
- if not predicate.resource or len(predicate.resource) == 0:
511
- return True
512
-
513
- def _validate_resource(
514
- resource: Union[BaseResource, Block, Dict, Pipeline],
515
- predicate=predicate,
516
- ) -> bool:
517
- model = resource
518
- if isinstance(resource, BaseResource):
519
- model = resource.model
520
-
521
- def _equals(
522
- key: str,
523
- value: Any,
524
- model=model,
525
- ) -> bool:
526
- if isinstance(model, dict):
527
- return model.get(key) == value
528
-
529
- return hasattr(model, key) and getattr(model, key) == value
530
-
531
- check = all([_equals(key, value) for key, value in predicate.resource.items()])
532
-
533
- return check
534
-
535
- if isinstance(operation_resource, Iterable) and not isinstance(operation_resource, dict):
536
- return all([_validate_resource(res) for res in operation_resource])
537
-
538
- return _validate_resource(operation_resource)
526
+ error=error,
527
+ hook=self.to_dict(include_all=True),
528
+ meta=meta,
529
+ metadata=metadata,
530
+ payload=payload,
531
+ query=query,
532
+ resource=resource,
533
+ resource_id=resource_id,
534
+ resource_parent_id=resource_parent_id,
535
+ resources=resources,
536
+ user=user,
537
+ )
539
538
 
540
539
 
541
540
  def __build_global_hook_resource_fields() -> List[Tuple]:
@@ -838,22 +837,52 @@ class GlobalHooks(BaseDataClass):
838
837
  resource_type: EntityName,
839
838
  stage: HookStage,
840
839
  conditions: List[HookCondition] = None,
840
+ error: Dict = None,
841
+ meta: Dict = None,
842
+ metadata: Dict = None,
841
843
  operation_resource: Union[BaseResource, Block, Dict, List[BaseResource], Pipeline] = None,
844
+ payload: Dict = None,
845
+ query: Dict = None,
846
+ resource: Dict = None,
847
+ resource_id: Union[int, str] = None,
848
+ resource_parent_id: Union[int, str] = None,
849
+ resources: List[Dict] = None,
850
+ user: Dict = None,
842
851
  ) -> List[Hook]:
843
852
  def _filter(
844
- hook: Hook,
853
+ hook,
845
854
  conditions=conditions,
855
+ error=error,
856
+ meta=meta,
857
+ metadata=metadata,
846
858
  operation_resource=operation_resource,
847
859
  operation_types=operation_types,
860
+ payload=payload,
861
+ query=query,
862
+ resource=resource,
863
+ resource_id=resource_id,
864
+ resource_parent_id=resource_parent_id,
848
865
  resource_type=resource_type,
866
+ resources=resources,
849
867
  stage=stage,
868
+ user=user,
850
869
  ) -> bool:
851
870
  return hook.should_run(
871
+ operation_types,
872
+ resource_type,
873
+ stage,
852
874
  conditions=conditions,
875
+ error=error,
876
+ meta=meta,
877
+ metadata=metadata,
853
878
  operation_resource=operation_resource,
854
- operation_types=operation_types,
855
- resource_type=resource_type,
856
- stage=stage,
879
+ payload=payload,
880
+ query=query,
881
+ resource=resource,
882
+ resource_id=resource_id,
883
+ resource_parent_id=resource_parent_id,
884
+ resources=resources,
885
+ user=user,
857
886
  )
858
887
 
859
888
  return list(filter(
@@ -861,7 +890,11 @@ class GlobalHooks(BaseDataClass):
861
890
  self.hooks(),
862
891
  ))
863
892
 
864
- def run_hooks(self, hooks: List[Hook], **kwargs) -> List[Hook]:
893
+ def run_hooks(
894
+ self,
895
+ hooks: List[Hook],
896
+ **kwargs,
897
+ ) -> List[Hook]:
865
898
  hooks_by_pipeline = {}
866
899
  for hook in hooks:
867
900
  if not hook.pipeline_settings or not hook.pipeline_settings.get('uuid'):
@@ -889,21 +922,52 @@ class GlobalHooks(BaseDataClass):
889
922
  resource_type: EntityName,
890
923
  stage: HookStage,
891
924
  conditions: List[HookCondition] = None,
925
+ error: Dict = None,
926
+ meta: Dict = None,
927
+ metadata: Dict = None,
892
928
  operation_resource: Union[BaseResource, Block, Dict, List[BaseResource], Pipeline] = None,
893
- **kwargs,
929
+ payload: Dict = None,
930
+ query: Dict = None,
931
+ resource: Dict = None,
932
+ resource_id: Union[int, str] = None,
933
+ resource_parent_id: Union[int, str] = None,
934
+ resources: List[Dict] = None,
935
+ user: Dict = None,
894
936
  ) -> List[Hook]:
895
937
  hooks = self.get_hooks(
896
- operation_types=operation_types,
897
- resource_type=resource_type,
898
- stage=stage,
938
+ operation_types,
939
+ resource_type,
940
+ stage,
899
941
  conditions=conditions,
942
+ error=error,
943
+ meta=meta,
944
+ metadata=metadata,
900
945
  operation_resource=operation_resource,
946
+ payload=payload,
947
+ query=query,
948
+ resource=resource,
949
+ resource_id=resource_id,
950
+ resource_parent_id=resource_parent_id,
951
+ resources=resources,
952
+ user=user,
901
953
  )
902
954
 
903
955
  if not hooks:
904
956
  return None
905
957
 
906
- return self.run_hooks(hooks, **kwargs)
958
+ return self.run_hooks(
959
+ hooks,
960
+ error=error,
961
+ meta=meta,
962
+ metadata=metadata,
963
+ payload=payload,
964
+ query=query,
965
+ resource=resource,
966
+ resource_id=resource_id,
967
+ resource_parent_id=resource_parent_id,
968
+ resources=resources,
969
+ user=user,
970
+ )
907
971
 
908
972
  def save(self, file_path: str = None) -> None:
909
973
  if not file_path: