mage-ai 0.9.74__py3-none-any.whl → 0.9.79__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 (420) hide show
  1. mage_ai/ai/llm_pipeline_wizard.py +6 -4
  2. mage_ai/ai/openai_client.py +7 -5
  3. mage_ai/api/policies/PipelineSchedulePolicy.py +1 -0
  4. mage_ai/api/presenters/PipelineSchedulePresenter.py +11 -2
  5. mage_ai/api/resources/GitFileResource.py +8 -0
  6. mage_ai/api/resources/PipelineScheduleResource.py +20 -14
  7. mage_ai/api/resources/PipelineTriggerResource.py +3 -1
  8. mage_ai/api/resources/SessionResource.py +2 -2
  9. mage_ai/api/resources/SyncResource.py +1 -1
  10. mage_ai/api/resources/UserResource.py +1 -1
  11. mage_ai/cli/main.py +8 -1
  12. mage_ai/data_cleaner/analysis/charts.py +1 -1
  13. mage_ai/data_cleaner/cleaning_rules/reformat_values.py +1 -1
  14. mage_ai/data_integrations/destinations/constants.py +3 -0
  15. mage_ai/data_integrations/sources/constants.py +2 -0
  16. mage_ai/data_preparation/executors/block_executor.py +8 -3
  17. mage_ai/data_preparation/executors/pipeline_executor.py +35 -19
  18. mage_ai/data_preparation/git/utils.py +2 -2
  19. mage_ai/data_preparation/logging/logger_manager.py +31 -2
  20. mage_ai/data_preparation/models/block/__init__.py +33 -27
  21. mage_ai/data_preparation/models/block/dbt/dbt_adapter.py +20 -8
  22. mage_ai/data_preparation/models/block/dynamic/constants.py +0 -1
  23. mage_ai/data_preparation/models/block/dynamic/counter.py +1 -3
  24. mage_ai/data_preparation/models/block/outputs.py +7 -1
  25. mage_ai/data_preparation/models/block/r/__init__.py +16 -5
  26. mage_ai/data_preparation/models/block/sql/__init__.py +2 -0
  27. mage_ai/data_preparation/models/block/sql/mssql.py +8 -0
  28. mage_ai/data_preparation/models/block/sql/utils/shared.py +6 -2
  29. mage_ai/data_preparation/models/constants.py +4 -1
  30. mage_ai/data_preparation/models/pipeline.py +11 -2
  31. mage_ai/data_preparation/models/project/__init__.py +3 -1
  32. mage_ai/data_preparation/models/triggers/__init__.py +1 -1
  33. mage_ai/data_preparation/storage/local_storage.py +4 -1
  34. mage_ai/data_preparation/templates/constants.py +7 -0
  35. mage_ai/data_preparation/templates/data_exporters/streaming/elasticsearch.yaml +3 -0
  36. mage_ai/data_preparation/templates/data_loaders/airtable.py +28 -0
  37. mage_ai/data_preparation/templates/data_loaders/streaming/nats.yaml +6 -3
  38. mage_ai/data_preparation/templates/repo/io_config.yaml +2 -0
  39. mage_ai/io/airtable.py +104 -0
  40. mage_ai/io/base.py +30 -1
  41. mage_ai/io/bigquery.py +36 -0
  42. mage_ai/io/config.py +6 -0
  43. mage_ai/io/mssql.py +21 -9
  44. mage_ai/io/mysql.py +6 -1
  45. mage_ai/io/oracledb.py +2 -4
  46. mage_ai/io/postgres.py +41 -19
  47. mage_ai/io/qdrant.py +1 -1
  48. mage_ai/io/redshift.py +13 -0
  49. mage_ai/io/sql.py +1 -0
  50. mage_ai/io/utils.py +18 -0
  51. mage_ai/orchestration/db/__init__.py +23 -3
  52. mage_ai/orchestration/db/migrations/versions/39d36f1dab73_create_genericjob.py +47 -0
  53. mage_ai/orchestration/db/models/oauth.py +2 -1
  54. mage_ai/orchestration/db/models/schedules.py +108 -6
  55. mage_ai/orchestration/db/models/schedules_project_platform.py +1 -1
  56. mage_ai/orchestration/db/models/secrets.py +11 -1
  57. mage_ai/orchestration/job_manager.py +19 -0
  58. mage_ai/orchestration/metrics/pipeline_run.py +1 -1
  59. mage_ai/orchestration/notification/sender.py +2 -2
  60. mage_ai/orchestration/pipeline_scheduler_original.py +150 -6
  61. mage_ai/orchestration/pipeline_scheduler_project_platform.py +4 -5
  62. mage_ai/orchestration/queue/config.py +11 -1
  63. mage_ai/orchestration/queue/process_queue.py +4 -0
  64. mage_ai/orchestration/utils/distributed_lock.py +8 -1
  65. mage_ai/orchestration/utils/resources.py +56 -2
  66. mage_ai/sample_datasets/salary_survey.csv +52 -52
  67. mage_ai/server/api/base.py +41 -0
  68. mage_ai/server/api/constants.py +1 -0
  69. mage_ai/server/api/triggers.py +9 -0
  70. mage_ai/server/constants.py +1 -1
  71. mage_ai/server/frontend_dist/404.html +3 -3
  72. mage_ai/server/frontend_dist/_next/static/TUo4RceCdMufBTBTq8CAq/_buildManifest.js +1 -0
  73. mage_ai/server/frontend_dist/_next/static/chunks/{1187-839336d276186105.js → 1187-4560c3895e1d7099.js} +1 -1
  74. mage_ai/server/frontend_dist/_next/static/chunks/{1598-0adca9dce3ba4c60.js → 1598-cbf3f5a6078fc3f5.js} +1 -1
  75. mage_ai/server/frontend_dist/_next/static/chunks/2717-638a944d24d5abde.js +1 -0
  76. mage_ai/server/frontend_dist/_next/static/chunks/3548-36f746b1824004f2.js +1 -0
  77. mage_ai/server/frontend_dist/_next/static/chunks/{3763-39a5174f6a3924db.js → 3763-aabe2703076636b0.js} +1 -1
  78. mage_ai/server/frontend_dist/_next/static/chunks/3782-3e2acb5ed45b582b.js +1 -0
  79. mage_ai/server/frontend_dist/_next/static/chunks/449-5e2253c6aba42557.js +1 -0
  80. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/5627-d5e559859dd0e1e0.js → frontend_dist/_next/static/chunks/5627-10e76bafa5a26f5f.js} +1 -1
  81. mage_ai/server/frontend_dist/_next/static/chunks/{5699-e49718dfc9eb2854.js → 5699-e99379e332bd0b41.js} +1 -1
  82. mage_ai/server/frontend_dist/_next/static/chunks/{7966-163da2621b8c987c.js → 7966-a5a7db345ce81263.js} +1 -1
  83. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-b697b35dfc4e6e26.js +2 -0
  84. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/compute-ed67fa8e81662e8b.js → frontend_dist/_next/static/chunks/pages/compute-9e2dea78024e3bb4.js} +1 -1
  85. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/files-e0ecd7ced09a63b2.js → frontend_dist/_next/static/chunks/pages/files-e08c7fe76f968f9c.js} +1 -1
  86. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/{[...slug]-c7a729477ecda50e.js → [...slug]-30c3807057a4e65b.js} +1 -1
  87. mage_ai/server/frontend_dist/_next/static/chunks/pages/{global-data-products-fd6ae6a358a60a0c.js → global-data-products-8dcb3b31af9e0e39.js} +1 -1
  88. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-8e50243797a7fe59.js → frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-85a64b64d27214b6.js} +1 -1
  89. mage_ai/server/frontend_dist/_next/static/chunks/pages/{global-hooks-d0c003446332dc0d.js → global-hooks-4ff959d51b8a9502.js} +1 -1
  90. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/{files-a69ed8e9f814490c.js → files-d08a460641d0efaa.js} +1 -1
  91. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/{overview-1aad7093c6d39257.js → overview-aae747f487e08d51.js} +1 -1
  92. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/{pipeline-runs-528d30e0d13b0cc7.js → pipeline-runs-09a842d64a6ada62.js} +1 -1
  93. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/{settings-fb9201d9cf63031d.js → settings-2e98e57d9376a458.js} +1 -1
  94. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/{[user]-000f5a980a07da39.js → [user]-7be6e41ad66089bb.js} +1 -1
  95. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-e4e613f6e817a733.js → frontend_dist/_next/static/chunks/pages/manage/users/new-4c088833063bfa07.js} +1 -1
  96. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users-5db54821a3059c69.js +1 -0
  97. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/manage-34d718b8a4066c23.js → frontend_dist/_next/static/chunks/pages/manage-868fcd8cbeb265f0.js} +1 -1
  98. mage_ai/server/frontend_dist/_next/static/chunks/pages/{oauth-3bfd1b8d7f036726.js → oauth-6ceceb62191dfe8a.js} +1 -1
  99. mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-f65416f6dbe30ad3.js +1 -0
  100. mage_ai/server/frontend_dist/_next/static/chunks/pages/{pipeline-runs-5f8c100e648efa8a.js → pipeline-runs-2d0136b51b57de93.js} +1 -1
  101. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/{[...slug]-688c652f3296bb9c.js → [...slug]-1ad5238742e25b4c.js} +1 -1
  102. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-bd11e87d026bfbf9.js +1 -0
  103. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{dashboard-1236e36d39b1637d.js → dashboard-0f4f47f721b0723f.js} +1 -1
  104. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-5ae8efe9e0530212.js +1 -0
  105. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-fe91dfb0091f6bc6.js +1 -0
  106. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-0d68d4bf6290fefb.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-cf794b2d22a80f31.js} +1 -1
  107. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-9254358d58f07714.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-a964caef91bed9e1.js} +1 -1
  108. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{monitors-821001e690caebe2.js → monitors-80bebb4401eefe25.js} +1 -1
  109. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-2eae7cb017027682.js +1 -0
  110. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-2d4b2a0800a66b33.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-776b2e5b0b6ceba8.js} +1 -1
  111. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-03d9bca3bc5e6088.js +1 -0
  112. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-707ed8ca942ca802.js +1 -0
  113. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/{[...slug]-259143ed3cf59e31.js → [...slug]-8429f17d4146e1ec.js} +1 -1
  114. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-193045d9836d8d80.js +1 -0
  115. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-d25d07db166cbb04.js +1 -0
  116. mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks/{[...slug]-5eeec927e4202b63.js → [...slug]-6834ae87bd668cb2.js} +1 -1
  117. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks-fbe9ad995d46d837.js → frontend_dist/_next/static/chunks/pages/platform/global-hooks-b3f7309a23e592b2.js} +1 -1
  118. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/{profile-fc659962d4015cb3.js → profile-f8b7374385e1f1bf.js} +1 -1
  119. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-8de68502a9afa299.js +1 -0
  120. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-a4f88c334414402b.js → frontend_dist/_next/static/chunks/pages/settings/platform/settings-50fb6a34f3913f1f.js} +1 -1
  121. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-4deb9579ef99a3c6.js → [...slug]-2e5c098c21ea32b7.js} +1 -1
  122. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{permissions-e0cda2f2bfce8d61.js → permissions-54e4b15b9585bfc4.js} +1 -1
  123. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-040f83d75d0f6537.js +1 -0
  124. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-910257d16c604ebd.js → [...slug]-95088f43034e3c95.js} +1 -1
  125. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{roles-4f7a0756806cee34.js → roles-e9149e1fcf218f42.js} +1 -1
  126. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{sync-data-208d6f955204d704.js → sync-data-75b67ae4a00818ef.js} +1 -1
  127. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-c89dc67e5a1706a8.js → [...slug]-557dda05ca6c6124.js} +1 -1
  128. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users-fa61dc6c1370e6a5.js +1 -0
  129. mage_ai/server/frontend_dist/_next/static/chunks/pages/{sign-in-054b33312d3193c3.js → sign-in-593c40985d63fcf7.js} +1 -1
  130. mage_ai/server/frontend_dist/_next/static/chunks/pages/templates/{[...slug]-b6ed6a5d818bfd20.js → [...slug]-252c4b6b818345d5.js} +1 -1
  131. mage_ai/server/frontend_dist/_next/static/chunks/pages/{templates-852357bc983af2ea.js → templates-ca528bc607753ab8.js} +1 -1
  132. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/terminal-1f9c56d671bbc67d.js → frontend_dist/_next/static/chunks/pages/terminal-287362c1defcc96b.js} +1 -1
  133. mage_ai/server/frontend_dist/_next/static/chunks/pages/test-2f83af8c9f1378fe.js +1 -0
  134. mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-d9de73fb799efed8.js +1 -0
  135. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/version-control-ae3469b992a341d6.js → frontend_dist/_next/static/chunks/pages/version-control-573f0225d7a703ed.js} +1 -1
  136. mage_ai/server/frontend_dist/block-layout.html +3 -3
  137. mage_ai/server/frontend_dist/compute.html +6 -6
  138. mage_ai/server/frontend_dist/files.html +6 -6
  139. mage_ai/server/frontend_dist/global-data-products/[...slug].html +6 -6
  140. mage_ai/server/frontend_dist/global-data-products.html +6 -6
  141. mage_ai/server/frontend_dist/global-hooks/[...slug].html +6 -6
  142. mage_ai/server/frontend_dist/global-hooks.html +6 -6
  143. mage_ai/server/frontend_dist/index.html +3 -3
  144. mage_ai/server/frontend_dist/manage/files.html +6 -6
  145. mage_ai/server/frontend_dist/manage/overview.html +6 -6
  146. mage_ai/server/frontend_dist/manage/pipeline-runs.html +6 -6
  147. mage_ai/server/frontend_dist/manage/settings.html +6 -6
  148. mage_ai/server/frontend_dist/manage/users/[user].html +6 -6
  149. mage_ai/server/frontend_dist/manage/users/new.html +6 -6
  150. mage_ai/server/frontend_dist/manage/users.html +6 -6
  151. mage_ai/server/frontend_dist/manage.html +6 -6
  152. mage_ai/server/frontend_dist/oauth.html +5 -5
  153. mage_ai/server/frontend_dist/overview.html +6 -6
  154. mage_ai/server/frontend_dist/pipeline-runs.html +6 -6
  155. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +6 -6
  156. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +6 -6
  157. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +6 -6
  158. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +3 -3
  159. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +6 -6
  160. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +6 -6
  161. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
  162. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +6 -6
  163. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +6 -6
  164. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +6 -6
  165. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +6 -6
  166. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +6 -6
  167. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +6 -6
  168. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +6 -6
  169. mage_ai/server/frontend_dist/pipelines/[pipeline].html +3 -3
  170. mage_ai/server/frontend_dist/pipelines.html +6 -6
  171. mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +6 -6
  172. mage_ai/server/frontend_dist/platform/global-hooks.html +6 -6
  173. mage_ai/server/frontend_dist/settings/account/profile.html +6 -6
  174. mage_ai/server/frontend_dist/settings/platform/preferences.html +6 -6
  175. mage_ai/server/frontend_dist/settings/platform/settings.html +6 -6
  176. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +6 -6
  177. mage_ai/server/frontend_dist/settings/workspace/permissions.html +6 -6
  178. mage_ai/server/frontend_dist/settings/workspace/preferences.html +6 -6
  179. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +6 -6
  180. mage_ai/server/frontend_dist/settings/workspace/roles.html +6 -6
  181. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +6 -6
  182. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +6 -6
  183. mage_ai/server/frontend_dist/settings/workspace/users.html +6 -6
  184. mage_ai/server/frontend_dist/settings.html +3 -3
  185. mage_ai/server/frontend_dist/sign-in.html +7 -7
  186. mage_ai/server/frontend_dist/templates/[...slug].html +6 -6
  187. mage_ai/server/frontend_dist/templates.html +6 -6
  188. mage_ai/server/frontend_dist/terminal.html +6 -6
  189. mage_ai/server/frontend_dist/test.html +3 -3
  190. mage_ai/server/frontend_dist/triggers.html +6 -6
  191. mage_ai/server/frontend_dist/v2/canvas.html +2 -2
  192. mage_ai/server/frontend_dist/v2.html +2 -2
  193. mage_ai/server/frontend_dist/version-control.html +6 -6
  194. mage_ai/server/frontend_dist_base_path_template/404.html +3 -3
  195. mage_ai/server/frontend_dist_base_path_template/_next/static/2QL-FT4lFR0a9bDZ7lNd9/_buildManifest.js +1 -0
  196. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{1187-839336d276186105.js → 1187-4560c3895e1d7099.js} +1 -1
  197. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{1598-0adca9dce3ba4c60.js → 1598-cbf3f5a6078fc3f5.js} +1 -1
  198. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2717-638a944d24d5abde.js +1 -0
  199. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3548-36f746b1824004f2.js +1 -0
  200. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{3763-39a5174f6a3924db.js → 3763-aabe2703076636b0.js} +1 -1
  201. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-3e2acb5ed45b582b.js +1 -0
  202. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/449-5e2253c6aba42557.js +1 -0
  203. mage_ai/server/{frontend_dist/_next/static/chunks/5627-d5e559859dd0e1e0.js → frontend_dist_base_path_template/_next/static/chunks/5627-10e76bafa5a26f5f.js} +1 -1
  204. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{5699-e49718dfc9eb2854.js → 5699-e99379e332bd0b41.js} +1 -1
  205. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{7966-163da2621b8c987c.js → 7966-a5a7db345ce81263.js} +1 -1
  206. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-f205accb03b9ff43.js +2 -0
  207. mage_ai/server/{frontend_dist/_next/static/chunks/pages/compute-ed67fa8e81662e8b.js → frontend_dist_base_path_template/_next/static/chunks/pages/compute-9e2dea78024e3bb4.js} +1 -1
  208. mage_ai/server/{frontend_dist/_next/static/chunks/pages/files-e0ecd7ced09a63b2.js → frontend_dist_base_path_template/_next/static/chunks/pages/files-e08c7fe76f968f9c.js} +1 -1
  209. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/{[...slug]-c7a729477ecda50e.js → [...slug]-30c3807057a4e65b.js} +1 -1
  210. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{global-data-products-fd6ae6a358a60a0c.js → global-data-products-8dcb3b31af9e0e39.js} +1 -1
  211. mage_ai/server/{frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-8e50243797a7fe59.js → frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-85a64b64d27214b6.js} +1 -1
  212. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{global-hooks-d0c003446332dc0d.js → global-hooks-4ff959d51b8a9502.js} +1 -1
  213. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/{files-a69ed8e9f814490c.js → files-d08a460641d0efaa.js} +1 -1
  214. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/{overview-1aad7093c6d39257.js → overview-aae747f487e08d51.js} +1 -1
  215. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/{pipeline-runs-528d30e0d13b0cc7.js → pipeline-runs-09a842d64a6ada62.js} +1 -1
  216. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/{settings-fb9201d9cf63031d.js → settings-2e98e57d9376a458.js} +1 -1
  217. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/{[user]-000f5a980a07da39.js → [user]-7be6e41ad66089bb.js} +1 -1
  218. mage_ai/server/{frontend_dist/_next/static/chunks/pages/manage/users/new-e4e613f6e817a733.js → frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-4c088833063bfa07.js} +1 -1
  219. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users-5db54821a3059c69.js +1 -0
  220. mage_ai/server/{frontend_dist/_next/static/chunks/pages/manage-34d718b8a4066c23.js → frontend_dist_base_path_template/_next/static/chunks/pages/manage-868fcd8cbeb265f0.js} +1 -1
  221. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{oauth-3bfd1b8d7f036726.js → oauth-6ceceb62191dfe8a.js} +1 -1
  222. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-f65416f6dbe30ad3.js +1 -0
  223. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{pipeline-runs-5f8c100e648efa8a.js → pipeline-runs-2d0136b51b57de93.js} +1 -1
  224. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/{[...slug]-688c652f3296bb9c.js → [...slug]-1ad5238742e25b4c.js} +1 -1
  225. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-bd11e87d026bfbf9.js +1 -0
  226. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{dashboard-1236e36d39b1637d.js → dashboard-0f4f47f721b0723f.js} +1 -1
  227. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-5ae8efe9e0530212.js +1 -0
  228. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-fe91dfb0091f6bc6.js +1 -0
  229. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-0d68d4bf6290fefb.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-cf794b2d22a80f31.js} +1 -1
  230. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-9254358d58f07714.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-a964caef91bed9e1.js} +1 -1
  231. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{monitors-821001e690caebe2.js → monitors-80bebb4401eefe25.js} +1 -1
  232. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-2eae7cb017027682.js +1 -0
  233. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-2d4b2a0800a66b33.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-776b2e5b0b6ceba8.js} +1 -1
  234. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-03d9bca3bc5e6088.js +1 -0
  235. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-707ed8ca942ca802.js +1 -0
  236. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/{[...slug]-259143ed3cf59e31.js → [...slug]-8429f17d4146e1ec.js} +1 -1
  237. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-193045d9836d8d80.js +1 -0
  238. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-d25d07db166cbb04.js +1 -0
  239. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks/{[...slug]-5eeec927e4202b63.js → [...slug]-6834ae87bd668cb2.js} +1 -1
  240. mage_ai/server/{frontend_dist/_next/static/chunks/pages/platform/global-hooks-fbe9ad995d46d837.js → frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks-b3f7309a23e592b2.js} +1 -1
  241. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/{profile-fc659962d4015cb3.js → profile-f8b7374385e1f1bf.js} +1 -1
  242. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-8de68502a9afa299.js +1 -0
  243. mage_ai/server/{frontend_dist/_next/static/chunks/pages/settings/platform/settings-a4f88c334414402b.js → frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-50fb6a34f3913f1f.js} +1 -1
  244. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-4deb9579ef99a3c6.js → [...slug]-2e5c098c21ea32b7.js} +1 -1
  245. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{permissions-e0cda2f2bfce8d61.js → permissions-54e4b15b9585bfc4.js} +1 -1
  246. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-040f83d75d0f6537.js +1 -0
  247. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-910257d16c604ebd.js → [...slug]-95088f43034e3c95.js} +1 -1
  248. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{roles-4f7a0756806cee34.js → roles-e9149e1fcf218f42.js} +1 -1
  249. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{sync-data-208d6f955204d704.js → sync-data-75b67ae4a00818ef.js} +1 -1
  250. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-c89dc67e5a1706a8.js → [...slug]-557dda05ca6c6124.js} +1 -1
  251. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users-fa61dc6c1370e6a5.js +1 -0
  252. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{sign-in-054b33312d3193c3.js → sign-in-593c40985d63fcf7.js} +1 -1
  253. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates/{[...slug]-b6ed6a5d818bfd20.js → [...slug]-252c4b6b818345d5.js} +1 -1
  254. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{templates-852357bc983af2ea.js → templates-ca528bc607753ab8.js} +1 -1
  255. mage_ai/server/{frontend_dist/_next/static/chunks/pages/terminal-1f9c56d671bbc67d.js → frontend_dist_base_path_template/_next/static/chunks/pages/terminal-287362c1defcc96b.js} +1 -1
  256. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-2f83af8c9f1378fe.js +1 -0
  257. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-d9de73fb799efed8.js +1 -0
  258. mage_ai/server/{frontend_dist/_next/static/chunks/pages/version-control-ae3469b992a341d6.js → frontend_dist_base_path_template/_next/static/chunks/pages/version-control-573f0225d7a703ed.js} +1 -1
  259. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-12ad70eb5c31aa92.js → webpack-5f4be622608d9267.js} +1 -1
  260. mage_ai/server/frontend_dist_base_path_template/block-layout.html +3 -3
  261. mage_ai/server/frontend_dist_base_path_template/compute.html +6 -6
  262. mage_ai/server/frontend_dist_base_path_template/files.html +6 -6
  263. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +6 -6
  264. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +6 -6
  265. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +6 -6
  266. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +6 -6
  267. mage_ai/server/frontend_dist_base_path_template/index.html +3 -3
  268. mage_ai/server/frontend_dist_base_path_template/manage/files.html +6 -6
  269. mage_ai/server/frontend_dist_base_path_template/manage/overview.html +6 -6
  270. mage_ai/server/frontend_dist_base_path_template/manage/pipeline-runs.html +6 -6
  271. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +6 -6
  272. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +6 -6
  273. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +6 -6
  274. mage_ai/server/frontend_dist_base_path_template/manage/users.html +6 -6
  275. mage_ai/server/frontend_dist_base_path_template/manage.html +6 -6
  276. mage_ai/server/frontend_dist_base_path_template/oauth.html +5 -5
  277. mage_ai/server/frontend_dist_base_path_template/overview.html +6 -6
  278. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +6 -6
  279. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +6 -6
  280. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +6 -6
  281. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +6 -6
  282. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +3 -3
  283. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +6 -6
  284. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +6 -6
  285. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
  286. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +6 -6
  287. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +6 -6
  288. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +6 -6
  289. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +6 -6
  290. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +6 -6
  291. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +6 -6
  292. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +6 -6
  293. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +3 -3
  294. mage_ai/server/frontend_dist_base_path_template/pipelines.html +6 -6
  295. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +6 -6
  296. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +6 -6
  297. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +6 -6
  298. mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +6 -6
  299. mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +6 -6
  300. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +6 -6
  301. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +6 -6
  302. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +6 -6
  303. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +6 -6
  304. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +6 -6
  305. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +6 -6
  306. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +6 -6
  307. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +6 -6
  308. mage_ai/server/frontend_dist_base_path_template/settings.html +3 -3
  309. mage_ai/server/frontend_dist_base_path_template/sign-in.html +7 -7
  310. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +6 -6
  311. mage_ai/server/frontend_dist_base_path_template/templates.html +6 -6
  312. mage_ai/server/frontend_dist_base_path_template/terminal.html +6 -6
  313. mage_ai/server/frontend_dist_base_path_template/test.html +3 -3
  314. mage_ai/server/frontend_dist_base_path_template/triggers.html +6 -6
  315. mage_ai/server/frontend_dist_base_path_template/v2/canvas.html +2 -2
  316. mage_ai/server/frontend_dist_base_path_template/v2.html +2 -2
  317. mage_ai/server/frontend_dist_base_path_template/version-control.html +6 -6
  318. mage_ai/server/scheduler_manager.py +2 -0
  319. mage_ai/server/server.py +13 -0
  320. mage_ai/server/terminal_server.py +3 -0
  321. mage_ai/server/utils/output_display.py +5 -3
  322. mage_ai/services/aws/events/events.py +2 -2
  323. mage_ai/services/gcp/cloud_run/cloud_run.py +1 -1
  324. mage_ai/services/teams/config.py +13 -2
  325. mage_ai/services/teams/teams.py +13 -11
  326. mage_ai/settings/server.py +12 -1
  327. mage_ai/shared/constants.py +3 -1
  328. mage_ai/shared/croniter.py +1398 -0
  329. mage_ai/shared/enum.py +2 -5
  330. mage_ai/shared/environments.py +27 -3
  331. mage_ai/streaming/sinks/elasticsearch.py +15 -5
  332. mage_ai/streaming/sinks/kafka.py +21 -3
  333. mage_ai/streaming/sources/kafka.py +64 -7
  334. mage_ai/streaming/sources/kafka_oauth.py +182 -0
  335. mage_ai/tests/api/endpoints/test_blocks.py +1 -101
  336. mage_ai/tests/api/endpoints/test_configuration_options.py +1 -48
  337. mage_ai/tests/api/endpoints/test_configuration_options_project_platform.py +68 -0
  338. mage_ai/tests/api/endpoints/test_custom_designs.py +1 -106
  339. mage_ai/tests/api/endpoints/test_custom_designs_project_platform.py +132 -0
  340. mage_ai/tests/api/endpoints/test_dbt_blocks.py +111 -0
  341. mage_ai/tests/api/endpoints/test_file_contents.py +0 -48
  342. mage_ai/tests/api/endpoints/test_file_contents_with_project_platform.py +66 -0
  343. mage_ai/tests/api/endpoints/test_pipelines.py +0 -134
  344. mage_ai/tests/api/endpoints/test_pipelines_with_project_platform.py +143 -0
  345. mage_ai/tests/data_preparation/executors/test_block_executor.py +3 -3
  346. mage_ai/tests/data_preparation/logging/test_logger_manager.py +24 -5
  347. mage_ai/tests/data_preparation/models/block/dynamic/test_counter.py +1 -3
  348. mage_ai/tests/data_preparation/models/block/hook/test_hook_block.py +3 -3
  349. mage_ai/tests/data_preparation/models/test_block.py +7 -0
  350. mage_ai/tests/data_preparation/models/test_pipeline.py +55 -0
  351. mage_ai/tests/data_preparation/models/test_variable.py +2 -0
  352. mage_ai/tests/data_preparation/test_repo_manager.py +0 -63
  353. mage_ai/tests/data_preparation/test_repo_manager_project_platform.py +67 -0
  354. mage_ai/tests/data_preparation/test_variable_manager.py +0 -51
  355. mage_ai/tests/data_preparation/test_variable_manager_project_platform.py +41 -0
  356. mage_ai/tests/io/create_table/test_postgresql.py +28 -0
  357. mage_ai/tests/orchestration/db/models/test_schedules.py +1 -1
  358. mage_ai/tests/orchestration/notification/test_config.py +3 -3
  359. mage_ai/tests/orchestration/notification/test_sender.py +5 -1
  360. mage_ai/tests/orchestration/utils/__init__.py +0 -0
  361. mage_ai/tests/orchestration/utils/test_resources.py +235 -0
  362. mage_ai/tests/shared/test_croniter.py +2541 -0
  363. mage_ai/tests/streaming/sinks/test_kafka.py +130 -0
  364. mage_ai/tests/streaming/sources/test_kafka.py +125 -3
  365. mage_ai/tests/streaming/sources/test_kafka_oauth.py +208 -0
  366. mage_ai/tests/streaming/sources/test_kafka_raw_value.py +105 -0
  367. mage_ai/usage_statistics/logger.py +99 -15
  368. mage_ai-0.9.79.dist-info/METADATA +358 -0
  369. {mage_ai-0.9.74.dist-info → mage_ai-0.9.79.dist-info}/RECORD +377 -359
  370. {mage_ai-0.9.74.dist-info → mage_ai-0.9.79.dist-info}/WHEEL +1 -1
  371. mage_ai/server/frontend_dist/_next/static/chunks/1557-1ad0c64c2d08e569.js +0 -1
  372. mage_ai/server/frontend_dist/_next/static/chunks/2717-d65056b6b5e124eb.js +0 -1
  373. mage_ai/server/frontend_dist/_next/static/chunks/3548-b2c5edfb710886a6.js +0 -1
  374. mage_ai/server/frontend_dist/_next/static/chunks/3782-4b3091e550f809a2.js +0 -1
  375. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-5bdff745074fb350.js +0 -2
  376. mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users-a5e9d77ed5b50205.js +0 -1
  377. mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-69af3253ad0d0d89.js +0 -1
  378. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-fe112809feb25b05.js +0 -1
  379. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-e9ca358209cdf93d.js +0 -1
  380. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-a29f1615d2e7d330.js +0 -1
  381. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-6d382ae5bad9745c.js +0 -1
  382. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-cd49372ae1702963.js +0 -1
  383. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-135be8974f7f5f2b.js +0 -1
  384. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-3af13e89adff4d6c.js +0 -1
  385. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-b578b075a8d857e3.js +0 -1
  386. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-058d283ee178c038.js +0 -1
  387. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-7b02bb70462144cb.js +0 -1
  388. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users-5212c01a9dc558da.js +0 -1
  389. mage_ai/server/frontend_dist/_next/static/chunks/pages/test-86b12cc12d4a625f.js +0 -1
  390. mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-2481c40b18d5b6d4.js +0 -1
  391. mage_ai/server/frontend_dist/_next/static/pLWT6Sqd09xYpufCVIqnz/_buildManifest.js +0 -1
  392. mage_ai/server/frontend_dist_base_path_template/_next/static/JQewSAObpbhO0wrdAM6Ng/_buildManifest.js +0 -1
  393. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-1ad0c64c2d08e569.js +0 -1
  394. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2717-d65056b6b5e124eb.js +0 -1
  395. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3548-b2c5edfb710886a6.js +0 -1
  396. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-4b3091e550f809a2.js +0 -1
  397. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-90de19bc03f1484b.js +0 -2
  398. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users-a5e9d77ed5b50205.js +0 -1
  399. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-69af3253ad0d0d89.js +0 -1
  400. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-fe112809feb25b05.js +0 -1
  401. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-e9ca358209cdf93d.js +0 -1
  402. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-a29f1615d2e7d330.js +0 -1
  403. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-6d382ae5bad9745c.js +0 -1
  404. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-cd49372ae1702963.js +0 -1
  405. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-135be8974f7f5f2b.js +0 -1
  406. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-3af13e89adff4d6c.js +0 -1
  407. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-b578b075a8d857e3.js +0 -1
  408. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-058d283ee178c038.js +0 -1
  409. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-7b02bb70462144cb.js +0 -1
  410. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users-5212c01a9dc558da.js +0 -1
  411. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-86b12cc12d4a625f.js +0 -1
  412. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-2481c40b18d5b6d4.js +0 -1
  413. mage_ai-0.9.74.dist-info/METADATA +0 -544
  414. /mage_ai/server/frontend_dist/_next/static/{pLWT6Sqd09xYpufCVIqnz → TUo4RceCdMufBTBTq8CAq}/_ssgManifest.js +0 -0
  415. /mage_ai/server/frontend_dist/_next/static/chunks/pages/{_app-5bdff745074fb350.js.LICENSE.txt → _app-b697b35dfc4e6e26.js.LICENSE.txt} +0 -0
  416. /mage_ai/server/frontend_dist_base_path_template/_next/static/{JQewSAObpbhO0wrdAM6Ng → 2QL-FT4lFR0a9bDZ7lNd9}/_ssgManifest.js +0 -0
  417. /mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{_app-90de19bc03f1484b.js.LICENSE.txt → _app-f205accb03b9ff43.js.LICENSE.txt} +0 -0
  418. {mage_ai-0.9.74.dist-info → mage_ai-0.9.79.dist-info}/entry_points.txt +0 -0
  419. {mage_ai-0.9.74.dist-info → mage_ai-0.9.79.dist-info/licenses}/LICENSE +0 -0
  420. {mage_ai-0.9.74.dist-info → mage_ai-0.9.79.dist-info}/top_level.txt +0 -0
