mage-ai 0.9.70__py3-none-any.whl → 0.9.71__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 (568) hide show
  1. mage_ai/ai/utils/xgboost.py +222 -0
  2. mage_ai/api/errors.py +37 -25
  3. mage_ai/api/operations/base.py +13 -1
  4. mage_ai/api/parsers/PipelineScheduleParser.py +1 -1
  5. mage_ai/api/policies/BlockOutputPolicy.py +40 -17
  6. mage_ai/api/policies/GlobalDataProductPolicy.py +91 -41
  7. mage_ai/api/policies/KernelPolicy.py +55 -32
  8. mage_ai/api/policies/KernelProcessPolicy.py +56 -0
  9. mage_ai/api/policies/OutputPolicy.py +73 -41
  10. mage_ai/api/policies/PipelinePolicy.py +206 -138
  11. mage_ai/api/presenters/BlockLayoutItemPresenter.py +9 -7
  12. mage_ai/api/presenters/BlockPresenter.py +1 -1
  13. mage_ai/api/presenters/GlobalDataProductPresenter.py +6 -1
  14. mage_ai/api/presenters/KernelPresenter.py +5 -26
  15. mage_ai/api/presenters/KernelProcessPresenter.py +28 -0
  16. mage_ai/api/presenters/PipelinePresenter.py +18 -5
  17. mage_ai/api/presenters/StatusPresenter.py +2 -0
  18. mage_ai/api/presenters/SyncPresenter.py +25 -0
  19. mage_ai/api/resources/AutocompleteItemResource.py +1 -1
  20. mage_ai/api/resources/BlockLayoutItemResource.py +90 -44
  21. mage_ai/api/resources/BlockOutputResource.py +42 -9
  22. mage_ai/api/resources/BlockResource.py +4 -3
  23. mage_ai/api/resources/BlockRunResource.py +27 -22
  24. mage_ai/api/resources/ClusterResource.py +4 -1
  25. mage_ai/api/resources/CustomTemplateResource.py +34 -14
  26. mage_ai/api/resources/DataProviderResource.py +1 -1
  27. mage_ai/api/resources/ExecutionStateResource.py +3 -1
  28. mage_ai/api/resources/FileContentResource.py +8 -2
  29. mage_ai/api/resources/FileResource.py +10 -4
  30. mage_ai/api/resources/FileVersionResource.py +3 -1
  31. mage_ai/api/resources/GitBranchResource.py +46 -9
  32. mage_ai/api/resources/GlobalDataProductResource.py +44 -7
  33. mage_ai/api/resources/GlobalHookResource.py +4 -1
  34. mage_ai/api/resources/IntegrationDestinationResource.py +6 -2
  35. mage_ai/api/resources/IntegrationSourceResource.py +8 -4
  36. mage_ai/api/resources/IntegrationSourceStreamResource.py +6 -2
  37. mage_ai/api/resources/KernelProcessResource.py +44 -0
  38. mage_ai/api/resources/KernelResource.py +25 -3
  39. mage_ai/api/resources/OutputResource.py +33 -11
  40. mage_ai/api/resources/PageBlockLayoutResource.py +34 -23
  41. mage_ai/api/resources/PipelineInteractionResource.py +31 -15
  42. mage_ai/api/resources/PipelineResource.py +250 -123
  43. mage_ai/api/resources/PipelineRunResource.py +11 -3
  44. mage_ai/api/resources/PipelineScheduleResource.py +7 -2
  45. mage_ai/api/resources/PipelineTriggerResource.py +6 -1
  46. mage_ai/api/resources/ProjectResource.py +18 -7
  47. mage_ai/api/resources/SecretResource.py +1 -1
  48. mage_ai/api/resources/SeedResource.py +8 -1
  49. mage_ai/api/resources/StatusResource.py +21 -6
  50. mage_ai/api/resources/SyncResource.py +6 -8
  51. mage_ai/api/resources/VariableResource.py +46 -26
  52. mage_ai/api/resources/VersionControlProjectResource.py +9 -2
  53. mage_ai/api/resources/WidgetResource.py +1 -1
  54. mage_ai/api/resources/WorkspaceResource.py +1 -1
  55. mage_ai/api/views.py +47 -40
  56. mage_ai/authentication/permissions/seed.py +16 -2
  57. mage_ai/authentication/providers/oidc.py +21 -1
  58. mage_ai/autocomplete/utils.py +13 -9
  59. mage_ai/cache/base.py +1 -1
  60. mage_ai/cache/block.py +18 -12
  61. mage_ai/cache/block_action_object/__init__.py +32 -4
  62. mage_ai/cache/file.py +22 -19
  63. mage_ai/cache/pipeline.py +18 -12
  64. mage_ai/cli/main.py +1 -0
  65. mage_ai/cluster_manager/aws/emr_cluster_manager.py +9 -5
  66. mage_ai/cluster_manager/config.py +2 -2
  67. mage_ai/cluster_manager/manage.py +1 -1
  68. mage_ai/cluster_manager/workspace/base.py +1 -1
  69. mage_ai/command_center/applications/factory.py +10 -7
  70. mage_ai/command_center/files/factory.py +17 -15
  71. mage_ai/command_center/utils.py +25 -13
  72. mage_ai/data/__init__.py +0 -0
  73. mage_ai/data/constants.py +45 -0
  74. mage_ai/data/models/__init__.py +0 -0
  75. mage_ai/data/models/base.py +119 -0
  76. mage_ai/data/models/constants.py +1 -0
  77. mage_ai/data/models/generator.py +115 -0
  78. mage_ai/data/models/manager.py +168 -0
  79. mage_ai/data/models/pyarrow/__init__.py +0 -0
  80. mage_ai/data/models/pyarrow/record_batch.py +55 -0
  81. mage_ai/data/models/pyarrow/shared.py +21 -0
  82. mage_ai/data/models/pyarrow/table.py +8 -0
  83. mage_ai/data/models/reader.py +103 -0
  84. mage_ai/data/models/utils.py +59 -0
  85. mage_ai/data/models/writer.py +91 -0
  86. mage_ai/data/tabular/__init__.py +0 -0
  87. mage_ai/data/tabular/constants.py +23 -0
  88. mage_ai/data/tabular/mocks.py +19 -0
  89. mage_ai/data/tabular/models.py +126 -0
  90. mage_ai/data/tabular/reader.py +602 -0
  91. mage_ai/data/tabular/utils.py +102 -0
  92. mage_ai/data/tabular/writer.py +266 -0
  93. mage_ai/data/variables/__init__.py +0 -0
  94. mage_ai/data/variables/wrapper.py +54 -0
  95. mage_ai/data_cleaner/analysis/charts.py +61 -39
  96. mage_ai/data_cleaner/column_types/column_type_detector.py +53 -31
  97. mage_ai/data_cleaner/estimators/encoders.py +5 -2
  98. mage_ai/data_integrations/utils/scheduler.py +16 -11
  99. mage_ai/data_preparation/decorators.py +1 -0
  100. mage_ai/data_preparation/executors/block_executor.py +237 -155
  101. mage_ai/data_preparation/executors/streaming_pipeline_executor.py +1 -1
  102. mage_ai/data_preparation/git/__init__.py +27 -7
  103. mage_ai/data_preparation/git/api.py +7 -1
  104. mage_ai/data_preparation/git/utils.py +22 -16
  105. mage_ai/data_preparation/logging/logger_manager.py +4 -3
  106. mage_ai/data_preparation/models/block/__init__.py +1542 -878
  107. mage_ai/data_preparation/models/block/data_integration/mixins.py +4 -3
  108. mage_ai/data_preparation/models/block/dynamic/__init__.py +17 -6
  109. mage_ai/data_preparation/models/block/dynamic/child.py +41 -102
  110. mage_ai/data_preparation/models/block/dynamic/constants.py +1 -0
  111. mage_ai/data_preparation/models/block/dynamic/counter.py +296 -0
  112. mage_ai/data_preparation/models/block/dynamic/data.py +16 -0
  113. mage_ai/data_preparation/models/block/dynamic/factory.py +163 -0
  114. mage_ai/data_preparation/models/block/dynamic/models.py +19 -0
  115. mage_ai/data_preparation/models/block/dynamic/shared.py +92 -0
  116. mage_ai/data_preparation/models/block/dynamic/utils.py +291 -168
  117. mage_ai/data_preparation/models/block/dynamic/variables.py +384 -144
  118. mage_ai/data_preparation/models/block/dynamic/wrappers.py +77 -0
  119. mage_ai/data_preparation/models/block/extension/utils.py +10 -1
  120. mage_ai/data_preparation/models/block/global_data_product/__init__.py +10 -1
  121. mage_ai/data_preparation/models/block/integration/__init__.py +6 -2
  122. mage_ai/data_preparation/models/block/outputs.py +722 -0
  123. mage_ai/data_preparation/models/block/platform/mixins.py +7 -8
  124. mage_ai/data_preparation/models/block/r/__init__.py +56 -38
  125. mage_ai/data_preparation/models/block/settings/__init__.py +0 -0
  126. mage_ai/data_preparation/models/block/settings/dynamic/__init__.py +0 -0
  127. mage_ai/data_preparation/models/block/settings/dynamic/constants.py +7 -0
  128. mage_ai/data_preparation/models/block/settings/dynamic/mixins.py +118 -0
  129. mage_ai/data_preparation/models/block/settings/dynamic/models.py +31 -0
  130. mage_ai/data_preparation/models/block/settings/global_data_products/__init__.py +0 -0
  131. mage_ai/data_preparation/models/block/settings/global_data_products/mixins.py +20 -0
  132. mage_ai/data_preparation/models/block/settings/global_data_products/models.py +46 -0
  133. mage_ai/data_preparation/models/block/settings/variables/__init__.py +0 -0
  134. mage_ai/data_preparation/models/block/settings/variables/mixins.py +74 -0
  135. mage_ai/data_preparation/models/block/settings/variables/models.py +49 -0
  136. mage_ai/data_preparation/models/block/spark/mixins.py +2 -1
  137. mage_ai/data_preparation/models/block/sql/__init__.py +30 -5
  138. mage_ai/data_preparation/models/block/sql/utils/shared.py +21 -3
  139. mage_ai/data_preparation/models/block/utils.py +127 -70
  140. mage_ai/data_preparation/models/constants.py +19 -14
  141. mage_ai/data_preparation/models/custom_templates/custom_block_template.py +18 -13
  142. mage_ai/data_preparation/models/custom_templates/custom_pipeline_template.py +33 -16
  143. mage_ai/data_preparation/models/custom_templates/utils.py +1 -1
  144. mage_ai/data_preparation/models/file.py +41 -28
  145. mage_ai/data_preparation/models/global_data_product/__init__.py +88 -58
  146. mage_ai/data_preparation/models/global_hooks/models.py +1 -0
  147. mage_ai/data_preparation/models/interfaces.py +29 -0
  148. mage_ai/data_preparation/models/pipeline.py +365 -180
  149. mage_ai/data_preparation/models/pipelines/integration_pipeline.py +1 -2
  150. mage_ai/data_preparation/models/pipelines/seed.py +1 -1
  151. mage_ai/data_preparation/models/project/__init__.py +66 -18
  152. mage_ai/data_preparation/models/project/constants.py +2 -0
  153. mage_ai/data_preparation/models/triggers/__init__.py +120 -24
  154. mage_ai/data_preparation/models/utils.py +467 -17
  155. mage_ai/data_preparation/models/variable.py +1028 -137
  156. mage_ai/data_preparation/models/variables/__init__.py +0 -0
  157. mage_ai/data_preparation/models/variables/cache.py +149 -0
  158. mage_ai/data_preparation/models/variables/constants.py +72 -0
  159. mage_ai/data_preparation/models/variables/summarizer.py +336 -0
  160. mage_ai/data_preparation/models/variables/utils.py +77 -0
  161. mage_ai/data_preparation/models/widget/__init__.py +63 -41
  162. mage_ai/data_preparation/models/widget/charts.py +40 -27
  163. mage_ai/data_preparation/models/widget/constants.py +2 -0
  164. mage_ai/data_preparation/models/widget/utils.py +3 -3
  165. mage_ai/data_preparation/preferences.py +3 -3
  166. mage_ai/data_preparation/repo_manager.py +55 -21
  167. mage_ai/data_preparation/storage/base_storage.py +2 -2
  168. mage_ai/data_preparation/storage/gcs_storage.py +7 -4
  169. mage_ai/data_preparation/storage/local_storage.py +6 -3
  170. mage_ai/data_preparation/storage/s3_storage.py +5 -2
  171. mage_ai/data_preparation/templates/data_exporters/streaming/oracledb.yaml +8 -0
  172. mage_ai/data_preparation/variable_manager.py +281 -76
  173. mage_ai/io/base.py +3 -2
  174. mage_ai/io/bigquery.py +1 -0
  175. mage_ai/io/redshift.py +7 -5
  176. mage_ai/kernels/__init__.py +0 -0
  177. mage_ai/kernels/models.py +188 -0
  178. mage_ai/kernels/utils.py +169 -0
  179. mage_ai/orchestration/concurrency.py +6 -2
  180. mage_ai/orchestration/db/__init__.py +1 -0
  181. mage_ai/orchestration/db/migrations/versions/0227396a216c_add_userproject_table.py +38 -0
  182. mage_ai/orchestration/db/models/dynamic/__init__.py +0 -0
  183. mage_ai/orchestration/db/models/dynamic/controller.py +67 -0
  184. mage_ai/orchestration/db/models/oauth.py +2 -9
  185. mage_ai/orchestration/db/models/projects.py +10 -0
  186. mage_ai/orchestration/db/models/schedules.py +204 -187
  187. mage_ai/orchestration/db/models/schedules_project_platform.py +18 -12
  188. mage_ai/orchestration/db/models/utils.py +46 -5
  189. mage_ai/orchestration/metrics/pipeline_run.py +8 -9
  190. mage_ai/orchestration/notification/sender.py +1 -0
  191. mage_ai/orchestration/pipeline_scheduler_original.py +32 -8
  192. mage_ai/orchestration/pipeline_scheduler_project_platform.py +1 -1
  193. mage_ai/orchestration/run_status_checker.py +11 -4
  194. mage_ai/orchestration/triggers/api.py +12 -1
  195. mage_ai/presenters/charts/data_sources/base.py +4 -2
  196. mage_ai/presenters/charts/data_sources/block.py +15 -9
  197. mage_ai/presenters/charts/data_sources/chart_code.py +8 -5
  198. mage_ai/presenters/charts/data_sources/constants.py +1 -0
  199. mage_ai/presenters/charts/data_sources/system_metrics.py +22 -0
  200. mage_ai/presenters/interactions/models.py +11 -7
  201. mage_ai/presenters/pages/loaders/pipelines.py +5 -3
  202. mage_ai/presenters/pages/models/page_components/pipeline_schedules.py +3 -1
  203. mage_ai/presenters/utils.py +2 -0
  204. mage_ai/server/api/blocks.py +2 -1
  205. mage_ai/server/api/downloads.py +5 -1
  206. mage_ai/server/api/triggers.py +3 -1
  207. mage_ai/server/constants.py +1 -1
  208. mage_ai/server/frontend_dist/404.html +5 -5
  209. mage_ai/server/frontend_dist/_next/static/UZLabyPgcxtZvp0O0EUUS/_buildManifest.js +1 -0
  210. mage_ai/server/frontend_dist/_next/static/chunks/1376-22de38b4ad008d8a.js +1 -0
  211. mage_ai/server/frontend_dist/_next/static/chunks/{1557-b3502f3f1aa92ac7.js → 1557-25a7d985d5564fd3.js} +1 -1
  212. mage_ai/server/frontend_dist/_next/static/chunks/1668-30b4619b9534519b.js +1 -0
  213. mage_ai/server/frontend_dist/_next/static/chunks/1799-c42db95a015689ee.js +1 -0
  214. mage_ai/server/frontend_dist/_next/static/chunks/2996-2108b53b9d371d8d.js +1 -0
  215. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/3763-61b542dafdbf5754.js → frontend_dist/_next/static/chunks/3763-40780c6d1e4b261d.js} +1 -1
  216. mage_ai/server/frontend_dist/_next/static/chunks/3782-129dd2a2448a2e36.js +1 -0
  217. mage_ai/server/frontend_dist/_next/static/chunks/3958-bcdfa414ccfa1eb2.js +1 -0
  218. mage_ai/server/frontend_dist/_next/static/chunks/4168-97fd1578d1a38315.js +1 -0
  219. mage_ai/server/frontend_dist/_next/static/chunks/4982-fa5a238b139fbdd2.js +1 -0
  220. mage_ai/server/frontend_dist/_next/static/chunks/5699-176f445e1313f001.js +1 -0
  221. mage_ai/server/frontend_dist/_next/static/chunks/7162-7dd03f0f605de721.js +1 -0
  222. mage_ai/server/frontend_dist/_next/static/chunks/7779-68d2b72a90c5f925.js +1 -0
  223. mage_ai/server/frontend_dist/_next/static/chunks/7966-5446a8e43711e2f9.js +1 -0
  224. mage_ai/server/frontend_dist/_next/static/chunks/8023-6c2f172f48dcb99b.js +1 -0
  225. mage_ai/server/frontend_dist/_next/static/chunks/8095-c351b8a735d73e0c.js +1 -0
  226. mage_ai/server/frontend_dist/_next/static/chunks/{main-77fe248a6fbd12d8.js → main-b99d4e30a88d9dc7.js} +1 -1
  227. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-9fe2d9d07c94e968.js +1 -0
  228. mage_ai/server/frontend_dist/_next/static/chunks/pages/{block-layout-14f952f66964022f.js → block-layout-7f4b735c67115df5.js} +1 -1
  229. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-e7d48e6b0c3068ac.js +1 -0
  230. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products-b943f31f050fc3a4.js +1 -0
  231. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/overview-597b74828bf105db.js → frontend_dist/_next/static/chunks/pages/overview-9f1ac4ec003884f3.js} +1 -1
  232. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/{[...slug]-7181b086c93784d2.js → [...slug]-7e737f6fc7e83e9b.js} +1 -1
  233. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-d94488e3f2eeef36.js +1 -0
  234. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-cc641a7fa8473796.js +1 -0
  235. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-a5c0362763a21fa8.js → block-runs-284309877f3c5a5a.js} +1 -1
  236. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-26250e5335194ade.js +1 -0
  237. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-7acc7afc00df17c2.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-5f4c8128b2413fd8.js} +1 -1
  238. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-4ebfc8e400315dda.js +1 -0
  239. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-e5e0150a256aadb3.js +1 -0
  240. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/{profile-3f0df3decc856ee9.js → profile-3ae43c932537b254.js} +1 -1
  241. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-32985f3f7c7dd3ab.js → frontend_dist/_next/static/chunks/pages/settings/platform/preferences-b603d7fe4b175256.js} +1 -1
  242. mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-c2e9ef989c8bfa73.js → frontend_dist/_next/static/chunks/pages/settings/platform/settings-319ddbabc239e91b.js} +1 -1
  243. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-47b64ced27c24985.js → [...slug]-5c360f72e4498855.js} +1 -1
  244. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{permissions-e5a4d3d815cec25d.js → permissions-fb29fa6c2bd90bb0.js} +1 -1
  245. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-3b76fa959ffa09d3.js +1 -0
  246. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-379e1ee292504842.js → [...slug]-3b787b42f1093b1f.js} +1 -1
  247. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-0b83fbdd39e85f5b.js +1 -0
  248. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-a1e6950974d643a8.js +1 -0
  249. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-2af9afbe727d88aa.js → [...slug]-0aa019d87db8b0b8.js} +1 -1
  250. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{users-a4db8710f703c729.js → users-88c694d19207f2ec.js} +1 -1
  251. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-31d0d50f7f30462b.js +1 -0
  252. mage_ai/server/frontend_dist/_next/static/chunks/{webpack-d079359c241db804.js → webpack-ac7fdc472bedf682.js} +1 -1
  253. mage_ai/server/frontend_dist/block-layout.html +3 -3
  254. mage_ai/server/frontend_dist/compute.html +6 -6
  255. mage_ai/server/frontend_dist/files.html +6 -6
  256. mage_ai/server/frontend_dist/global-data-products/[...slug].html +6 -6
  257. mage_ai/server/frontend_dist/global-data-products.html +6 -6
  258. mage_ai/server/frontend_dist/global-hooks/[...slug].html +6 -6
  259. mage_ai/server/frontend_dist/global-hooks.html +6 -6
  260. mage_ai/server/frontend_dist/index.html +3 -3
  261. mage_ai/server/frontend_dist/manage/files.html +6 -6
  262. mage_ai/server/frontend_dist/manage/settings.html +6 -6
  263. mage_ai/server/frontend_dist/manage/users/[user].html +6 -6
  264. mage_ai/server/frontend_dist/manage/users/new.html +6 -6
  265. mage_ai/server/frontend_dist/manage/users.html +6 -6
  266. mage_ai/server/frontend_dist/manage.html +6 -6
  267. mage_ai/server/frontend_dist/oauth.html +5 -5
  268. mage_ai/server/frontend_dist/overview.html +6 -6
  269. mage_ai/server/frontend_dist/pipeline-runs.html +6 -6
  270. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +6 -6
  271. mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +6 -6
  272. mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +6 -6
  273. mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +3 -3
  274. mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +6 -6
  275. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +6 -6
  276. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
  277. mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +6 -6
  278. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +6 -6
  279. mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +6 -6
  280. mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +6 -6
  281. mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +6 -6
  282. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +6 -6
  283. mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +6 -6
  284. mage_ai/server/frontend_dist/pipelines/[pipeline].html +3 -3
  285. mage_ai/server/frontend_dist/pipelines.html +6 -6
  286. mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +6 -6
  287. mage_ai/server/frontend_dist/platform/global-hooks.html +6 -6
  288. mage_ai/server/frontend_dist/settings/account/profile.html +6 -6
  289. mage_ai/server/frontend_dist/settings/platform/preferences.html +6 -6
  290. mage_ai/server/frontend_dist/settings/platform/settings.html +6 -6
  291. mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +6 -6
  292. mage_ai/server/frontend_dist/settings/workspace/permissions.html +6 -6
  293. mage_ai/server/frontend_dist/settings/workspace/preferences.html +6 -6
  294. mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +6 -6
  295. mage_ai/server/frontend_dist/settings/workspace/roles.html +6 -6
  296. mage_ai/server/frontend_dist/settings/workspace/sync-data.html +6 -6
  297. mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +6 -6
  298. mage_ai/server/frontend_dist/settings/workspace/users.html +6 -6
  299. mage_ai/server/frontend_dist/settings.html +3 -3
  300. mage_ai/server/frontend_dist/sign-in.html +12 -12
  301. mage_ai/server/frontend_dist/templates/[...slug].html +6 -6
  302. mage_ai/server/frontend_dist/templates.html +6 -6
  303. mage_ai/server/frontend_dist/terminal.html +6 -6
  304. mage_ai/server/frontend_dist/test.html +3 -3
  305. mage_ai/server/frontend_dist/triggers.html +6 -6
  306. mage_ai/server/frontend_dist/version-control.html +6 -6
  307. mage_ai/server/frontend_dist_base_path_template/404.html +5 -5
  308. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1376-22de38b4ad008d8a.js +1 -0
  309. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{1557-b3502f3f1aa92ac7.js → 1557-25a7d985d5564fd3.js} +1 -1
  310. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1668-30b4619b9534519b.js +1 -0
  311. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1799-c42db95a015689ee.js +1 -0
  312. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2996-2108b53b9d371d8d.js +1 -0
  313. mage_ai/server/{frontend_dist/_next/static/chunks/3763-61b542dafdbf5754.js → frontend_dist_base_path_template/_next/static/chunks/3763-40780c6d1e4b261d.js} +1 -1
  314. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-129dd2a2448a2e36.js +1 -0
  315. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3958-bcdfa414ccfa1eb2.js +1 -0
  316. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4168-97fd1578d1a38315.js +1 -0
  317. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4982-fa5a238b139fbdd2.js +1 -0
  318. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-176f445e1313f001.js +1 -0
  319. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7162-7dd03f0f605de721.js +1 -0
  320. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7779-68d2b72a90c5f925.js +1 -0
  321. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-5446a8e43711e2f9.js +1 -0
  322. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8023-6c2f172f48dcb99b.js +1 -0
  323. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-c351b8a735d73e0c.js +1 -0
  324. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{main-70b78159c2bb3fe1.js → main-384298e9133cec76.js} +1 -1
  325. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-13a578bce3b7f30c.js +1 -0
  326. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{block-layout-14f952f66964022f.js → block-layout-7f4b735c67115df5.js} +1 -1
  327. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-e7d48e6b0c3068ac.js +1 -0
  328. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products-b943f31f050fc3a4.js +1 -0
  329. mage_ai/server/{frontend_dist/_next/static/chunks/pages/overview-597b74828bf105db.js → frontend_dist_base_path_template/_next/static/chunks/pages/overview-9f1ac4ec003884f3.js} +1 -1
  330. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/{[...slug]-7181b086c93784d2.js → [...slug]-7e737f6fc7e83e9b.js} +1 -1
  331. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-d94488e3f2eeef36.js +1 -0
  332. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-cc641a7fa8473796.js +1 -0
  333. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-a5c0362763a21fa8.js → block-runs-284309877f3c5a5a.js} +1 -1
  334. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-26250e5335194ade.js +1 -0
  335. mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-7acc7afc00df17c2.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-5f4c8128b2413fd8.js} +1 -1
  336. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-4ebfc8e400315dda.js +1 -0
  337. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-e5e0150a256aadb3.js +1 -0
  338. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/{profile-3f0df3decc856ee9.js → profile-3ae43c932537b254.js} +1 -1
  339. mage_ai/server/{frontend_dist/_next/static/chunks/pages/settings/platform/preferences-32985f3f7c7dd3ab.js → frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-b603d7fe4b175256.js} +1 -1
  340. mage_ai/server/{frontend_dist/_next/static/chunks/pages/settings/platform/settings-c2e9ef989c8bfa73.js → frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-319ddbabc239e91b.js} +1 -1
  341. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-47b64ced27c24985.js → [...slug]-5c360f72e4498855.js} +1 -1
  342. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{permissions-e5a4d3d815cec25d.js → permissions-fb29fa6c2bd90bb0.js} +1 -1
  343. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-3b76fa959ffa09d3.js +1 -0
  344. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-379e1ee292504842.js → [...slug]-3b787b42f1093b1f.js} +1 -1
  345. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-0b83fbdd39e85f5b.js +1 -0
  346. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-a1e6950974d643a8.js +1 -0
  347. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-2af9afbe727d88aa.js → [...slug]-0aa019d87db8b0b8.js} +1 -1
  348. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{users-a4db8710f703c729.js → users-88c694d19207f2ec.js} +1 -1
  349. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-31d0d50f7f30462b.js +1 -0
  350. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-68c003fb6a175cd7.js → webpack-481689d9989710cd.js} +1 -1
  351. mage_ai/server/frontend_dist_base_path_template/_next/static/kcptwoOU-JJJg6Vwpkfmx/_buildManifest.js +1 -0
  352. mage_ai/server/frontend_dist_base_path_template/block-layout.html +3 -3
  353. mage_ai/server/frontend_dist_base_path_template/compute.html +6 -6
  354. mage_ai/server/frontend_dist_base_path_template/files.html +6 -6
  355. mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +6 -6
  356. mage_ai/server/frontend_dist_base_path_template/global-data-products.html +6 -6
  357. mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +6 -6
  358. mage_ai/server/frontend_dist_base_path_template/global-hooks.html +6 -6
  359. mage_ai/server/frontend_dist_base_path_template/index.html +3 -3
  360. mage_ai/server/frontend_dist_base_path_template/manage/files.html +6 -6
  361. mage_ai/server/frontend_dist_base_path_template/manage/settings.html +6 -6
  362. mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +6 -6
  363. mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +6 -6
  364. mage_ai/server/frontend_dist_base_path_template/manage/users.html +6 -6
  365. mage_ai/server/frontend_dist_base_path_template/manage.html +6 -6
  366. mage_ai/server/frontend_dist_base_path_template/oauth.html +5 -5
  367. mage_ai/server/frontend_dist_base_path_template/overview.html +6 -6
  368. mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +6 -6
  369. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +6 -6
  370. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +6 -6
  371. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +6 -6
  372. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +3 -3
  373. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +6 -6
  374. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +6 -6
  375. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
  376. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +6 -6
  377. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +6 -6
  378. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +6 -6
  379. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +6 -6
  380. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +6 -6
  381. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +6 -6
  382. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +6 -6
  383. mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +3 -3
  384. mage_ai/server/frontend_dist_base_path_template/pipelines.html +6 -6
  385. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +6 -6
  386. mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +6 -6
  387. mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +6 -6
  388. mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +6 -6
  389. mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +6 -6
  390. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +6 -6
  391. mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +6 -6
  392. mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +6 -6
  393. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +6 -6
  394. mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +6 -6
  395. mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +6 -6
  396. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +6 -6
  397. mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +6 -6
  398. mage_ai/server/frontend_dist_base_path_template/settings.html +3 -3
  399. mage_ai/server/frontend_dist_base_path_template/sign-in.html +12 -12
  400. mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +6 -6
  401. mage_ai/server/frontend_dist_base_path_template/templates.html +6 -6
  402. mage_ai/server/frontend_dist_base_path_template/terminal.html +6 -6
  403. mage_ai/server/frontend_dist_base_path_template/test.html +3 -3
  404. mage_ai/server/frontend_dist_base_path_template/triggers.html +6 -6
  405. mage_ai/server/frontend_dist_base_path_template/version-control.html +6 -6
  406. mage_ai/server/kernel_output_parser.py +4 -1
  407. mage_ai/server/scheduler_manager.py +9 -0
  408. mage_ai/server/server.py +35 -31
  409. mage_ai/server/utils/custom_output.py +284 -0
  410. mage_ai/server/utils/execute_custom_code.py +245 -0
  411. mage_ai/server/utils/output_display.py +123 -289
  412. mage_ai/server/websocket_server.py +116 -69
  413. mage_ai/services/k8s/config.py +23 -0
  414. mage_ai/services/k8s/job_manager.py +6 -1
  415. mage_ai/services/ssh/aws/emr/utils.py +8 -8
  416. mage_ai/settings/keys/auth.py +1 -0
  417. mage_ai/settings/platform/__init__.py +159 -38
  418. mage_ai/settings/platform/constants.py +5 -0
  419. mage_ai/settings/platform/utils.py +53 -10
  420. mage_ai/settings/repo.py +26 -12
  421. mage_ai/settings/server.py +128 -37
  422. mage_ai/shared/array.py +24 -1
  423. mage_ai/shared/complex.py +45 -0
  424. mage_ai/shared/config.py +2 -1
  425. mage_ai/shared/custom_logger.py +11 -0
  426. mage_ai/shared/dates.py +10 -6
  427. mage_ai/shared/files.py +63 -8
  428. mage_ai/shared/hash.py +33 -9
  429. mage_ai/shared/io.py +9 -5
  430. mage_ai/shared/models.py +82 -24
  431. mage_ai/shared/outputs.py +87 -0
  432. mage_ai/shared/parsers.py +141 -15
  433. mage_ai/shared/path_fixer.py +11 -7
  434. mage_ai/shared/singletons/__init__.py +0 -0
  435. mage_ai/shared/singletons/base.py +47 -0
  436. mage_ai/shared/singletons/memory.py +38 -0
  437. mage_ai/shared/strings.py +34 -1
  438. mage_ai/shared/yaml.py +24 -0
  439. mage_ai/streaming/sinks/oracledb.py +57 -0
  440. mage_ai/streaming/sinks/sink_factory.py +4 -0
  441. mage_ai/system/__init__.py +0 -0
  442. mage_ai/system/constants.py +14 -0
  443. mage_ai/system/memory/__init__.py +0 -0
  444. mage_ai/system/memory/constants.py +1 -0
  445. mage_ai/system/memory/manager.py +174 -0
  446. mage_ai/system/memory/presenters.py +158 -0
  447. mage_ai/system/memory/process.py +216 -0
  448. mage_ai/system/memory/samples.py +13 -0
  449. mage_ai/system/memory/utils.py +656 -0
  450. mage_ai/system/memory/wrappers.py +177 -0
  451. mage_ai/system/models.py +58 -0
  452. mage_ai/system/storage/__init__.py +0 -0
  453. mage_ai/system/storage/utils.py +29 -0
  454. mage_ai/tests/api/endpoints/mixins.py +2 -2
  455. mage_ai/tests/api/endpoints/test_blocks.py +2 -1
  456. mage_ai/tests/api/endpoints/test_custom_designs.py +4 -4
  457. mage_ai/tests/api/endpoints/test_pipeline_runs.py +2 -2
  458. mage_ai/tests/api/endpoints/test_projects.py +2 -1
  459. mage_ai/tests/api/operations/base/test_base.py +27 -27
  460. mage_ai/tests/api/operations/base/test_base_with_user_authentication.py +27 -27
  461. mage_ai/tests/api/operations/base/test_base_with_user_permissions.py +23 -23
  462. mage_ai/tests/api/operations/test_syncs.py +6 -4
  463. mage_ai/tests/api/resources/test_pipeline_resource.py +9 -2
  464. mage_ai/tests/authentication/providers/test_oidc.py +59 -0
  465. mage_ai/tests/base_test.py +2 -2
  466. mage_ai/tests/data/__init__.py +0 -0
  467. mage_ai/tests/data/models/__init__.py +0 -0
  468. mage_ai/tests/data_preparation/executors/test_block_executor.py +23 -16
  469. mage_ai/tests/data_preparation/git/test_git.py +4 -1
  470. mage_ai/tests/data_preparation/models/block/dynamic/test_combos.py +305 -0
  471. mage_ai/tests/data_preparation/models/block/dynamic/test_counter.py +212 -0
  472. mage_ai/tests/data_preparation/models/block/dynamic/test_factory.py +360 -0
  473. mage_ai/tests/data_preparation/models/block/dynamic/test_variables.py +332 -0
  474. mage_ai/tests/data_preparation/models/block/hook/test_hook_block.py +2 -2
  475. mage_ai/tests/data_preparation/models/block/platform/test_mixins.py +1 -1
  476. mage_ai/tests/data_preparation/models/block/sql/utils/test_shared.py +26 -1
  477. mage_ai/tests/data_preparation/models/block/test_global_data_product.py +3 -2
  478. mage_ai/tests/data_preparation/models/custom_templates/test_utils.py +5 -4
  479. mage_ai/tests/data_preparation/models/global_hooks/test_hook.py +3 -0
  480. mage_ai/tests/data_preparation/models/global_hooks/test_predicates.py +9 -3
  481. mage_ai/tests/data_preparation/models/test_block.py +115 -120
  482. mage_ai/tests/data_preparation/models/test_blocks_helper.py +114 -0
  483. mage_ai/tests/data_preparation/models/test_global_data_product.py +41 -24
  484. mage_ai/tests/data_preparation/models/test_pipeline.py +9 -6
  485. mage_ai/tests/data_preparation/models/test_project.py +4 -1
  486. mage_ai/tests/data_preparation/models/test_utils.py +80 -0
  487. mage_ai/tests/data_preparation/models/test_variable.py +242 -69
  488. mage_ai/tests/data_preparation/models/variables/__init__.py +0 -0
  489. mage_ai/tests/data_preparation/models/variables/test_summarizer.py +481 -0
  490. mage_ai/tests/data_preparation/storage/shared/__init__.py +0 -0
  491. mage_ai/tests/data_preparation/test_repo_manager.py +6 -7
  492. mage_ai/tests/data_preparation/test_variable_manager.py +57 -48
  493. mage_ai/tests/factory.py +64 -43
  494. mage_ai/tests/orchestration/db/models/test_schedules.py +3 -3
  495. mage_ai/tests/orchestration/db/models/test_schedules_dynamic_blocks.py +279 -0
  496. mage_ai/tests/orchestration/test_pipeline_scheduler.py +1 -0
  497. mage_ai/tests/orchestration/triggers/test_global_data_product.py +3 -2
  498. mage_ai/tests/orchestration/triggers/test_utils.py +3 -2
  499. mage_ai/tests/services/k8s/test_job_manager.py +18 -0
  500. mage_ai/tests/streaming/sinks/test_oracledb.py +38 -0
  501. mage_ai/tests/test_shared.py +61 -0
  502. mage_ai/usage_statistics/logger.py +7 -2
  503. mage_ai/utils/code.py +33 -19
  504. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/METADATA +5 -2
  505. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/RECORD +513 -417
  506. mage_ai/data_preparation/models/global_data_product/constants.py +0 -6
  507. mage_ai/server/frontend_dist/_next/static/RhDiJSkcjCsh4xxX4BFBk/_buildManifest.js +0 -1
  508. mage_ai/server/frontend_dist/_next/static/chunks/2631-b9f9bea3f1cf906d.js +0 -1
  509. mage_ai/server/frontend_dist/_next/static/chunks/3782-ef4cd4f0b52072d0.js +0 -1
  510. mage_ai/server/frontend_dist/_next/static/chunks/4783-422429203610c318.js +0 -1
  511. mage_ai/server/frontend_dist/_next/static/chunks/5699-6d708c6b2153ea08.js +0 -1
  512. mage_ai/server/frontend_dist/_next/static/chunks/635-0d6b7c8804bcd2dc.js +0 -1
  513. mage_ai/server/frontend_dist/_next/static/chunks/7022-0d52dd8868621fb0.js +0 -1
  514. mage_ai/server/frontend_dist/_next/static/chunks/7361-8a23dd8360593e7a.js +0 -1
  515. mage_ai/server/frontend_dist/_next/static/chunks/7966-b9b85ba10667e654.js +0 -1
  516. mage_ai/server/frontend_dist/_next/static/chunks/8095-bdce03896ef9639a.js +0 -1
  517. mage_ai/server/frontend_dist/_next/static/chunks/8146-6bed4e7401e067e6.js +0 -1
  518. mage_ai/server/frontend_dist/_next/static/chunks/9265-d2a1aaec75ec69b8.js +0 -1
  519. mage_ai/server/frontend_dist/_next/static/chunks/9440-4069842b90d4b801.js +0 -1
  520. mage_ai/server/frontend_dist/_next/static/chunks/9832-67896490f6e8a014.js +0 -1
  521. mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-2a69553d8c6eeb53.js +0 -1
  522. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-591abd392dc50ed4.js +0 -1
  523. mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products-78e8e88f2a757a18.js +0 -1
  524. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-95ffcd3e2b27e567.js +0 -1
  525. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-b645a6d13ab9fe3a.js +0 -1
  526. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-1ed9045b2f1dfd65.js +0 -1
  527. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.js +0 -1
  528. mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +0 -1
  529. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-349af617d05f001b.js +0 -1
  530. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-36fa165a48af586b.js +0 -1
  531. mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-60d01d3887e31136.js +0 -1
  532. mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-3433c8b22e8342aa.js +0 -1
  533. mage_ai/server/frontend_dist_base_path_template/_next/static/TdpLLFome13qvM0gXvpHs/_buildManifest.js +0 -1
  534. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2631-b9f9bea3f1cf906d.js +0 -1
  535. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-ef4cd4f0b52072d0.js +0 -1
  536. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4783-422429203610c318.js +0 -1
  537. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-6d708c6b2153ea08.js +0 -1
  538. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/635-0d6b7c8804bcd2dc.js +0 -1
  539. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-0d52dd8868621fb0.js +0 -1
  540. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-8a23dd8360593e7a.js +0 -1
  541. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-b9b85ba10667e654.js +0 -1
  542. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-bdce03896ef9639a.js +0 -1
  543. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-6bed4e7401e067e6.js +0 -1
  544. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9265-d2a1aaec75ec69b8.js +0 -1
  545. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-4069842b90d4b801.js +0 -1
  546. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9832-67896490f6e8a014.js +0 -1
  547. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-2a69553d8c6eeb53.js +0 -1
  548. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-591abd392dc50ed4.js +0 -1
  549. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products-78e8e88f2a757a18.js +0 -1
  550. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-95ffcd3e2b27e567.js +0 -1
  551. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-b645a6d13ab9fe3a.js +0 -1
  552. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-1ed9045b2f1dfd65.js +0 -1
  553. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.js +0 -1
  554. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +0 -1
  555. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-349af617d05f001b.js +0 -1
  556. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-36fa165a48af586b.js +0 -1
  557. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-60d01d3887e31136.js +0 -1
  558. mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-3433c8b22e8342aa.js +0 -1
  559. mage_ai/shared/memory.py +0 -90
  560. mage_ai/tests/data_preparation/models/block/dynamic/test_dynamic_helpers.py +0 -48
  561. /mage_ai/{tests/data_preparation/shared → ai/utils}/__init__.py +0 -0
  562. /mage_ai/server/frontend_dist/_next/static/{RhDiJSkcjCsh4xxX4BFBk → UZLabyPgcxtZvp0O0EUUS}/_ssgManifest.js +0 -0
  563. /mage_ai/server/frontend_dist_base_path_template/_next/static/{TdpLLFome13qvM0gXvpHs → kcptwoOU-JJJg6Vwpkfmx}/_ssgManifest.js +0 -0
  564. /mage_ai/tests/data_preparation/{shared → storage/shared}/test_secrets.py +0 -0
  565. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/LICENSE +0 -0
  566. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/WHEEL +0 -0
  567. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/entry_points.txt +0 -0
  568. {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/top_level.txt +0 -0
@@ -106,7 +106,7 @@ class BlockWithProjectPlatformInactiveTest(BaseAPIEndpointTest, BlockWithProject
106
106
 
107
107
  with patch(
108
108
  'mage_ai.data_preparation.models.block.File.from_path',
109
- lambda _x: file,
109
+ lambda _x, repo_path=None: file,
110
110
  ):
111
111
  with patch.object(file, 'create_parent_directories') as mock_create_parent_directories:
112
112
  with patch.object(file, 'update_content') as mock_update_content:
@@ -55,7 +55,7 @@ class SQLBlockSharedUtilsTest(DBTestCase):
55
55
  self.assertEqual(extract_create_statement_table_name(text), expected_result)
56
56
 
57
57
  def test_extract_insert_statement_table_names(self):
58
- # Test case 1: Basic test with one INSERT statement
58
+ # Test case 1: Basic test with one INSERT statement and remove comment
59
59
  text = """
60
60
  -- This is a comment
61
61
  INSERT INTO table_name
@@ -79,6 +79,31 @@ class SQLBlockSharedUtilsTest(DBTestCase):
79
79
  expected_result = []
80
80
  self.assertEqual(extract_insert_statement_table_names(text), expected_result)
81
81
 
82
+ # Test case 4: Multiple INSERT statements
83
+ text = """
84
+ INSERT INTO table1 VALUES (1, 'John');
85
+ INSERT INTO table2 VALUES (2, 'Jane');
86
+ """
87
+ expected_result = ["table1", "table2"]
88
+ self.assertEqual(extract_insert_statement_table_names(text), expected_result)
89
+
90
+ # Test case 5: IGNORE INSERT statement
91
+ text = "INSERT IGNORE INTO table3 VALUES (3, 'Alice');"
92
+ expected_result = ["table3"]
93
+ self.assertEqual(extract_insert_statement_table_names(text), expected_result)
94
+
95
+ # Test case 6: case insensitivity
96
+ text = "insert into TABLE5 values (5, 'Eve');"
97
+ expected_result = ["TABLE5"]
98
+ self.assertEqual(extract_insert_statement_table_names(text), expected_result)
99
+
100
+ # Test case 7: Multiple spaces
101
+ text = """
102
+ INSERT INTO table_name VALUES (1, 'John');
103
+ """
104
+ expected_result = ['table_name']
105
+ self.assertEqual(extract_insert_statement_table_names(text), expected_result)
106
+
82
107
  def test_extract_drop_statement_table_names(self):
83
108
  # Test case 1: Basic DROP TABLE statement
84
109
  text = """
@@ -20,7 +20,7 @@ class GlobalDataProductBlockTest(DBTestCase):
20
20
  repo_path=self.repo_path,
21
21
  )
22
22
  except Exception:
23
- self.pipeline = Pipeline.get('test_pipeline')
23
+ self.pipeline = Pipeline.get('test_pipeline', repo_path=self.repo_path)
24
24
 
25
25
  self.block = GlobalDataProductBlock(
26
26
  'GDP',
@@ -42,6 +42,7 @@ class GlobalDataProductBlockTest(DBTestCase):
42
42
  object_uuid=self.pipeline.uuid,
43
43
  outdated_after=dict(months=1),
44
44
  outdated_starting_at=dict(day_of_month=1),
45
+ repo_path=self.repo_path,
45
46
  settings=dict(data_loader=dict(partitions=1)),
46
47
  uuid='mage',
47
48
  )
@@ -50,7 +51,7 @@ class GlobalDataProductBlockTest(DBTestCase):
50
51
  self.repo_path,
51
52
  'global_data_products.yaml',
52
53
  )
