mage-ai 0.9.65__py3-none-any.whl → 0.9.67__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mage-ai might be problematic. Click here for more details.

Files changed (242) hide show
  1. mage_ai/api/monitors/BaseMonitor.py +38 -16
  2. mage_ai/api/policies/BackfillPolicy.py +1 -0
  3. mage_ai/api/resources/OauthResource.py +13 -5
  4. mage_ai/api/resources/SessionResource.py +6 -4
  5. mage_ai/authentication/ldap.py +19 -9
  6. mage_ai/authentication/oauth/constants.py +8 -14
  7. mage_ai/authentication/oauth/utils.py +18 -6
  8. mage_ai/authentication/providers/active_directory.py +21 -16
  9. mage_ai/authentication/providers/azure_devops.py +18 -0
  10. mage_ai/authentication/providers/bitbucket.py +10 -9
  11. mage_ai/authentication/providers/constants.py +2 -0
  12. mage_ai/authentication/providers/ghe.py +5 -9
  13. mage_ai/authentication/providers/gitlab.py +6 -9
  14. mage_ai/authentication/providers/google.py +9 -6
  15. mage_ai/authentication/providers/oidc.py +6 -4
  16. mage_ai/authentication/providers/okta.py +9 -6
  17. mage_ai/cluster_manager/kubernetes/workload_manager.py +10 -0
  18. mage_ai/cluster_manager/workspace/base.py +6 -1
  19. mage_ai/cluster_manager/workspace/kubernetes.py +3 -0
  20. mage_ai/data_preparation/decorators.py +15 -0
  21. mage_ai/data_preparation/executors/streaming_pipeline_executor.py +22 -12
  22. mage_ai/data_preparation/git/__init__.py +10 -1
  23. mage_ai/data_preparation/git/api.py +3 -0
  24. mage_ai/data_preparation/git/clients/azure_devops.py +106 -0
  25. mage_ai/data_preparation/git/clients/base.py +6 -0
  26. mage_ai/data_preparation/git/clients/gitlab.py +3 -2
  27. mage_ai/data_preparation/git/utils.py +31 -29
  28. mage_ai/data_preparation/models/block/__init__.py +27 -18
  29. mage_ai/data_preparation/models/block/dbt/block_sql.py +164 -0
  30. mage_ai/data_preparation/models/block/dynamic/variables.py +1 -2
  31. mage_ai/data_preparation/models/pipeline.py +3 -3
  32. mage_ai/data_preparation/models/triggers/__init__.py +6 -1
  33. mage_ai/data_preparation/preferences.py +42 -37
  34. mage_ai/data_preparation/repo_manager.py +21 -0
  35. mage_ai/data_preparation/storage/gcs_storage.py +27 -2
  36. mage_ai/data_preparation/storage/local_storage.py +18 -3
  37. mage_ai/data_preparation/storage/s3_storage.py +7 -2
  38. mage_ai/data_preparation/templates/data_loaders/streaming/generic_python.py +23 -0
  39. mage_ai/data_preparation/templates/main/metadata.yaml +6 -0
  40. mage_ai/data_preparation/templates/template.py +6 -2
  41. mage_ai/data_preparation/variable_manager.py +2 -1
  42. mage_ai/io/base.py +3 -0
  43. mage_ai/io/bigquery.py +2 -0
  44. mage_ai/io/export_utils.py +14 -9
  45. mage_ai/io/mssql.py +104 -25
  46. mage_ai/io/mysql.py +10 -9
  47. mage_ai/io/oracledb.py +14 -2
  48. mage_ai/io/postgres.py +3 -0
  49. mage_ai/io/sql.py +14 -6
  50. mage_ai/io/trino.py +10 -8
  51. mage_ai/orchestration/db/migrations/versions/90d978a8aef8_update_unique_constraint_for_secret.py +11 -5
  52. mage_ai/orchestration/db/models/schedules.py +25 -1
  53. mage_ai/orchestration/db/models/schedules_project_platform.py +24 -1
  54. mage_ai/orchestration/job_manager.py +6 -1
  55. mage_ai/orchestration/pipeline_scheduler_original.py +16 -10
  56. mage_ai/server/constants.py +1 -1
  57. mage_ai/server/file_observer.py +10 -0
  58. mage_ai/server/frontend_dist/404.html +2 -2
  59. mage_ai/server/frontend_dist/_next/static/chunks/{1557-a754b04510d50b80.js → 1557-01f0843dc6ac4971.js} +1 -1
  60. mage_ai/server/frontend_dist/_next/static/chunks/9440-4069842b90d4b801.js +1 -0
  61. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-1c1ffd928f5a00f7.js +1 -0
  62. mage_ai/server/frontend_dist/_next/static/chunks/pages/index-b7b8695a7f9efde2.js +1 -0
  63. mage_ai/server/frontend_dist/_next/static/chunks/pages/oauth-30e34ee15d410331.js +1 -0
  64. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-ff4bd7a8ec3bab40.js +1 -0
  65. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-aaf393c86fc1bda3.js +1 -0
  66. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{edit-8d32ac7e8f023779.js → edit-36377e679da2cd91.js} +1 -1
  67. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-3f5c14076ddde20e.js +1 -0
  68. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{triggers-fe08120d9a6fb1b0.js → triggers-f508c2f261297724.js} +1 -1
  69. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-bcdb4ad41dd4c7d5.js → frontend_dist/_next/static/chunks/pages/pipelines-f99e99aa8f45529c.js} +1 -1
  70. mage_ai/server/frontend_dist/_next/static/chunks/pages/{sign-in-19b36600d908b711.js → sign-in-7d38b2f7c3e918a1.js} +1 -1
  71. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-5753fac7c1bfdc88.js +1 -0
  72. mage_ai/server/frontend_dist/_next/static/chunks/{webpack-ac7fdc472bedf682.js → webpack-d079359c241db804.js} +1 -1
  73. mage_ai/server/frontend_dist/_next/static/{ZMrJfDouIX5AMb_RteRbL → vPsMu6Fi2zrHaf2fRXKRO}/_buildManifest.js +1 -1
  74. mage_ai/server/frontend_dist/block-layout.html +2 -2
  75. mage_ai/server/frontend_dist/compute.html +2 -2
  76. mage_ai/server/frontend_dist/files.html +2 -2
  77. mage_ai/server/frontend_dist/global-data-products/[...slug].html +2 -2
  78. mage_ai/server/frontend_dist/global-data-products.html +2 -2
  79. mage_ai/server/frontend_dist/global-hooks/[...slug].html +2 -2
  80. mage_ai/server/frontend_dist/global-hooks.html +2 -2
  81. mage_ai/server/frontend_dist/index.html +2 -2
  82. mage_ai/server/frontend_dist/manage/files.html +2 -2
  83. mage_ai/server/frontend_dist/manage/settings.html +2 -2
  84. mage_ai/server/frontend_dist/manage/users/[user].html +2 -2
  85. mage_ai/server/frontend_dist/manage/users/new.html +2 -2
  86. mage_ai/server/frontend_dist/manage/users.html +2 -2
  87. mage_ai/server/frontend_dist/manage.html +2 -2
  88. mage_ai/server/frontend_dist/oauth.html +2 -2
  89. mage_ai/server/frontend_dist/overview.html +2 -2
  90. mage_ai/server/frontend_dist/pipeline-runs.html +2 -2
  91. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +2 -2
  92. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +2 -2
  93. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +2 -2
  94. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +2 -2
  95. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +2 -2
  96. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +2 -2
  97. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +2 -2
  98. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +2 -2
  99. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +2 -2
  100. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +2 -2
  101. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +2 -2
  102. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +2 -2
  103. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +2 -2
  104. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +2 -2
  105. mage_ai/server/frontend_dist/pipelines/[pipeline].html +2 -2
  106. mage_ai/server/frontend_dist/pipelines.html +2 -2
  107. mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +2 -2
  108. mage_ai/server/frontend_dist/platform/global-hooks.html +2 -2
  109. mage_ai/server/frontend_dist/settings/account/profile.html +2 -2
  110. mage_ai/server/frontend_dist/settings/platform/preferences.html +2 -2
  111. mage_ai/server/frontend_dist/settings/platform/settings.html +2 -2
  112. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +2 -2
  113. mage_ai/server/frontend_dist/settings/workspace/permissions.html +2 -2
  114. mage_ai/server/frontend_dist/settings/workspace/preferences.html +2 -2
  115. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +2 -2
  116. mage_ai/server/frontend_dist/settings/workspace/roles.html +2 -2
  117. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +2 -2
  118. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +2 -2
  119. mage_ai/server/frontend_dist/settings/workspace/users.html +2 -2
  120. mage_ai/server/frontend_dist/settings.html +2 -2
  121. mage_ai/server/frontend_dist/sign-in.html +2 -2
  122. mage_ai/server/frontend_dist/templates/[...slug].html +2 -2
  123. mage_ai/server/frontend_dist/templates.html +2 -2
  124. mage_ai/server/frontend_dist/terminal.html +2 -2
  125. mage_ai/server/frontend_dist/test.html +2 -2
  126. mage_ai/server/frontend_dist/triggers.html +2 -2
  127. mage_ai/server/frontend_dist/version-control.html +2 -2
  128. mage_ai/server/frontend_dist_base_path_template/404.html +2 -2
  129. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{1557-a754b04510d50b80.js → 1557-01f0843dc6ac4971.js} +1 -1
  130. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-4069842b90d4b801.js +1 -0
  131. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-1c1ffd928f5a00f7.js +1 -0
  132. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/index-b7b8695a7f9efde2.js +1 -0
  133. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/oauth-30e34ee15d410331.js +1 -0
  134. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-ff4bd7a8ec3bab40.js +1 -0
  135. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-aaf393c86fc1bda3.js +1 -0
  136. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{edit-8d32ac7e8f023779.js → edit-36377e679da2cd91.js} +1 -1
  137. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-3f5c14076ddde20e.js +1 -0
  138. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{triggers-fe08120d9a6fb1b0.js → triggers-f508c2f261297724.js} +1 -1
  139. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines-bcdb4ad41dd4c7d5.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-f99e99aa8f45529c.js} +1 -1
  140. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{sign-in-19b36600d908b711.js → sign-in-7d38b2f7c3e918a1.js} +1 -1
  141. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-5753fac7c1bfdc88.js +1 -0
  142. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-481689d9989710cd.js → webpack-68c003fb6a175cd7.js} +1 -1
  143. mage_ai/server/frontend_dist_base_path_template/_next/static/{QYwFH4sievaq5XyUjRriy → khKiaJtwrslgMmp4YSa1f}/_buildManifest.js +1 -1
  144. mage_ai/server/frontend_dist_base_path_template/block-layout.html +2 -2
  145. mage_ai/server/frontend_dist_base_path_template/compute.html +2 -2
  146. mage_ai/server/frontend_dist_base_path_template/files.html +2 -2
  147. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +2 -2
  148. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +2 -2
  149. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +2 -2
  150. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +2 -2
  151. mage_ai/server/frontend_dist_base_path_template/index.html +2 -2
  152. mage_ai/server/frontend_dist_base_path_template/manage/files.html +2 -2
  153. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +2 -2
  154. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +2 -2
  155. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +2 -2
  156. mage_ai/server/frontend_dist_base_path_template/manage/users.html +2 -2
  157. mage_ai/server/frontend_dist_base_path_template/manage.html +2 -2
  158. mage_ai/server/frontend_dist_base_path_template/oauth.html +2 -2
  159. mage_ai/server/frontend_dist_base_path_template/overview.html +2 -2
  160. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +2 -2
  161. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +2 -2
  162. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +2 -2
  163. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +2 -2
  164. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +2 -2
  165. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +2 -2
  166. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +2 -2
  167. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +2 -2
  168. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +2 -2
  169. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +2 -2
  170. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +2 -2
  171. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +2 -2
  172. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +2 -2
  173. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +2 -2
  174. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +2 -2
  175. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +2 -2
  176. mage_ai/server/frontend_dist_base_path_template/pipelines.html +2 -2
  177. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +2 -2
  178. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +2 -2
  179. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +2 -2
  180. mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +2 -2
  181. mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +2 -2
  182. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +2 -2
  183. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +2 -2
  184. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +2 -2
  185. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +2 -2
  186. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +2 -2
  187. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +2 -2
  188. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +2 -2
  189. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +2 -2
  190. mage_ai/server/frontend_dist_base_path_template/settings.html +2 -2
  191. mage_ai/server/frontend_dist_base_path_template/sign-in.html +2 -2
  192. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +2 -2
  193. mage_ai/server/frontend_dist_base_path_template/templates.html +2 -2
  194. mage_ai/server/frontend_dist_base_path_template/terminal.html +2 -2
  195. mage_ai/server/frontend_dist_base_path_template/test.html +2 -2
  196. mage_ai/server/frontend_dist_base_path_template/triggers.html +2 -2
  197. mage_ai/server/frontend_dist_base_path_template/version-control.html +2 -2
  198. mage_ai/server/server.py +117 -87
  199. mage_ai/server/utils/output_display.py +6 -1
  200. mage_ai/services/aws/s3/s3.py +8 -2
  201. mage_ai/services/slack/slack.py +8 -8
  202. mage_ai/settings/__init__.py +36 -186
  203. mage_ai/settings/backends.py +95 -0
  204. mage_ai/settings/keys/__init__.py +1 -0
  205. mage_ai/settings/keys/auth.py +76 -0
  206. mage_ai/settings/server.py +187 -0
  207. mage_ai/shared/io.py +2 -2
  208. mage_ai/shared/logger.py +12 -6
  209. mage_ai/streaming/sources/base_python.py +30 -0
  210. mage_ai/streaming/sources/source_factory.py +25 -0
  211. mage_ai/tests/api/endpoints/test_oauths.py +13 -5
  212. mage_ai/tests/api/operations/test_operations.py +2 -2
  213. mage_ai/tests/api/operations/test_sessions.py +83 -48
  214. mage_ai/tests/authentication/oauth/test_utils.py +56 -6
  215. mage_ai/tests/authentication/providers/test_active_directory.py +9 -15
  216. mage_ai/tests/data_preparation/models/test_block.py +39 -2
  217. mage_ai/tests/orchestration/db/models/test_schedules.py +33 -1
  218. {mage_ai-0.9.65.dist-info → mage_ai-0.9.67.dist-info}/METADATA +2 -1
  219. {mage_ai-0.9.65.dist-info → mage_ai-0.9.67.dist-info}/RECORD +225 -217
  220. {mage_ai-0.9.65.dist-info → mage_ai-0.9.67.dist-info}/WHEEL +1 -1
  221. mage_ai/server/frontend_dist/_next/static/chunks/9440-2bcbdc765ed82062.js +0 -1
  222. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-2ae1d919333f01fe.js +0 -1
  223. mage_ai/server/frontend_dist/_next/static/chunks/pages/index-64851458dde54ad9.js +0 -1
  224. mage_ai/server/frontend_dist/_next/static/chunks/pages/oauth-abe5ba687cb93509.js +0 -1
  225. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-22e49726eeed16ae.js +0 -1
  226. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-c74507dce89b41a2.js +0 -1
  227. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-cf656cbe37ecaacc.js +0 -1
  228. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-690206d30d8b412b.js +0 -1
  229. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-2bcbdc765ed82062.js +0 -1
  230. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-2ae1d919333f01fe.js +0 -1
  231. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/index-64851458dde54ad9.js +0 -1
  232. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/oauth-abe5ba687cb93509.js +0 -1
  233. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-22e49726eeed16ae.js +0 -1
  234. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-c74507dce89b41a2.js +0 -1
  235. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-cf656cbe37ecaacc.js +0 -1
  236. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-690206d30d8b412b.js +0 -1
  237. mage_ai/settings/sso.py +0 -27
  238. /mage_ai/server/frontend_dist/_next/static/{ZMrJfDouIX5AMb_RteRbL → vPsMu6Fi2zrHaf2fRXKRO}/_ssgManifest.js +0 -0
  239. /mage_ai/server/frontend_dist_base_path_template/_next/static/{QYwFH4sievaq5XyUjRriy → khKiaJtwrslgMmp4YSa1f}/_ssgManifest.js +0 -0
  240. {mage_ai-0.9.65.dist-info → mage_ai-0.9.67.dist-info}/LICENSE +0 -0
  241. {mage_ai-0.9.65.dist-info → mage_ai-0.9.67.dist-info}/entry_points.txt +0 -0
  242. {mage_ai-0.9.65.dist-info → mage_ai-0.9.67.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,95 @@
1
+ import base64
2
+ import logging
3
+ import os
4
+ from enum import Enum
5
+ from typing import Optional
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ class BackendType(str, Enum):
11
+ """
12
+ Enum for the different types of settings backends.
13
+ """
14
+ AWS_SECRETS_MANAGER = 'aws_secrets_manager'
15
+
16
+
17
+ class SettingsBackend:
18
+ """
19
+ Base settings backend class. A settings backend is a read-only storage of Mage settings.
20
+ The source of the configuration settings is dependent on the specific loader. The default source
21
+ are environment variables.
22
+ """
23
+ backend_type = None
24
+
25
+ def get(self, key: str, **kwargs) -> Optional[str]:
26
+ """
27
+ Loads the configuration setting stored under `key`.
28
+
29
+ Args:
30
+ key (str): Name of the setting to load
31
+
32
+ Returns:
33
+ Any: The setting value stored under `key` in the configuration manager. If key
34
+ doesn't exist, returns None.
35
+ """
36
+ value = self._get(key, **kwargs) # noqa: E1128
37
+ if value is None:
38
+ value = os.getenv(key)
39
+ if value is None:
40
+ value = kwargs.get('default')
41
+ return value
42
+
43
+ def _get(self, key: str, **kwargs) -> Optional[str]:
44
+ """
45
+ Loads the configuration setting stored under `key`.
46
+
47
+ Args:
48
+ key (str): Name of the setting to load
49
+
50
+ Returns:
51
+ Any: The setting value stored under `key` in the configuration manager. If key
52
+ doesn't exist, returns None.
53
+ """
54
+ return None
55
+
56
+
57
+ class AWSSecretsManagerBackend(SettingsBackend):
58
+ """
59
+ Settings backend that loads configuration settings from AWS Secrets Manager.
60
+ """
61
+ backend_type = BackendType.AWS_SECRETS_MANAGER
62
+
63
+ def __init__(self, **kwargs) -> None:
64
+ import boto3
65
+
66
+ self.client = boto3.client('secretsmanager')
67
+ self.prefix = kwargs.get('prefix', '')
68
+ self.use_cache = kwargs.get('use_cache', False)
69
+ self.cache = None
70
+ if self.use_cache:
71
+ from aws_secretsmanager_caching import SecretCache, SecretCacheConfig
72
+ cache_config_arg = kwargs.get('cache_config', {})
73
+ cache_config = SecretCacheConfig(**cache_config_arg)
74
+ self.cache = SecretCache(config=cache_config, client=self.client)
75
+
76
+ def _get(self, key: str, **kwargs) -> Optional[str]:
77
+ from botocore.exceptions import ClientError
78
+ if self.prefix:
79
+ key = f'{self.prefix}{key}'
80
+ if self.cache is not None:
81
+ return self.cache.get_secret_string(key)
82
+ else:
83
+ try:
84
+ secret_response = self.client.get_secret_value(
85
+ SecretId=key,
86
+ )
87
+ if 'SecretBinary' in secret_response:
88
+ binary = secret_response['SecretBinary']
89
+ return base64.b64decode(binary)
90
+ else:
91
+ return secret_response['SecretString']
92
+ except ClientError as error:
93
+ if error.response['Error']['Code'] != 'ResourceNotFoundException':
94
+ logger.exception('Failed to get secret %s from AWS Secrets Manager.', key)
95
+ return None
@@ -0,0 +1 @@
1
+ from mage_ai.settings.keys.auth import * # noqa: F401, F403
@@ -0,0 +1,76 @@
1
+ # LDAP settings
2
+
3
+ LDAP_SERVER = 'LDAP_SERVER'
4
+ LDAP_BIND_DN = 'LDAP_BIND_DN'
5
+ LDAP_BIND_PASSWORD = 'LDAP_BIND_PASSWORD'
6
+ LDAP_BASE_DN = 'LDAP_BASE_DN'
7
+ LDAP_AUTHENTICATION_FILTER = 'LDAP_AUTHENTICATION_FILTER'
8
+ LDAP_AUTHORIZATION_FILTER = 'LDAP_AUTHORIZATION_FILTER'
9
+ LDAP_ADMIN_USERNAME = 'LDAP_ADMIN_USERNAME'
10
+ # Default access level to give to users created when authenticated through LDAP
11
+ # for the first time. value should be the name of a Mage role (e.g. Viewer, Editor, Admin)
12
+ LDAP_DEFAULT_ACCESS = 'LDAP_DEFAULT_ACCESS'
13
+ LDAP_GROUP_FIELD = 'LDAP_GROUP_FIELD'
14
+ LDAP_ROLES_MAPPING = 'LDAP_ROLES_MAPPING'
15
+
16
+ # Git settings
17
+
18
+ GIT_REPO_LINK = 'GIT_REPO_LINK'
19
+ GIT_REPO_PATH = 'GIT_REPO_PATH'
20
+ GIT_USERNAME = 'GIT_USERNAME'
21
+ GIT_EMAIL = 'GIT_EMAIL'
22
+ GIT_AUTH_TYPE = 'GIT_AUTH_TYPE'
23
+ GIT_BRANCH = 'GIT_BRANCH'
24
+ GIT_SYNC_ON_PIPELINE_RUN = 'GIT_SYNC_ON_PIPELINE_RUN'
25
+ GIT_SYNC_ON_START = 'GIT_SYNC_ON_START'
26
+ GIT_SYNC_ON_EXECUTOR_START = 'GIT_SYNC_ON_EXECUTOR_START'
27
+ GIT_SYNC_SUBMODULES = 'GIT_SYNC_SUBMODULES'
28
+
29
+ GIT_ENABLE_GIT_INTEGRATION = 'GIT_ENABLE_GIT_INTEGRATION'
30
+ GIT_OVERWRITE_WITH_PROJECT_SETTINGS = 'GIT_OVERWRITE_WITH_PROJECT_SETTINGS'
31
+
32
+ GIT_SSH_PUBLIC_KEY = 'GIT_SSH_PUBLIC_KEY'
33
+ GIT_SSH_PRIVATE_KEY = 'GIT_SSH_PRIVATE_KEY'
34
+ GIT_ACCESS_TOKEN = 'GIT_ACCESS_TOKEN'
35
+
36
+ # Git Provider OAuth settings
37
+
38
+ GHE_CLIENT_ID = 'GHE_CLIENT_ID'
39
+ GHE_CLIENT_SECRET = 'GHE_CLIENT_SECRET'
40
+ GHE_HOSTNAME = 'GHE_HOSTNAME'
41
+
42
+ GITLAB_HOST = 'GITLAB_HOST'
43
+ GITLAB_CLIENT_ID = 'GITLAB_CLIENT_ID'
44
+ GITLAB_CLIENT_SECRET = 'GITLAB_CLIENT_SECRET'
45
+
46
+ BITBUCKET_HOST = 'BITBUCKET_HOST'
47
+ BITBUCKET_OAUTH_KEY = 'BITBUCKET_OAUTH_KEY'
48
+ BITBUCKET_OAUTH_SECRET = 'BITBUCKET_OAUTH_SECRET'
49
+
50
+ # Okta settings
51
+
52
+ OKTA_DOMAIN_URL = 'OKTA_DOMAIN_URL'
53
+ OKTA_CLIENT_ID = 'OKTA_CLIENT_ID'
54
+ OKTA_CLIENT_SECRET = 'OKTA_CLIENT_SECRET'
55
+
56
+ # Google settings
57
+
58
+ GOOGLE_CLIENT_ID = 'GOOGLE_CLIENT_ID'
59
+ GOOGLE_CLIENT_SECRET = 'GOOGLE_CLIENT_SECRET'
60
+
61
+ # Active directory settings
62
+
63
+ ACTIVE_DIRECTORY_CLIENT_ID = 'ACTIVE_DIRECTORY_CLIENT_ID'
64
+ ACTIVE_DIRECTORY_CLIENT_SECRET = 'ACTIVE_DIRECTORY_CLIENT_SECRET'
65
+ ACTIVE_DIRECTORY_DIRECTORY_ID = 'ACTIVE_DIRECTORY_DIRECTORY_ID'
66
+ ACTIVE_DIRECTORY_ROLES_MAPPING = 'ACTIVE_DIRECTORY_ROLES_MAPPING'
67
+
68
+ # Azure DevOps settings
69
+
70
+ AZURE_DEVOPS_ORGANIZATION = 'AZURE_DEVOPS_ORGANIZATION'
71
+
72
+ # OIDC
73
+
74
+ OIDC_CLIENT_ID = 'OIDC_CLIENT_ID'
75
+ OIDC_CLIENT_SECRET = 'OIDC_CLIENT_SECRET'
76
+ OIDC_DISCOVERY_URL = 'OIDC_DISCOVERY_URL'
@@ -0,0 +1,187 @@
1
+ import os
2
+
3
+ from .secret_generation import generate_jwt_secret
4
+
5
+ # If you add a new environment variable, make sure to check if it should be added to
6
+ # the `MAGE_SETTINGS_ENVIRONMENT_VARIABLES` list at the bottom of this file. Also, update
7
+ # the environment variable documentation at docs/development/variables/environment-variables.mdx
8
+
9
+ DEBUG = os.getenv('DEBUG', False)
10
+ HIDE_ENV_VAR_VALUES = int(os.getenv('HIDE_ENV_VAR_VALUES', 1) or 1) == 1
11
+ QUERY_API_KEY = 'api_key'
12
+
13
+ """
14
+ import secrets
15
+ secrets.token_urlsafe()
16
+
17
+ Make sure this value is the same in mage_ai/frontend/api/constants.ts
18
+ """
19
+ OAUTH2_APPLICATION_CLIENT_ID = 'zkWlN0PkIKSN0C11CfUHUj84OT5XOJ6tDZ6bDRO2'
20
+
21
+ # valid values: 0, 1, 2
22
+ try:
23
+ DISABLE_NOTEBOOK_EDIT_ACCESS = int(os.getenv('DISABLE_NOTEBOOK_EDIT_ACCESS', 0))
24
+ except ValueError:
25
+ DISABLE_NOTEBOOK_EDIT_ACCESS = 1 if os.getenv('DISABLE_NOTEBOOK_EDIT_ACCESS') else 0
26
+
27
+
28
+ def is_disable_pipeline_edit_access(
29
+ disable_notebook_edit_access_override: int = None,
30
+ ) -> bool:
31
+ value = DISABLE_NOTEBOOK_EDIT_ACCESS
32
+ if disable_notebook_edit_access_override is not None:
33
+ value = disable_notebook_edit_access_override
34
+ return value >= 1
35
+
36
+
37
+ def get_bool_value(value: str) -> bool:
38
+ """
39
+ Converts a string environment variable to a bool value. Returns True if the value
40
+ is 'true', '1', or 't' (case insensitive). Otherwise, False
41
+ """
42
+ if value is None:
43
+ return False
44
+
45
+ return value.lower() in ('true', '1', 't')
46
+
47
+
48
+ # ------------------------- DISABLE TERMINAL ----------------------
49
+
50
+ DISABLE_TERMINAL = os.getenv('DISABLE_TERMINAL', '0').lower() in ('true', '1', 't')
51
+
52
+ # ----------------- Authentication settings ----------------
53
+ REQUIRE_USER_AUTHENTICATION = get_bool_value(
54
+ os.getenv('REQUIRE_USER_AUTHENTICATION', 'False')
55
+ )
56
+ REQUIRE_USER_PERMISSIONS = REQUIRE_USER_AUTHENTICATION and get_bool_value(
57
+ os.getenv('REQUIRE_USER_PERMISSIONS', 'False')
58
+ )
59
+ AUTHENTICATION_MODE = os.getenv('AUTHENTICATION_MODE', 'LOCAL')
60
+ try:
61
+ MAGE_ACCESS_TOKEN_EXPIRY_TIME = int(
62
+ os.getenv('MAGE_ACCESS_TOKEN_EXPIRY_TIME', '2592000')
63
+ )
64
+ except ValueError:
65
+ MAGE_ACCESS_TOKEN_EXPIRY_TIME = 2592000
66
+
67
+ # Default access level to give to users created when authenticated through OAuth
68
+ # for the first time. value should be the name of a Mage role (e.g. Viewer, Editor, Admin)
69
+ OAUTH_DEFAULT_ACCESS = os.getenv('OAUTH_DEFAULT_ACCESS')
70
+
71
+ # ----------------------------------------------------------
72
+
73
+ HOSTNAME = os.getenv('HOSTNAME')
74
+ REDIS_URL = os.getenv('REDIS_URL')
75
+ SERVER_VERBOSITY = os.getenv('SERVER_VERBOSITY', 'info') or 'info'
76
+ SERVER_LOGGING_FORMAT = os.getenv('SERVER_LOGGING_FORMAT', 'plaintext')
77
+ SERVER_LOGGING_TEMPLATE = os.getenv(
78
+ 'SERVER_LOGGING_TEMPLATE',
79
+ '%(levelname)s:%(name)s:%(message)s',
80
+ )
81
+
82
+ INITIAL_METADATA = os.getenv('INITIAL_METADATA', '{{}}')
83
+
84
+ DISABLE_AUTO_BROWSER_OPEN = get_bool_value(os.getenv('DISABLE_AUTO_BROWSER_OPEN', 'False'))
85
+
86
+ SHELL_COMMAND = os.getenv('SHELL_COMMAND', None)
87
+ USE_UNIQUE_TERMINAL = os.getenv('USE_UNIQUE_TERMINAL', None)
88
+
89
+ # sentry environment variables
90
+ SENTRY_DSN = os.getenv('SENTRY_DSN')
91
+ SENTRY_TRACES_SAMPLE_RATE = os.getenv('SENTRY_TRACES_SAMPLE_RATE', 1.0)
92
+
93
+ # New relic enable environment variable
94
+ ENABLE_NEW_RELIC = os.getenv('ENABLE_NEW_RELIC', False)
95
+ NEW_RELIC_CONFIG_PATH = os.getenv('NEW_RELIC_CONFIG_PATH', '')
96
+
97
+ # If enabled, the /metrics route will expose Tornado server metrics
98
+ ENABLE_PROMETHEUS = get_bool_value(os.getenv('ENABLE_PROMETHEUS', 'False'))
99
+
100
+ # OpenTelemetry configuration
101
+ OTEL_EXPORTER_OTLP_ENDPOINT = os.getenv('OTEL_EXPORTER_OTLP_ENDPOINT', None)
102
+ OTEL_EXPORTER_OTLP_HTTP_ENDPOINT = os.getenv('OTEL_EXPORTER_HTTP_OTLP_ENDPOINT', None)
103
+ OTEL_PYTHON_TORNADO_EXCLUDED_URLS = (
104
+ os.getenv('OTEL_PYTHON_TORNADO_EXCLUDED_URLS') or '/api/statuses'
105
+ )
106
+
107
+ DEFAULT_LOCALHOST_URL = 'http://localhost:6789'
108
+ MAGE_PUBLIC_HOST = os.getenv('MAGE_PUBLIC_HOST') or DEFAULT_LOCALHOST_URL
109
+
110
+ MAX_FILE_CACHE_SIZE = os.getenv('MAX_FILE_CACHE_SIZE') or (1024 * 1024) # 1 MB
111
+
112
+ # All base path variables should not include a leading forward slash
113
+ # e.g. MAGE_BASE_PATH = 'test_prefix' -> localhost:6789/test_prefix/pipelines
114
+ BASE_PATH = os.getenv('MAGE_BASE_PATH')
115
+ # Requests base path is used to configure the base path for the frontend requests. Defaults
116
+ # to the MAGE_BASE_PATH environment variable.
117
+ REQUESTS_BASE_PATH = os.getenv('MAGE_REQUESTS_BASE_PATH', BASE_PATH)
118
+ # Routes base path is used to configure the base path for the backend routes. Defaults
119
+ # to the MAGE_BASE_PATH environment variable.
120
+ ROUTES_BASE_PATH = os.getenv('MAGE_ROUTES_BASE_PATH', BASE_PATH)
121
+ # Used for OAUTH
122
+ JWT_SECRET = os.getenv('JWT_SECRET', 'materia')
123
+ # Used for generating download tokens
124
+ JWT_DOWNLOAD_SECRET = os.getenv('JWT_DOWNLOAD_SECRET', generate_jwt_secret())
125
+ # Sets the trigger interval of the scheduler to a numeric value, in seconds
126
+ # Determines how often the scheduler gets invoked
127
+ try:
128
+ SCHEDULER_TRIGGER_INTERVAL = float(os.getenv('SCHEDULER_TRIGGER_INTERVAL', '10'))
129
+ except ValueError:
130
+ SCHEDULER_TRIGGER_INTERVAL = 10
131
+
132
+ # List of environment variables used to configure Mage. The value of these settings
133
+ # will be copied between workspaces.
134
+ MAGE_SETTINGS_ENVIRONMENT_VARIABLES = [
135
+ 'DISABLE_NOTEBOOK_EDIT_ACCESS',
136
+ 'DISABLE_AUTO_BROWSER_OPEN',
137
+ 'REQUIRE_USER_AUTHENTICATION',
138
+ 'AUTHENTICATION_MODE',
139
+ 'OAUTH_DEFAULT_ACCESS',
140
+ 'LDAP_SERVER',
141
+ 'LDAP_BIND_DN',
142
+ 'LDAP_BIND_PASSWORD',
143
+ 'LDAP_BASE_DN',
144
+ 'LDAP_AUTHENTICATION_FILTER',
145
+ 'LDAP_AUTHORIZATION_FILTER',
146
+ 'LDAP_ADMIN_USERNAME',
147
+ 'LDAP_DEFAULT_ACCESS',
148
+ 'LDAP_GROUP_FIELD',
149
+ 'LDAP_ROLES_MAPPING',
150
+ 'SERVER_VERBOSITY',
151
+ 'SERVER_LOGGING_FORMAT',
152
+ 'SHELL_COMMAND',
153
+ 'USE_UNIQUE_TERMINAL',
154
+ 'SENTRY_DSN',
155
+ 'SENTRY_TRACES_SAMPLE_RATE',
156
+ 'MAGE_PUBLIC_HOST',
157
+ 'SCHEDULER_TRIGGER_INTERVAL',
158
+ 'REQUIRE_USER_PERMISSIONS',
159
+ 'ENABLE_PROMETHEUS',
160
+ 'OTEL_EXPORTER_OTLP_ENDPOINT',
161
+ 'OTEL_EXPORTER_OTLP_HTTP_ENDPOINT',
162
+ 'MAX_FILE_CACHE_SIZE',
163
+ 'REDIS_URL',
164
+ # Oauth variables
165
+ 'ACTIVE_DIRECTORY_DIRECTORY_ID',
166
+ 'ACTIVE_DIRECTORY_CLIENT_ID',
167
+ 'ACTIVE_DIRECTORY_CLIENT_SECRET',
168
+ 'ACTIVE_DIRECTORY_ROLES_MAPPING',
169
+ 'OKTA_DOMAIN_URL',
170
+ 'OKTA_CLIENT_ID',
171
+ 'OKTA_CLIENT_SECRET',
172
+ 'GOOGLE_CLIENT_ID',
173
+ 'GOOGLE_CLIENT_SECRET',
174
+ 'OIDC_CLIENT_ID',
175
+ 'OIDC_CLIENT_SECRET',
176
+ 'OIDC_DISCOVERY_URL',
177
+ 'GHE_CLIENT_ID',
178
+ 'GHE_CLIENT_SECRET',
179
+ 'GHE_HOSTNAME',
180
+ 'BITBUCKET_HOST',
181
+ 'BITBUCKET_OAUTH_KEY',
182
+ 'BITBUCKET_OAUTH_SECRET',
183
+ 'GITLAB_HOST',
184
+ 'GITLAB_CLIENT_ID',
185
+ 'GITLAB_CLIENT_SECRET',
186
+ 'SERVER_LOGGING_TEMPLATE',
187
+ ]
mage_ai/shared/io.py CHANGED
@@ -39,7 +39,7 @@ def safe_write(filepath: str, content: str, write_func: Callable = None):
39
39
 
40
40
  success = False
41
41
  try:
42
- with open(filepath, 'w') as fp:
42
+ with open(filepath, 'w', encoding='utf-8') as fp:
43
43
  if write_func is not None:
44
44
  write_func(fp, content)
45
45
  else:
@@ -67,7 +67,7 @@ async def safe_write_async(filepath: str, content: str, write_func: Callable = N
67
67
 
68
68
  success = False
69
69
  try:
70
- async with aiofiles.open(filepath, mode='w') as fp:
70
+ async with aiofiles.open(filepath, mode='w', encoding='utf-8') as fp:
71
71
  if write_func is not None:
72
72
  await write_func(fp, content)
73
73
  else:
mage_ai/shared/logger.py CHANGED
@@ -5,6 +5,7 @@ from contextlib import contextmanager, redirect_stdout
5
5
  from enum import Enum
6
6
  from typing import Callable, List
7
7
 
8
+ from mage_ai.settings import SERVER_LOGGING_TEMPLATE
8
9
  from mage_ai.shared.hash import merge_dict
9
10
 
10
11
  logger = logging.getLogger(__name__)
@@ -84,16 +85,21 @@ class JSONFormatter(logging.Formatter):
84
85
 
85
86
 
86
87
  def set_logging_format(logging_format: str = None, level: str = None) -> None:
87
- handler = logging.StreamHandler()
88
- handler.setFormatter(JSONFormatter())
89
-
90
- root_logger = logging.getLogger()
91
88
  if isinstance(logging_format, str):
92
89
  logging_format = logging_format.lower()
90
+
91
+ root_logger = logging.getLogger()
92
+ if len(root_logger.handlers) > 0:
93
+ root_logger.removeHandler(root_logger.handlers[0])
94
+
95
+ handler = logging.StreamHandler()
93
96
  if logging_format == 'json':
94
- if len(root_logger.handlers) > 0:
95
- root_logger.removeHandler(root_logger.handlers[0])
97
+ handler.setFormatter(JSONFormatter())
96
98
  root_logger.addHandler(handler)
99
+ else:
100
+ handler.setFormatter(logging.Formatter(SERVER_LOGGING_TEMPLATE))
101
+ root_logger.addHandler(handler)
102
+
97
103
  if level:
98
104
  try:
99
105
  root_logger.setLevel(level.upper())
@@ -0,0 +1,30 @@
1
+ from typing import Callable
2
+
3
+ from mage_ai.streaming.sources.base import BaseSource
4
+
5
+
6
+ class BasePythonSource(BaseSource):
7
+ def __init__(self, **kwargs):
8
+ """
9
+ Not require config in the python source
10
+ """
11
+ super().__init__(None, **kwargs)
12
+
13
+ def init_client(self):
14
+ """
15
+ Intialize the client for the source.
16
+ """
17
+
18
+ def read(self, handler: Callable):
19
+ """
20
+ Read the message from the source and use handler to process the message.
21
+
22
+ This method only needs to be implemented when consume_method is 'READ'.
23
+ """
24
+
25
+ def batch_read(self, handler: Callable):
26
+ """
27
+ Batch read the messages from the source and use handler to process the messages.
28
+
29
+ This method only needs to be implemented when consume_method is 'BATCH_READ'.
30
+ """
@@ -1,5 +1,6 @@
1
1
  from typing import Dict
2
2
 
3
+ from mage_ai.data_preparation.decorators import collect_decorated_objs
3
4
  from mage_ai.streaming.constants import SourceType
4
5
 
5
6
 
@@ -51,3 +52,27 @@ class SourceFactory:
51
52
  raise Exception(
52
53
  f'Consuming data from {connector_type} is not supported in streaming pipelines yet.',
53
54
  )
55
+
56
+ @classmethod
57
+ def get_python_source(self, content: str, **kwargs):
58
+ """
59
+ Find the class that's decorated with streaming_source from the source code.
60
+
61
+ Args:
62
+ content (str): The python code that contains the streaming source implementation.
63
+ **kwargs: {'global_vars': {...}}
64
+
65
+ Returns:
66
+ The initialized class object.
67
+
68
+ Raises:
69
+ Exception: Description
70
+ """
71
+ decorated_sources = []
72
+
73
+ exec(content, {'streaming_source': collect_decorated_objs(decorated_sources)})
74
+
75
+ if not decorated_sources:
76
+ raise Exception('Not find the class that has streaming_source decorator.')
77
+
78
+ return decorated_sources[0](**kwargs)
@@ -1,3 +1,5 @@
1
+ import os
2
+
1
3
  from mage_ai.tests.api.endpoints.mixins import (
2
4
  BaseAPIEndpointTest,
3
5
  build_list_endpoint_tests,
@@ -5,7 +7,17 @@ from mage_ai.tests.api.endpoints.mixins import (
5
7
 
6
8
 
7
9
  class OauthAPIEndpointTest(BaseAPIEndpointTest):
8
- pass
10
+ @classmethod
11
+ def setUpClass(self):
12
+ super().setUpClass()
13
+ os.environ['GOOGLE_CLIENT_ID'] = 'test'
14
+ os.environ['GOOGLE_CLIENT_SECRET'] = 'test secret'
15
+
16
+ @classmethod
17
+ def tearDownClass(self):
18
+ super().tearDownClass()
19
+ del os.environ['GOOGLE_CLIENT_ID']
20
+ del os.environ['GOOGLE_CLIENT_SECRET']
9
21
 
10
22
 
11
23
  build_list_endpoint_tests(
@@ -18,8 +30,4 @@ build_list_endpoint_tests(
18
30
  'url',
19
31
  'redirect_query_params',
20
32
  ],
21
- patch_function_settings=[
22
- ('mage_ai.settings.sso.GOOGLE_CLIENT_ID', lambda: 'test'),
23
- ('mage_ai.settings.sso.GOOGLE_CLIENT_SECRET', lambda: 'test secret'),
24
- ]
25
33
  )
@@ -7,7 +7,7 @@ from mage_ai.tests.api.operations.test_base import BaseApiTestCase
7
7
 
8
8
 
9
9
  class OperationTests(BaseApiTestCase):
10
- @patch('mage_ai.settings.DISABLE_NOTEBOOK_EDIT_ACCESS', 1)
10
+ @patch('mage_ai.settings.server.DISABLE_NOTEBOOK_EDIT_ACCESS', 1)
11
11
  @patch('mage_ai.api.utils.DISABLE_NOTEBOOK_EDIT_ACCESS', 1)
12
12
  @patch('mage_ai.api.policies.BasePolicy.DISABLE_NOTEBOOK_EDIT_ACCESS', 1)
13
13
  @patch('mage_ai.api.policies.BasePolicy.REQUIRE_USER_AUTHENTICATION', 0)
@@ -25,7 +25,7 @@ class OperationTests(BaseApiTestCase):
25
25
 
26
26
  self.assertIsNotNone(response['error'])
27
27
 
28
- @patch('mage_ai.settings.DISABLE_NOTEBOOK_EDIT_ACCESS', 1)
28
+ @patch('mage_ai.settings.server.DISABLE_NOTEBOOK_EDIT_ACCESS', 1)
29
29
  @patch('mage_ai.api.utils.DISABLE_NOTEBOOK_EDIT_ACCESS', 1)
30
30
  @patch('mage_ai.api.policies.BasePolicy.DISABLE_NOTEBOOK_EDIT_ACCESS', 1)
31
31
  @patch('mage_ai.api.policies.BasePolicy.REQUIRE_USER_AUTHENTICATION', 1)