mage_ai/shared/enum.py CHANGED
@@ -1,11 +1,8 @@
1
1
  try:
2
2
  # breaking change introduced in python 3.11
3
- from enum import Enum, IntEnum, StrEnum
3
+ from enum import Enum, IntEnum, StrEnum # noqa: F401
4
4
  except ImportError: # pragma: no cover
5
- from enum import Enum # pragma: no cover
6
-
7
- class IntEnum(int, Enum): # pragma: no cover
8
- pass # pragma: no cover
5
+ from enum import Enum, IntEnum # noqa: F401 # pragma: no cover
9
6
 
10
7
  class StrEnum(str, Enum): # pragma: no cover
11
8
  pass # pragma: no cover
@@ -1,7 +1,13 @@
1
1
  import os
2
2
  import sys
3
3
 
4
- from mage_ai.shared.constants import ENV_DEV, ENV_PROD, ENV_STAGING, ENV_TEST
4
+ from mage_ai.shared.constants import (
5
+ ENV_DEV,
6
+ ENV_PROD,
7
+ ENV_STAGING,
8
+ ENV_TEST,
9
+ ENV_TEST_MAGE,
10
+ )
5
11
 
6
12
 
7
13
  def is_deus_ex_machina():
@@ -16,10 +22,26 @@ def is_dev():
16
22
  return os.getenv('ENV', None) == 'dev' or os.getenv('ENV', None) == 'development'