53
- self.global_data_product.save(file_path=self.file_path)
54
+ self.global_data_product.save()
54
55
 
55
56
  def tearDown(self):
56
57
  super().tearDown()
@@ -1,10 +1,11 @@
1
1
  from unittest.mock import patch
2
2
 
3
-
4
3
  from mage_ai.data_preparation.models.custom_templates.custom_block_template import (
5
4
  CustomBlockTemplate,
6
5
  )
7
- from mage_ai.data_preparation.models.custom_templates.utils import group_and_hydrate_files
6
+ from mage_ai.data_preparation.models.custom_templates.utils import (
7
+ group_and_hydrate_files,
8
+ )
8
9
  from mage_ai.shared.array import find
9
10
  from mage_ai.tests.base_test import DBTestCase
10
11
 
@@ -20,8 +21,8 @@ class CustomTemplatesUtilsTest(DBTestCase):
20
21
  dict(parent_names=['mage', 'fire']),
21
22
  ]
22
23
 
23
- def load(template_uuid: str):
24
- return CustomBlockTemplate(template_uuid=template_uuid)
24
+ def load(repo_path: str, template_uuid: str):
25
+ return CustomBlockTemplate(repo_path=repo_path, template_uuid=template_uuid)
25
26
 
26
27
  with patch.object(
27
28
  CustomBlockTemplate,
@@ -334,6 +334,7 @@ class HookTest(GlobalHooksMixin):
334
334
 
335
335
  mock_trigger_pipeline.assert_called_once_with(
336
336
  hook.pipeline.uuid,
337
+ repo_path=self.repo_path,
337
338
  variables=merge_dict(variables, kwargs),
338
339
  check_status=True,
339
340
  error_on_failure=True,
@@ -381,6 +382,7 @@ class HookTest(GlobalHooksMixin):
381
382
 
382
383
  mock_trigger_pipeline.assert_called_once_with(
383
384
  hook.pipeline.uuid,
385
+ repo_path=self.repo_path,
384
386
  variables=merge_dict(variables, kwargs),
385
387
  check_status=False,
386
388
  error_on_failure=True,
@@ -426,6 +428,7 @@ class HookTest(GlobalHooksMixin):
426
428
 
427
429
  mock_trigger_pipeline.assert_called_once_with(
428
430
  hook.pipeline.uuid,
431
+ repo_path=self.repo_path,
429
432
  variables=merge_dict(variables, dict(hook=kwargs['hook'], project=None)),
430
433
  check_status=True,
431
434
  error_on_failure=True,
@@ -18,6 +18,7 @@ from mage_ai.data_preparation.models.global_hooks.predicates import (
18
18
  PredicateValueType,
19
19
  )
20
20
  from mage_ai.data_preparation.models.pipeline import Pipeline
21
+ from mage_ai.settings.repo import get_repo_path
21
22
  from mage_ai.shared.array import find
22
23
  from mage_ai.shared.hash import dig, ignore_keys, merge_dict, set_value
23
24
  from mage_ai.tests.base_test import AsyncDBTestCase
@@ -39,6 +40,7 @@ def build_operation_resource_settings(
39
40
  first_object_key=first_object_key,
40
41
  repo_path: str = None,
41
42
  ) -> Dict:
43
+ repo_path = repo_path or get_repo_path()
42
44
  settings = {
43
45
  BaseResource.__name__: dict(
44
46
  right_object_keys=[first_object_key],
@@ -62,9 +64,13 @@ def build_operation_resource_settings(
62
64
  ),
63
65
  Pipeline.__name__: dict(
64
66
  right_object_keys=['variables', first_object_key],
65
- operation_resource=Pipeline(uuid.uuid4().hex, config=dict(variables={
66
- first_object_key: right_value,
67
- })),
67
+ operation_resource=Pipeline(
68
+ uuid.uuid4().hex,
69
+ config=dict(variables={
70
+ first_object_key: right_value,
71
+ }),
72
+ repo_path=repo_path,
73
+ ),
68
74
  ),
69
75
  }
70
76
 
@@ -26,14 +26,18 @@ class BlockTest(DBTestCase):
26
26
  def test_create(self):
27
27
  block1 = Block.create('test_transformer', 'transformer', self.repo_path)
28
28
  block2 = Block.create('test data loader', BlockType.DATA_LOADER, self.repo_path)
29
- self.assertTrue(os.path.exists(os.path.join(
30
- self.repo_path, 'transformers', 'test_transformer.py')))
31
- self.assertTrue(os.path.exists(os.path.join(
32
- self.repo_path, 'transformers', '__init__.py')))
33
- self.assertTrue(os.path.exists(os.path.join(
34
- self.repo_path, 'data_loaders', 'test_data_loader.py')))
35
- self.assertTrue(os.path.exists(os.path.join(
36
- self.repo_path, 'data_loaders', '__init__.py')))
29
+ self.assertTrue(
30
+ os.path.exists(os.path.join(self.repo_path, 'transformers', 'test_transformer.py'))
31
+ )
32
+ self.assertTrue(
33
+ os.path.exists(os.path.join(self.repo_path, 'transformers', '__init__.py'))
34
+ )
35
+ self.assertTrue(
36
+ os.path.exists(os.path.join(self.repo_path, 'data_loaders', 'test_data_loader.py'))
37
+ )
38
+ self.assertTrue(
39
+ os.path.exists(os.path.join(self.repo_path, 'data_loaders', '__init__.py'))
40
+ )
37
41
  self.assertEqual(block1.name, 'test_transformer')
38
42
  self.assertEqual(block1.uuid, 'test_transformer')
39
43
  self.assertEqual(block1.type, 'transformer')
@@ -55,20 +59,20 @@ class BlockTest(DBTestCase):
55
59
  upstream_block_uuids=['test_data_loader'],
56
60
  )
57
61
  with open(block1.file_path, 'w') as file:
58
- file.write('''import pandas as pd
62
+ file.write("""import pandas as pd
59
63
  @data_loader
60
64
  def load_data():
61
65
  data = {'col1': [1, 1, 3], 'col2': [2, 2, 4]}
62
66
  df = pd.DataFrame(data)
63
67
  return [df]
64
- ''')
68
+ """)
65
69
  with open(block2.file_path, 'w') as file:
66
- file.write('''import pandas as pd
70
+ file.write("""import pandas as pd
67
71
  @transformer
68
72
  def remove_duplicate_rows(df):
69
73
  df_transformed = df.drop_duplicates()
70
74
  return [df_transformed]
71
- ''')
75
+ """)
72
76
  asyncio.run(block1.execute(analyze_outputs=True))
73
77
  asyncio.run(block2.execute(analyze_outputs=True))
74
78
 
@@ -76,10 +80,7 @@ def remove_duplicate_rows(df):
76
80
  variables_dir=get_repo_config(self.repo_path).variables_dir,
77
81
  )
78
82
  data = variable_manager.get_variable(
79
- pipeline.uuid,
80
- block2.uuid,
81
- 'output_0',
82
- variable_type='dataframe'
83
+ pipeline.uuid, block2.uuid, 'output_0', variable_type='dataframe'
83
84
  )
84
85
  # analysis = variable_manager.get_variable(
85
86
  # pipeline.uuid,
@@ -111,7 +112,7 @@ def remove_duplicate_rows(df):
111
112
  upstream_block_uuids=['test_data_loader'],
112
113
  )
113
114
  with open(block1.file_path, 'w') as file:
114
- file.write('''import pandas as pd
115
+ file.write("""import pandas as pd
115
116
  @preprocesser
116
117
  def preprocesser0(*args, **kwargs):
117
118
  kwargs['context']['count'] = 1
@@ -129,14 +130,14 @@ def load_data(**kwargs):
129
130
  data = {'col1': [i * count for i in [1, 1, 3]], 'col2': [i * count for i in [2, 2, 4]]}
130
131
  df = pd.DataFrame(data)
131
132
  return [df]
132
- ''')
133
+ """)
133
134
  with open(block2.file_path, 'w') as file:
134
- file.write('''import pandas as pd
135
+ file.write("""import pandas as pd
135
136
  @transformer
136
137
  def remove_duplicate_rows(df):
137
138
  df_transformed = df.drop_duplicates()
138
139
  return [df_transformed]
139
- ''')
140
+ """)
140
141
  asyncio.run(block1.execute())
141
142
  asyncio.run(block2.execute())
142
143
 
@@ -144,10 +145,7 @@ def remove_duplicate_rows(df):
144
145
  variables_dir=get_repo_config(self.repo_path).variables_dir,
145
146
  )
146
147
  data = variable_manager.get_variable(
147
- pipeline.uuid,
148
- block2.uuid,
149
- 'output_0',
150
- variable_type='dataframe'
148
+ pipeline.uuid, block2.uuid, 'output_0', variable_type='dataframe'
151
149
  )
152
150
 
153
151
  df_final = pd.DataFrame({'col1': [2, 2, 6], 'col2': [4, 4, 8]}).drop_duplicates()
@@ -172,7 +170,7 @@ def remove_duplicate_rows(df):
172
170
  upstream_block_uuids=['test_data_loader_2'],
173
171
  )
174
172
  with open(block1.file_path, 'w') as file:
175
- file.write('''import pandas as pd
173
+ file.write("""import pandas as pd
176
174
  @data_loader
177
175
  def load_data():
178
176
  data = {
@@ -183,14 +181,14 @@ def load_data():
183
181
  }
184
182
  df = pd.DataFrame(data)
185
183
  return [df]
186
- ''')
184
+ """)
187
185
  with open(block2.file_path, 'w') as file:
188
- file.write('''import pandas as pd
186
+ file.write("""import pandas as pd
189
187
  @transformer
190
188
  def remove_duplicate_rows(df):
191
189
  df_transformed = df
192
190
  return [df_transformed]
193
- ''')
191
+ """)
194
192
  asyncio.run(block1.execute())
195
193
  asyncio.run(block2.execute())
196
194
 
@@ -198,10 +196,7 @@ def remove_duplicate_rows(df):
198
196
  variables_dir=get_repo_config(self.repo_path).variables_dir,
199
197
  )
200
198
  data = variable_manager.get_variable(
201
- pipeline.uuid,
202
- block2.uuid,
203
- 'output_0',
204
- variable_type='dataframe'
199
+ pipeline.uuid, block2.uuid, 'output_0', variable_type='dataframe'
205
200
  )
206
201
  df_final = pd.DataFrame({
207
202
  'col1': [1, 1, 3],
@@ -236,28 +231,28 @@ def remove_duplicate_rows(df):
236
231
  upstream_block_uuids=['test_data_loader_1', 'test_data_loader_2'],
237
232
  )
238
233
  with open(block1.file_path, 'w') as file:
239
- file.write('''import pandas as pd
234
+ file.write("""import pandas as pd
240
235
  @data_loader
241
236
  def load_data():
242
237
  data = {'col1': [1, 3], 'col2': [2, 4]}
243
238
  df = pd.DataFrame(data)
244
239
  return [df]
245
- ''')
240
+ """)
246
241
  with open(block2.file_path, 'w') as file:
247
- file.write('''import pandas as pd
242
+ file.write("""import pandas as pd
248
243
  @data_loader
249
244
  def load_data():
250
245
  data = {'col1': [5], 'col2': [6]}
251
246
  df = pd.DataFrame(data)
252
247
  return [df]
253
- ''')
248
+ """)
254
249
  with open(block3.file_path, 'w') as file:
255
- file.write('''import pandas as pd
250
+ file.write("""import pandas as pd
256
251
  @transformer
257
252
  def union_datasets(df1, df2):
258
253
  df_union = pd.concat([df1, df2]).reset_index(drop=True)
259
254
  return [df_union]
260
- ''')
255
+ """)
261
256
  asyncio.run(block1.execute(analyze_outputs=True))
262
257
  asyncio.run(block2.execute(analyze_outputs=True))
263
258
  asyncio.run(block3.execute(analyze_outputs=True))
@@ -266,10 +261,7 @@ def union_datasets(df1, df2):
266
261
  variables_dir=get_repo_config(self.repo_path).variables_dir,
267
262
  )
268
263
  data = variable_manager.get_variable(
269
- pipeline.uuid,
270
- block3.uuid,
271
- 'output_0',
272
- variable_type='dataframe'
264
+ pipeline.uuid, block3.uuid, 'output_0', variable_type='dataframe'
273
265
  )
274
266
  analysis = variable_manager.get_variable(
275
267
  pipeline.uuid,
@@ -319,48 +311,48 @@ def union_datasets(df1, df2):
319
311
  upstream_block_uuids=['test_data_loader_1', 'test_data_loader_2'],
320
312
  )
321
313
  with open(block1.file_path, 'w') as file:
322
- file.write('''import pandas as pd
314
+ file.write("""import pandas as pd
323
315
  @data_loader
324
316
  def load_data():
325
317
  data = {'col1': [1, 3], 'col2': [2, 4]}
326
318
  df = pd.DataFrame(data)
327
319
  return [df]
328
- ''')
320
+ """)
329
321
  with open(block2.file_path, 'w') as file:
330
- file.write('''import pandas as pd
322
+ file.write("""import pandas as pd
331
323
  @data_loader
332
324
  def load_data():
333
325
  data = {'col1': [5], 'col2': [6]}
334
326
  df = pd.DataFrame(data)
335
327
  return [df]
336
- ''')
328
+ """)
337
329
  with open(block3.file_path, 'w') as file:
338
- file.write('''import pandas as pd
330
+ file.write("""import pandas as pd
339
331
  @transformer
340
332
  def incorrect_function(df1):
341
333
  return df1
342
- ''')
334
+ """)
343
335
  asyncio.run(block1.execute())
344
336
  asyncio.run(block2.execute())
345
337
  with self.assertRaisesRegex(
346
338
  Exception,
347
- 'Block test_transformer may have too many upstream dependencies. It expected to have' +
348
- ' 1 arguments, but received 2. Confirm that the @transformer method declaration has ' +
349
- 'the correct number of arguments.'
339
+ 'Block test_transformer may have too many upstream dependencies. It expected to have'
340
+ + ' 1 arguments, but received 2. Confirm that the @transformer method declaration has '
341
+ + 'the correct number of arguments.',
350
342
  ):
351
343
  asyncio.run(block3.execute())
352
344
 
353
345
  with open(block3.file_path, 'w') as file:
354
- file.write('''import pandas as pd
346
+ file.write("""import pandas as pd
355
347
  @transformer
356
348
  def incorrect_function(df1, df2, df3):
357
349
  return df1
358
- ''')
350
+ """)
359
351
  with self.assertRaisesRegex(
360
352
  Exception,
361
- 'Block test_transformer may have too many upstream dependencies. It expected to have' +
362
- ' 1 arguments, but received 2. Confirm that the @transformer method declaration has ' +
363
- 'the correct number of arguments.'
353
+ 'Block test_transformer may have too many upstream dependencies. It expected to have'
354
+ + ' 1 arguments, but received 2. Confirm that the @transformer method declaration has '
355
+ + 'the correct number of arguments.',
364
356
  ):
365
357
  asyncio.run(block3.execute())
366
358
 
@@ -384,20 +376,20 @@ def incorrect_function(df1, df2, df3):
384
376
  block2.upstream_blocks = [block1]
385
377
  block1.downstream_blocks = [block2]
386
378
  with open(block1.file_path, 'w') as file:
387
- file.write('''import pandas as pd
379
+ file.write("""import pandas as pd
388
380
  @data_loader
389
381
  def load_data():
390
382
  data = {'col1': [1, 3], 'col2': [2, 4]}
391
383
  df = pd.DataFrame(data)
392
384
  return [df]
393
- ''')
385
+ """)
394
386
  with open(block2.file_path, 'w') as file:
395
- file.write('''import pandas as pd
387
+ file.write("""import pandas as pd
396
388
  @sensor
397
389
  def sensor(*args):
398
390
  df = args[0]
399
391
  return df is not None
400
- ''')
392
+ """)
401
393
  asyncio.run(block1.execute())
402
394
  output = block2.execute_sync(from_notebook=True)
403
395
  self.assertEqual(output['output'][0], True)
@@ -415,20 +407,20 @@ def sensor(*args):
415
407
  pipeline=pipeline,
416
408
  )
417
409
  with open(block1.file_path, 'w') as file:
418
- file.write('''import pandas as pd
410
+ file.write("""import pandas as pd
419
411
  @data_loader
420
412
  def load_data():
421
413
  data = {'col1': [1, 3], 'col2': [2, 4]}
422
414
  df = pd.DataFrame(data)
423
415
  return [df]
424
- ''')
416
+ """)
425
417
  block1.update(dict(has_callback=True))
426
418
  with open(block1.callback_block.file_path, 'w') as file:
427
- file.write('''
419
+ file.write("""
428
420
  @on_success
429
421
  def on_success_callback(**kwargs):
430
422
  print('SUCCESS')
431
- ''')
423
+ """)
432
424
  block1.execute_with_callback()
433
425
  mock_print.assert_called_with('SUCCESS')
434
426
 
@@ -445,18 +437,18 @@ def on_success_callback(**kwargs):
445
437
  pipeline=pipeline,
446
438
  )
447
439
  with open(block1.file_path, 'w') as file:
448
- file.write('''import pandas as pd
440
+ file.write("""import pandas as pd
449
441
  @data_loader
450
442
  def load_data():
451
443
  raise Exception('failed')
452
- ''')
444
+ """)
453
445
  block1.update(dict(has_callback=True))
454
446
  with open(block1.callback_block.file_path, 'w') as file:
455
- file.write('''
447
+ file.write("""
456
448
  @on_failure
457
449
  def on_failure_callback(**kwargs):
458
450
  print('FAILED')
459
- ''')
451
+ """)
460
452
 
461
453
  with self.assertRaisesRegex(Exception, 'failed'):
462
454
  block1.execute_with_callback()
@@ -477,40 +469,46 @@ def on_failure_callback(**kwargs):
477
469
  )
478
470
  block2.upstream_blocks = [block1]
479
471
  block1.downstream_blocks = [block2]
480
- self.assertEqual(block1.to_dict(), dict(
481
- all_upstream_blocks_executed=True,
482
- color=None,
483
- configuration={},
484
- downstream_blocks=['test_data_exporter'],
485
- executor_config=None,
486
- executor_type='local_python',
487
- has_callback=False,
488
- language='sql',
489
- name='test_transformer_2',
490
- retry_config=None,
491
- status='not_executed',
492
- timeout=None,
493
- type='transformer',
494
- upstream_blocks=[],
495
- uuid='test_transformer_2',
496
- ))
497
- self.assertEqual(block2.to_dict(), dict(
498
- all_upstream_blocks_executed=False,
499
- color=None,
500
- configuration={},
501
- downstream_blocks=[],
502
- executor_config=None,
503
- executor_type='local_python',
504
- has_callback=False,
505
- language='python',
506
- name='test_data_exporter',
507
- retry_config=None,
508
- status='not_executed',
509
- timeout=None,
510
- type='data_exporter',
511
- upstream_blocks=['test_transformer_2'],
512
- uuid='test_data_exporter',
513
- ))
472
+ self.assertEqual(
473
+ block1.to_dict(),
474
+ dict(
475
+ all_upstream_blocks_executed=True,
476
+ color=None,
477
+ configuration={},
478
+ downstream_blocks=['test_data_exporter'],
479
+ executor_config=None,
480
+ executor_type='local_python',
481
+ has_callback=False,
482
+ language='sql',
483
+ name='test_transformer_2',
484
+ retry_config=None,
485
+ status='not_executed',
486
+ timeout=None,
487
+ type='transformer',
488
+ upstream_blocks=[],
489
+ uuid='test_transformer_2',
490
+ ),
491
+ )
492
+ self.assertEqual(
493
+ block2.to_dict(),
494
+ dict(
495
+ all_upstream_blocks_executed=False,
496
+ color=None,
497
+ configuration={},
498
+ downstream_blocks=[],
499
+ executor_config=None,
500
+ executor_type='local_python',
501
+ has_callback=False,
502
+ language='python',
503
+ name='test_data_exporter',
504
+ retry_config=None,
505
+ status='not_executed',
506
+ timeout=None,
507
+ type='data_exporter',
508
+ upstream_blocks=['test_transformer_2'],
509
+ uuid='test_data_exporter',
510
+ ),
511
+ )
514
512
 
515
513
  def test_full_table_name(self):
516
514
  faker = Faker()
@@ -518,7 +516,7 @@ def on_failure_callback(**kwargs):
518
516
  block = Block.create(faker.name(), 'data_loader', self.repo_path, pipeline=pipeline)
519
517
 
520
518
  def get_block():
521
- return Pipeline.get(pipeline.uuid).get_block(block.uuid)
519
+ return Pipeline.get(pipeline.uuid, repo_path=self.repo_path).get_block(block.uuid)
522
520
 
523
521
  with open(block.file_path, 'w') as file:
524
522
  file.write('')
@@ -614,7 +612,7 @@ SELECT 1 AS id;
614
612
 
615
613
  test_block.delete(force=True)
616
614
 
617
- pipeline = Pipeline.get('test_pipeline_delete_force')
615
+ pipeline = Pipeline.get('test_pipeline_delete_force', repo_path=self.repo_path)
618
616
  self.assertIsNone(pipeline.get_block('test_data_loader'))
619
617
 
620
618
  block2 = pipeline.get_block('test_transformer')
@@ -732,19 +730,20 @@ def test_output(output, *args) -> None:
732
730
  columns=['id', 'email', 'zip_code'],
733
731
  )
734
732
 
735
- block.store_variables({
736
- 'output_sample_data_stream1': df
737
- })
733
+ block.store_variables({'output_sample_data_stream1': df})
738
734
  output_variables = block.output_variables()
739
735
  self.assertTrue('output_sample_data_stream1' in output_variables)
740
736
 
741
737
  def test_file_path(self):
742
738
  block = Block.create('test_transformer', 'transformer', self.repo_path)
743
- self.assertEqual(block.file_path, os.path.join(
744
- self.repo_path,
745
- 'transformers',
746
- f'{block.uuid}.py',
747
- ))
739
+ self.assertEqual(
740
+ block.file_path,
741
+ os.path.join(
742
+ self.repo_path,
743
+ 'transformers',
744
+ f'{block.uuid}.py',
745
+ ),
746
+ )
748
747
 
749
748
 
750
749
  class BlockProjectPlatformTests(ProjectPlatformMixin):
@@ -763,7 +762,7 @@ class BlockProjectPlatformTests(ProjectPlatformMixin):
763
762
  'test_transformer',
764
763
  'transformer',
765
764
  self.repo_path,
766
- configuration=dict(file_source=dict(path=path))
765
+ configuration=dict(file_source=dict(path=path)),
767
766
  )
768
767
 
769
768
  self.assertEqual(block.file_path, add_root_repo_path_to_relative_path(path))
@@ -783,14 +782,10 @@ class CallbackBlockTest(DBTestCase):
783
782
  self.repo_path,
784
783
  pipeline=self.pipeline,
785
784
  )
786
- callback_block = CallbackBlock.create(parent_block.name)
785
+ callback_block = CallbackBlock.create(parent_block.name, self.repo_path)
787
786
  self.pipeline.add_block(callback_block)
788
- parent_block = parent_block.update(
789
- dict(callback_blocks=[callback_block.uuid])
790
- )
791
- parent_block.global_vars = dict(
792
- configuration=dict(table_name='load_data_table')
793
- )
787
+ parent_block = parent_block.update(dict(callback_blocks=[callback_block.uuid]))
788
+ parent_block.global_vars = dict(configuration=dict(table_name='load_data_table'))
794
789
 
795
790
  global_vars = dict(
796
791
  random_var=1,