17
23
 
18
24
 
19
- def is_test():
25
+ def is_test_mage():
26
+ """
27
+ The "test_mage" environment is used for running unit tests in the CI/CD pipeline.
28
+ When running unit tests, a "test.db" sqlite database is temporarily created for
29
+ storing test metadata. Refer to the mage_ai/orchestration/db/__init__.py file for
30
+ implementation details. The test_mage environment is separate from the "test"
31
+ environment so that Mage's unit tests don't affect a user's own testing metadata db.
32
+ """
20
33
  return os.getenv('ENV', None) == 'test_mage' or any('unittest' in v for v in sys.argv)
21
34
 
22
35
 
36
+ def is_test():
37
+ """
38
+ The "test" environment is the default environment for testing where users may have
39
+ their own specific tests that they want to run with their own test metadata db at a
40
+ specific location.
41
+ """
42
+ return os.getenv('ENV', None) == 'test' or is_test_mage()
43
+
44
+
23
45
  def is_production():
24
46
  return os.getenv('ENV', None) == 'production' or os.getenv('ENV', None) == 'prod'
25
47
 
@@ -29,7 +51,9 @@ def is_staging():
29
51
 
30
52
 
31
53
  def get_env():
32
- if is_test():
54
+ if is_test_mage():
55
+ return ENV_TEST_MAGE
56
+ elif is_test():
33
57
  return ENV_TEST
34
58
  elif is_production():
35
59
  return ENV_PROD
@@ -16,6 +16,8 @@ class ElasticSearchConfig(BaseConfig):
16
16
  api_key: str = None
17
17
  ca_cert: str = None
18
18
  _id: str = None
19
+ _op_type: str = None
20
+ _source: str = None
19
21
 
20
22
 
21
23
  class ElasticSearchSink(BaseSink):
@@ -51,9 +53,17 @@ class ElasticSearchSink(BaseSink):
51
53
 
52
54
  def batch_write(self, messages: List[Dict]):
53
55
  self._print(f'Batch ingest data {messages}, time={time.time()}')
54
- if self.config._id is not None:
55
- docs = [{'_index': self.config.index_name, '_id': doc[self.config._id],
56
- 'doc': doc} for doc in messages]
57
- else:
58
- docs = [{'_index': self.config.index_name, 'doc': doc} for doc in messages]
56
+ docs = []
57
+ for msg in messages:
58
+ doc = {'_index': self.config.index_name}
59
+ if self.config._id is not None:
60
+ doc['id'] = msg[self.config._id]
61
+ if self.config._op_type is not None:
62
+ doc['_op_type'] = self.config._op_type
63
+ if self.config._source is not None:
64
+ doc[self.config._source] = msg
65
+ else:
66
+ doc['_doc'] = msg
67
+ docs.append(doc)
68
+
59
69
  helpers.bulk(self.client, docs)
@@ -4,7 +4,6 @@ from dataclasses import dataclass
4
4
  from typing import Dict, List
5
5
 
6
6
  from kafka import KafkaProducer
7
-
8
7
  from mage_ai.shared.config import BaseConfig
9
8
  from mage_ai.shared.enum import StrEnum
10
9
  from mage_ai.streaming.constants import DEFAULT_BATCH_SIZE, DEFAULT_TIMEOUT_MS
@@ -12,6 +11,7 @@ from mage_ai.streaming.sinks.base import BaseSink
12
11
 
13
12
 
14
13
  class SecurityProtocol(StrEnum):
14
+ SASL_PLAINTEXT = 'SASL_PLAINTEXT'
15
15
  SASL_SSL = 'SASL_SSL'
16
16
  SSL = 'SSL'
17
17
 
@@ -21,6 +21,11 @@ class SASLConfig:
21
21
  mechanism: str = 'PLAIN'
22
22
  username: str = None
23
23
  password: str = None
24
+ # OAuth configuration for OAUTHBEARER mechanism
25
+ oauth_token_url: str = None
26
+ oauth_client_id: str = None
27
+ oauth_client_secret: str = None
28
+ oauth_scope: str = None
24
29
 
25
30
 
26
31
  @dataclass
@@ -84,10 +89,23 @@ class KafkaSink(BaseSink):
84
89
  kwargs['ssl_password'] = self.config.ssl_config.password
85
90
  kwargs['ssl_check_hostname'] = self.config.ssl_config.check_hostname
86
91
  elif self.config.security_protocol == SecurityProtocol.SASL_SSL:
92
+ if not self.config.sasl_config:
93
+ raise Exception('sasl_config is required when security_protocol is SASL_SSL')
87
94
  kwargs['security_protocol'] = SecurityProtocol.SASL_SSL
88
95
  kwargs['sasl_mechanism'] = self.config.sasl_config.mechanism
89
- kwargs['sasl_plain_username'] = self.config.sasl_config.username
90
- kwargs['sasl_plain_password'] = self.config.sasl_config.password
96
+
97
+ # Handle OAUTHBEARER mechanism
98
+ if self.config.sasl_config.mechanism == 'OAUTHBEARER':
99
+ from mage_ai.streaming.sources.kafka_oauth import (
100
+ create_oauth_token_provider,
101
+ )
102
+
103
+ token_provider = create_oauth_token_provider(self.config.sasl_config)
104
+ kwargs['sasl_oauth_token_provider'] = token_provider
105
+ else:
106
+ # Handle PLAIN, SCRAM mechanisms
107
+ kwargs['sasl_plain_username'] = self.config.sasl_config.username
108
+ kwargs['sasl_plain_password'] = self.config.sasl_config.password
91
109
 
92
110
  if self.config.ssl_config is not None and self.config.ssl_config.cafile:
93
111
  kwargs['ssl_cafile'] = self.config.ssl_config.cafile
@@ -11,7 +11,6 @@ from dataclasses import dataclass, field
11
11
  from typing import Callable, Dict, List
12
12
 
13
13
  from kafka import KafkaConsumer, TopicPartition
14
-
15
14
  from mage_ai.shared.config import BaseConfig
16
15
  from mage_ai.shared.enum import StrEnum
17
16
  from mage_ai.streaming.constants import DEFAULT_BATCH_SIZE, DEFAULT_TIMEOUT_MS
@@ -30,6 +29,11 @@ class SASLConfig:
30
29
  mechanism: str = 'PLAIN'
31
30
  username: str = None
32
31
  password: str = None
32
+ # OAuth configuration for OAUTHBEARER mechanism
33
+ oauth_token_url: str = None
34
+ oauth_client_id: str = None
35
+ oauth_client_secret: str = None
36
+ oauth_scope: str = None
33
37
 
34
38
 
35
39
  @dataclass
@@ -91,9 +95,11 @@ class KafkaSource(BaseSource):
91
95
  api_version=self.config.api_version,
92
96
  auto_offset_reset=self.config.auto_offset_reset,
93
97
  max_partition_fetch_bytes=self.config.max_partition_fetch_bytes,
94
- enable_auto_commit=True,
98
+ enable_auto_commit=False,
95
99
  )
96
100
  if self.config.security_protocol == SecurityProtocol.SSL:
101
+ if not self.config.ssl_config:
102
+ raise Exception('ssl_config is required when security_protocol is SSL')
97
103
  consumer_kwargs['security_protocol'] = SecurityProtocol.SSL
98
104
  consumer_kwargs['ssl_cafile'] = self.config.ssl_config.cafile
99
105
  consumer_kwargs['ssl_certfile'] = self.config.ssl_config.certfile
@@ -103,10 +109,23 @@ class KafkaSource(BaseSource):
103
109
  'ssl_check_hostname'
104
110
  ] = self.config.ssl_config.check_hostname
105
111
  elif self.config.security_protocol == SecurityProtocol.SASL_SSL:
112
+ if not self.config.sasl_config:
113
+ raise Exception('sasl_config is required when security_protocol is SASL_SSL')
106
114
  consumer_kwargs['security_protocol'] = SecurityProtocol.SASL_SSL
107
115
  consumer_kwargs['sasl_mechanism'] = self.config.sasl_config.mechanism
108
- consumer_kwargs['sasl_plain_username'] = self.config.sasl_config.username
109
- consumer_kwargs['sasl_plain_password'] = self.config.sasl_config.password
116
+
117
+ # Handle OAUTHBEARER mechanism
118
+ if self.config.sasl_config.mechanism == 'OAUTHBEARER':
119
+ from mage_ai.streaming.sources.kafka_oauth import (
120
+ create_oauth_token_provider,
121
+ )
122
+
123
+ token_provider = create_oauth_token_provider(self.config.sasl_config)
124
+ consumer_kwargs['sasl_oauth_token_provider'] = token_provider
125
+ else:
126
+ # Handle PLAIN, SCRAM mechanisms
127
+ consumer_kwargs['sasl_plain_username'] = self.config.sasl_config.username
128
+ consumer_kwargs['sasl_plain_password'] = self.config.sasl_config.password
110
129
 
111
130
  if self.config.ssl_config:
112
131
  consumer_kwargs[
@@ -121,10 +140,27 @@ class KafkaSource(BaseSource):
121
140
  consumer_kwargs['ssl_password'] = self.config.ssl_config.password
122
141
 
123
142
  elif self.config.security_protocol == SecurityProtocol.SASL_PLAINTEXT:
143
+ if not self.config.sasl_config:
144
+ raise Exception('sasl_config is required when security_protocol is SASL_PLAINTEXT')
124
145
  consumer_kwargs['security_protocol'] = SecurityProtocol.SASL_PLAINTEXT
125
146
  consumer_kwargs['sasl_mechanism'] = self.config.sasl_config.mechanism
126
- consumer_kwargs['sasl_plain_username'] = self.config.sasl_config.username
127
- consumer_kwargs['sasl_plain_password'] = self.config.sasl_config.password
147
+
148
+ # Handle OAUTHBEARER mechanism
149
+ if self.config.sasl_config.mechanism == 'OAUTHBEARER':
150
+ self._print(
151
+ 'WARNING: Using OAUTHBEARER with SASL_PLAINTEXT is not recommended. '
152
+ 'OAuth tokens should be used with SASL_SSL for secure transmission.'
153
+ )
154
+ from mage_ai.streaming.sources.kafka_oauth import (
155
+ create_oauth_token_provider,
156
+ )
157
+
158
+ token_provider = create_oauth_token_provider(self.config.sasl_config)
159
+ consumer_kwargs['sasl_oauth_token_provider'] = token_provider
160
+ else:
161
+ # Handle PLAIN, SCRAM mechanisms
162
+ consumer_kwargs['sasl_plain_username'] = self.config.sasl_config.username
163
+ consumer_kwargs['sasl_plain_password'] = self.config.sasl_config.password
128
164
 
129
165
  if self.config.topic:
130
166
  topics = [self.config.topic]
@@ -171,12 +207,32 @@ class KafkaSource(BaseSource):
171
207
  self.registry_client, self.config.topic
172
208
  )
173
209
 
210
+ def _decode_key(self, key):
211
+ """Decode message key based on serialization method.
212
+
213
+ When using RAW_VALUE, keep key as raw bytes.
214
+ Otherwise, attempt UTF-8 decode with fallback to raw bytes on error.
215
+ """
216
+ if not key:
217
+ return None
218
+
219
+ # Keep as raw bytes for RAW_VALUE serialization
220
+ if (self.config.serde_config and
221
+ self.config.serde_config.serialization_method == SerializationMethod.RAW_VALUE):
222
+ return key
223
+
224
+ # Attempt UTF-8 decode, fallback to raw bytes on error
225
+ try:
226
+ return key.decode('utf-8')
227
+ except UnicodeDecodeError:
228
+ return key
229
+
174
230
  def _convert_message(self, message):
175
231
  if self.config.include_metadata:
176
232
  message = {
177
233
  'data': self.__deserialize_message(message.value),
178
234
  'metadata': {
179
- 'key': message.key.decode() if message.key else None,
235
+ 'key': self._decode_key(message.key),
180
236
  'partition': message.partition,
181
237
  'offset': message.offset,
182
238
  'time': int(message.timestamp),
@@ -270,6 +326,7 @@ class KafkaSource(BaseSource):
270
326
  message_values.append(message)
271
327
  if len(message_values) > 0:
272
328
  handler(message_values)
329
+ self.consumer.commit()
273
330
 
274
331
  def test_connection(self):
275
332
  self.consumer._client.check_version(timeout=5)
@@ -0,0 +1,182 @@
1
+ """
2
+ OAuth token provider for Kafka SASL OAUTHBEARER authentication.
3
+
4
+ This module provides a token provider implementation for OAuth 2.0 client credentials flow,
5
+ which can be used with kafka-python's OAUTHBEARER SASL mechanism.
6
+ """
7
+ import logging
8
+ import time
9
+ from typing import Dict, Optional
10
+
11
+ import requests
12
+
13
+ try:
14
+ from kafka.sasl.oauth import AbstractTokenProvider
15
+ except ImportError:
16
+ # Fallback for when kafka is not installed
17
+ class AbstractTokenProvider:
18
+ """Fallback token provider interface when kafka-python is not installed."""
19
+
20
+ def __init__(self, **config):
21
+ pass
22
+
23
+ def token(self):
24
+ raise NotImplementedError("token() must be implemented by subclass")
25
+
26
+ def extensions(self):
27
+ return {}
28
+
29
+
30
+ logger = logging.getLogger(__name__)
31
+
32
+
33
+ def create_oauth_token_provider(sasl_config):
34
+ """
35
+ Create an OAuth token provider for OAUTHBEARER mechanism.
36
+
37
+ Args:
38
+ sasl_config: SASL configuration containing OAuth parameters
39
+
40
+ Returns:
41
+ ClientCredentialsTokenProvider instance
42
+
43
+ Raises:
44
+ Exception: If required OAuth parameters are missing
45
+ """
46
+ if not sasl_config.oauth_token_url:
47
+ raise Exception(
48
+ 'oauth_token_url is required in sasl_config for OAUTHBEARER mechanism'
49
+ )
50
+ if not sasl_config.oauth_client_id:
51
+ raise Exception(
52
+ 'oauth_client_id is required in sasl_config for OAUTHBEARER mechanism'
53
+ )
54
+ if not sasl_config.oauth_client_secret:
55
+ raise Exception(
56
+ 'oauth_client_secret is required in sasl_config for OAUTHBEARER mechanism'
57
+ )
58
+
59
+ return ClientCredentialsTokenProvider(
60
+ token_url=sasl_config.oauth_token_url,
61
+ client_id=sasl_config.oauth_client_id,
62
+ client_secret=sasl_config.oauth_client_secret,
63
+ scope=sasl_config.oauth_scope,
64
+ )
65
+
66
+
67
+ class ClientCredentialsTokenProvider(AbstractTokenProvider):
68
+ """
69
+ Token provider that implements OAuth 2.0 client credentials flow.
70
+
71
+ This provider fetches access tokens from an OAuth 2.0 authorization server
72
+ (e.g., Keycloak) using client credentials and manages token refresh.
73
+
74
+ Args:
75
+ token_url: The OAuth 2.0 token endpoint URL
76
+ client_id: The OAuth 2.0 client ID
77
+ client_secret: The OAuth 2.0 client secret
78
+ scope: Optional scope for the token request
79
+ token_expiry_buffer: Buffer time in seconds before token expiry to refresh (default: 60)
80
+ """
81
+
82
+ def __init__(
83
+ self,
84
+ token_url: str,
85
+ client_id: str,
86
+ client_secret: str,
87
+ scope: Optional[str] = None,
88
+ token_expiry_buffer: int = 60,
89
+ **config
90
+ ):
91
+ super().__init__(**config)
92
+ self.token_url = token_url
93
+ self.client_id = client_id
94
+ self.client_secret = client_secret
95
+ self.scope = scope
96
+ self.token_expiry_buffer = token_expiry_buffer
97
+
98
+ self._access_token: Optional[str] = None
99
+ self._token_expiry_time: Optional[float] = None
100
+
101
+ def token(self) -> str:
102
+ """
103
+ Returns a valid access token, fetching a new one if necessary.
104
+
105
+ Returns:
106
+ str: The access token to use for authentication
107
+ """
108
+ if self._is_token_expired():
109
+ self._fetch_token()
110
+
111
+ return self._access_token
112
+
113
+ def _is_token_expired(self) -> bool:
114
+ """
115
+ Check if the current token is expired or will expire soon.
116
+
117
+ Returns:
118
+ bool: True if token is expired or will expire within buffer time
119
+ """
120
+ if self._access_token is None or self._token_expiry_time is None:
121
+ return True
122
+
123
+ current_time = time.time()
124
+ return current_time >= (self._token_expiry_time - self.token_expiry_buffer)
125
+
126
+ def _fetch_token(self):
127
+ """
128
+ Fetch a new access token from the OAuth 2.0 authorization server.
129
+
130
+ Raises:
131
+ RuntimeError: If token fetch fails
132
+ """
133
+ try:
134
+ data = {
135
+ 'grant_type': 'client_credentials',
136
+ 'client_id': self.client_id,
137
+ 'client_secret': self.client_secret,
138
+ }
139
+
140
+ if self.scope:
141
+ data['scope'] = self.scope
142
+
143
+ logger.debug(f"Fetching OAuth token from {self.token_url}")
144
+
145
+ response = requests.post(
146
+ self.token_url,
147
+ data=data,
148
+ headers={'Content-Type': 'application/x-www-form-urlencoded'},
149
+ timeout=10,
150
+ )
151
+
152
+ response.raise_for_status()
153
+ token_data = response.json()
154
+
155
+ # Validate that access_token is present in the response
156
+ if 'access_token' not in token_data:
157
+ logger.error("OAuth server response missing 'access_token' field")
158
+ raise RuntimeError(
159
+ "Invalid token response format: missing 'access_token' field"
160
+ )
161
+
162
+ self._access_token = token_data['access_token']
163
+ expires_in = token_data.get('expires_in', 3600)
164
+ self._token_expiry_time = time.time() + expires_in
165
+
166
+ logger.debug(f"Successfully fetched OAuth token, expires in {expires_in} seconds")
167
+
168
+ except requests.exceptions.RequestException as e:
169
+ logger.error(f"Failed to fetch OAuth token: {e}")
170
+ raise RuntimeError(f"Failed to fetch OAuth token: {e}")
171
+ except (KeyError, ValueError) as e:
172
+ logger.error(f"Invalid token response format: {e}")
173
+ raise RuntimeError(f"Invalid token response format: {e}")
174
+
175
+ def extensions(self) -> Dict[str, str]:
176
+ """
177
+ Return optional extensions to be sent with the SASL/OAUTHBEARER request.
178
+
179
+ Returns:
180
+ dict: Empty dict as no extensions are needed for basic client credentials flow
181
+ """
182
+ return {}
@@ -1,6 +1,4 @@
1
- import os
2
-
3
- from mage_ai.data_preparation.models.constants import BlockLanguage, BlockType
1
+ from mage_ai.data_preparation.models.constants import BlockType
4
2
  from mage_ai.data_preparation.models.pipeline import Pipeline
5
3
  from mage_ai.settings.repo import get_repo_path
6
4
  from mage_ai.tests.api.endpoints.mixins import (
@@ -11,7 +9,6 @@ from mage_ai.tests.api.endpoints.mixins import (
11
9
  build_list_endpoint_tests,
12
10
  build_update_endpoint_tests,
13
11
  )
14
- from mage_ai.tests.shared.mixins import DBTMixin
15
12
 
16
13
 
17
14
  def get_pipeline(self):
@@ -109,100 +106,3 @@ build_delete_endpoint_tests(
109
106
  resource='block',
110
107
  resource_parent='pipelines',
111
108
  )
112
-
113
-
114
- class DBTBlockAPIEndpointTest(BaseAPIEndpointTest, DBTMixin):
115
- pass
116
-
117
-
118
- def __assert_after_create(self):
119
- pipeline = get_pipeline(self)
120
- blocks = pipeline.blocks_by_uuid.values()
121
- blocks_dbt = list(filter(
122
- lambda x: x.type == BlockType.DBT and x.language == BlockLanguage.SQL,
123
- blocks,
124
- ))
125
-
126
- self.assertEqual(len(blocks), 5)
127
- self.assertEqual(len(blocks_dbt), 1)
128
-
129
- block = blocks_dbt[0]
130
- self.assertEqual({
131
- 'dbt_project_name': 'dbt/test_project',
132
- 'file_path': 'dbt/test_project/models/example/my_first_dbt_model.sql',
133
- 'file_source': {
134
- 'path': 'dbt/test_project/models/example/my_first_dbt_model.sql',
135
- 'project_path': 'dbt/test_project',
136
- },
137
- }, block.configuration)
138
-
139
- return True
140
-
141
-
142
- def __assert_after_create_yaml(self):
143
- pipeline = get_pipeline(self)
144
- blocks = pipeline.blocks_by_uuid.values()
145
- blocks_dbt = list(filter(
146
- lambda x: x.type == BlockType.DBT and x.language == BlockLanguage.YAML,
147
- blocks,
148
- ))
149
-
150
- self.assertEqual(len(blocks), 5)
151
- self.assertEqual(len(blocks_dbt), 1)
152
-
153
- block = blocks_dbt[0]
154
- self.assertEqual({
155
- 'dbt_project_name': 'dbt/test_project',
156
- 'file_source': {
157
- 'path': 'dbts/dbt_yaml.yaml',
158
- 'project_path': 'dbt/test_project',
159
- },
160
- }, block.configuration)
161
-
162
- return True
163
-
164
-
165
- build_create_endpoint_tests(
166
- DBTBlockAPIEndpointTest,
167
- assert_after_create_count=__assert_after_create,
168
- assert_before_create_count=lambda self: len(get_pipeline(self).blocks_by_uuid.values()) == 4,
169
- build_payload=lambda self: dict(
170
- name=self.faker.unique.name(),
171
- type=BlockType.DBT,
172
- language=BlockLanguage.SQL,
173
- configuration=dict(
174
- file_path=os.path.join(
175
- os.path.basename(self.dbt_directory),
176
- 'test_project',
177
- 'models',
178
- 'example',
179
- 'my_first_dbt_model.sql',
180
- ),
181
- ),
182
- ),
183
- get_resource_parent_id=lambda self: self.pipeline.uuid,
184
- resource='block',
185
- resource_parent='pipelines',
186
- )
187
-
188
-
189
- build_create_endpoint_tests(
190
- DBTBlockAPIEndpointTest,
191
- test_uuid='dbt_yaml',
192
- assert_after_create_count=__assert_after_create_yaml,
193
- assert_before_create_count=lambda self: len(get_pipeline(self).blocks_by_uuid.values()) == 4,
194
- build_payload=lambda self: dict(
195
- name='dbt_yaml',
196
- type=BlockType.DBT,
197
- language=BlockLanguage.YAML,
198
- configuration=dict(
199
- dbt_project_name=os.path.join(
200
- os.path.basename(self.dbt_directory),
201
- 'test_project',
202
- ),
203
- ),
204
- ),
205
- get_resource_parent_id=lambda self: self.pipeline.uuid,
206
- resource='block',
207
- resource_parent='pipelines',
208
- )
@@ -1,6 +1,5 @@
1
1
  import json
2
2
  import os
3
- from unittest.mock import patch
4
3
 
5
4
  from mage_ai.authentication.permissions.constants import EntityName
6
5
  from mage_ai.settings.models.configuration_option import ConfigurationType, OptionType
@@ -8,7 +7,7 @@ from mage_ai.tests.api.endpoints.mixins import (
8
7
  BaseAPIEndpointTest,
9
8
  build_list_endpoint_tests,
10
9
  )
11
- from mage_ai.tests.shared.mixins import DBTMixin, ProjectPlatformMixin
10
+ from mage_ai.tests.shared.mixins import DBTMixin
12
11
 
13
12
  CURRENT_FILE_PATH = os.path.dirname(os.path.realpath(__file__))
14
13
 
@@ -51,49 +50,3 @@ build_list_endpoint_tests(
51
50
  assert_after=__assert_after_list,
52
51
  build_query=__build_query,
53
52
  )
54
-
55
-
56
- @patch('mage_ai.settings.platform.utils.project_platform_activated', lambda: True)
57
- @patch('mage_ai.settings.repo.project_platform_activated', lambda: True)
58
- class ConfigurationOptionProjectPlatformAPIEndpointTest(
59
- DBTMixin,
60
- ProjectPlatformMixin,
61
- BaseAPIEndpointTest,
62
- ):
63
- pass
64
-
65
-
66
- def __assert_after_list2(self, result, **kwargs):
67
- with open(os.path.join(
68
- CURRENT_FILE_PATH,
69
- 'mocks',
70
- 'mock_dbt_configuration_options_project_platform.json',
71
- )) as f:
72
- self.assertEqual(
73
- result,
74
- json.loads(f.read()),
75
- )
76
-
77
-
78
- build_list_endpoint_tests(
79
- ConfigurationOptionProjectPlatformAPIEndpointTest,
80
- list_count=1,
81
- get_resource_parent_id=lambda test_case: test_case.pipeline.uuid,
82
- resource='configuration_option',
83
- resource_parent='pipeline',
84
- result_keys_to_compare=[
85
- 'configuration_type',
86
- 'metadata',
87
- 'option',
88
- 'option_type',
89
- 'resource_type',
90
- 'uuid',
91
- ],
92
- assert_after=__assert_after_list2,
93
- build_query=__build_query,
94
- patch_function_settings=[
95
- ('mage_ai.settings.models.configuration_option.project_platform_activated', lambda: True),
96
- ('mage_ai.settings.platform.utils.project_platform_activated', lambda: True),
97
- ('mage_ai.settings.repo.project_platform_activated', lambda: True),
98
- ],
99
- )