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.
- mage_ai/ai/utils/xgboost.py +222 -0
- mage_ai/api/errors.py +37 -25
- mage_ai/api/operations/base.py +13 -1
- mage_ai/api/parsers/PipelineScheduleParser.py +1 -1
- mage_ai/api/policies/BlockOutputPolicy.py +40 -17
- mage_ai/api/policies/GlobalDataProductPolicy.py +91 -41
- mage_ai/api/policies/KernelPolicy.py +55 -32
- mage_ai/api/policies/KernelProcessPolicy.py +56 -0
- mage_ai/api/policies/OutputPolicy.py +73 -41
- mage_ai/api/policies/PipelinePolicy.py +206 -138
- mage_ai/api/presenters/BlockLayoutItemPresenter.py +9 -7
- mage_ai/api/presenters/BlockPresenter.py +1 -1
- mage_ai/api/presenters/GlobalDataProductPresenter.py +6 -1
- mage_ai/api/presenters/KernelPresenter.py +5 -26
- mage_ai/api/presenters/KernelProcessPresenter.py +28 -0
- mage_ai/api/presenters/PipelinePresenter.py +18 -5
- mage_ai/api/presenters/StatusPresenter.py +2 -0
- mage_ai/api/presenters/SyncPresenter.py +25 -0
- mage_ai/api/resources/AutocompleteItemResource.py +1 -1
- mage_ai/api/resources/BlockLayoutItemResource.py +90 -44
- mage_ai/api/resources/BlockOutputResource.py +42 -9
- mage_ai/api/resources/BlockResource.py +4 -3
- mage_ai/api/resources/BlockRunResource.py +27 -22
- mage_ai/api/resources/ClusterResource.py +4 -1
- mage_ai/api/resources/CustomTemplateResource.py +34 -14
- mage_ai/api/resources/DataProviderResource.py +1 -1
- mage_ai/api/resources/ExecutionStateResource.py +3 -1
- mage_ai/api/resources/FileContentResource.py +8 -2
- mage_ai/api/resources/FileResource.py +10 -4
- mage_ai/api/resources/FileVersionResource.py +3 -1
- mage_ai/api/resources/GitBranchResource.py +46 -9
- mage_ai/api/resources/GlobalDataProductResource.py +44 -7
- mage_ai/api/resources/GlobalHookResource.py +4 -1
- mage_ai/api/resources/IntegrationDestinationResource.py +6 -2
- mage_ai/api/resources/IntegrationSourceResource.py +8 -4
- mage_ai/api/resources/IntegrationSourceStreamResource.py +6 -2
- mage_ai/api/resources/KernelProcessResource.py +44 -0
- mage_ai/api/resources/KernelResource.py +25 -3
- mage_ai/api/resources/OutputResource.py +33 -11
- mage_ai/api/resources/PageBlockLayoutResource.py +34 -23
- mage_ai/api/resources/PipelineInteractionResource.py +31 -15
- mage_ai/api/resources/PipelineResource.py +250 -123
- mage_ai/api/resources/PipelineRunResource.py +11 -3
- mage_ai/api/resources/PipelineScheduleResource.py +7 -2
- mage_ai/api/resources/PipelineTriggerResource.py +6 -1
- mage_ai/api/resources/ProjectResource.py +18 -7
- mage_ai/api/resources/SecretResource.py +1 -1
- mage_ai/api/resources/SeedResource.py +8 -1
- mage_ai/api/resources/StatusResource.py +21 -6
- mage_ai/api/resources/SyncResource.py +6 -8
- mage_ai/api/resources/VariableResource.py +46 -26
- mage_ai/api/resources/VersionControlProjectResource.py +9 -2
- mage_ai/api/resources/WidgetResource.py +1 -1
- mage_ai/api/resources/WorkspaceResource.py +1 -1
- mage_ai/api/views.py +47 -40
- mage_ai/authentication/permissions/seed.py +16 -2
- mage_ai/authentication/providers/oidc.py +21 -1
- mage_ai/autocomplete/utils.py +13 -9
- mage_ai/cache/base.py +1 -1
- mage_ai/cache/block.py +18 -12
- mage_ai/cache/block_action_object/__init__.py +32 -4
- mage_ai/cache/file.py +22 -19
- mage_ai/cache/pipeline.py +18 -12
- mage_ai/cli/main.py +1 -0
- mage_ai/cluster_manager/aws/emr_cluster_manager.py +9 -5
- mage_ai/cluster_manager/config.py +2 -2
- mage_ai/cluster_manager/manage.py +1 -1
- mage_ai/cluster_manager/workspace/base.py +1 -1
- mage_ai/command_center/applications/factory.py +10 -7
- mage_ai/command_center/files/factory.py +17 -15
- mage_ai/command_center/utils.py +25 -13
- mage_ai/data/__init__.py +0 -0
- mage_ai/data/constants.py +45 -0
- mage_ai/data/models/__init__.py +0 -0
- mage_ai/data/models/base.py +119 -0
- mage_ai/data/models/constants.py +1 -0
- mage_ai/data/models/generator.py +115 -0
- mage_ai/data/models/manager.py +168 -0
- mage_ai/data/models/pyarrow/__init__.py +0 -0
- mage_ai/data/models/pyarrow/record_batch.py +55 -0
- mage_ai/data/models/pyarrow/shared.py +21 -0
- mage_ai/data/models/pyarrow/table.py +8 -0
- mage_ai/data/models/reader.py +103 -0
- mage_ai/data/models/utils.py +59 -0
- mage_ai/data/models/writer.py +91 -0
- mage_ai/data/tabular/__init__.py +0 -0
- mage_ai/data/tabular/constants.py +23 -0
- mage_ai/data/tabular/mocks.py +19 -0
- mage_ai/data/tabular/models.py +126 -0
- mage_ai/data/tabular/reader.py +602 -0
- mage_ai/data/tabular/utils.py +102 -0
- mage_ai/data/tabular/writer.py +266 -0
- mage_ai/data/variables/__init__.py +0 -0
- mage_ai/data/variables/wrapper.py +54 -0
- mage_ai/data_cleaner/analysis/charts.py +61 -39
- mage_ai/data_cleaner/column_types/column_type_detector.py +53 -31
- mage_ai/data_cleaner/estimators/encoders.py +5 -2
- mage_ai/data_integrations/utils/scheduler.py +16 -11
- mage_ai/data_preparation/decorators.py +1 -0
- mage_ai/data_preparation/executors/block_executor.py +237 -155
- mage_ai/data_preparation/executors/streaming_pipeline_executor.py +1 -1
- mage_ai/data_preparation/git/__init__.py +27 -7
- mage_ai/data_preparation/git/api.py +7 -1
- mage_ai/data_preparation/git/utils.py +22 -16
- mage_ai/data_preparation/logging/logger_manager.py +4 -3
- mage_ai/data_preparation/models/block/__init__.py +1542 -878
- mage_ai/data_preparation/models/block/data_integration/mixins.py +4 -3
- mage_ai/data_preparation/models/block/dynamic/__init__.py +17 -6
- mage_ai/data_preparation/models/block/dynamic/child.py +41 -102
- mage_ai/data_preparation/models/block/dynamic/constants.py +1 -0
- mage_ai/data_preparation/models/block/dynamic/counter.py +296 -0
- mage_ai/data_preparation/models/block/dynamic/data.py +16 -0
- mage_ai/data_preparation/models/block/dynamic/factory.py +163 -0
- mage_ai/data_preparation/models/block/dynamic/models.py +19 -0
- mage_ai/data_preparation/models/block/dynamic/shared.py +92 -0
- mage_ai/data_preparation/models/block/dynamic/utils.py +291 -168
- mage_ai/data_preparation/models/block/dynamic/variables.py +384 -144
- mage_ai/data_preparation/models/block/dynamic/wrappers.py +77 -0
- mage_ai/data_preparation/models/block/extension/utils.py +10 -1
- mage_ai/data_preparation/models/block/global_data_product/__init__.py +10 -1
- mage_ai/data_preparation/models/block/integration/__init__.py +6 -2
- mage_ai/data_preparation/models/block/outputs.py +722 -0
- mage_ai/data_preparation/models/block/platform/mixins.py +7 -8
- mage_ai/data_preparation/models/block/r/__init__.py +56 -38
- mage_ai/data_preparation/models/block/settings/__init__.py +0 -0
- mage_ai/data_preparation/models/block/settings/dynamic/__init__.py +0 -0
- mage_ai/data_preparation/models/block/settings/dynamic/constants.py +7 -0
- mage_ai/data_preparation/models/block/settings/dynamic/mixins.py +118 -0
- mage_ai/data_preparation/models/block/settings/dynamic/models.py +31 -0
- mage_ai/data_preparation/models/block/settings/global_data_products/__init__.py +0 -0
- mage_ai/data_preparation/models/block/settings/global_data_products/mixins.py +20 -0
- mage_ai/data_preparation/models/block/settings/global_data_products/models.py +46 -0
- mage_ai/data_preparation/models/block/settings/variables/__init__.py +0 -0
- mage_ai/data_preparation/models/block/settings/variables/mixins.py +74 -0
- mage_ai/data_preparation/models/block/settings/variables/models.py +49 -0
- mage_ai/data_preparation/models/block/spark/mixins.py +2 -1
- mage_ai/data_preparation/models/block/sql/__init__.py +30 -5
- mage_ai/data_preparation/models/block/sql/utils/shared.py +21 -3
- mage_ai/data_preparation/models/block/utils.py +127 -70
- mage_ai/data_preparation/models/constants.py +19 -14
- mage_ai/data_preparation/models/custom_templates/custom_block_template.py +18 -13
- mage_ai/data_preparation/models/custom_templates/custom_pipeline_template.py +33 -16
- mage_ai/data_preparation/models/custom_templates/utils.py +1 -1
- mage_ai/data_preparation/models/file.py +41 -28
- mage_ai/data_preparation/models/global_data_product/__init__.py +88 -58
- mage_ai/data_preparation/models/global_hooks/models.py +1 -0
- mage_ai/data_preparation/models/interfaces.py +29 -0
- mage_ai/data_preparation/models/pipeline.py +365 -180
- mage_ai/data_preparation/models/pipelines/integration_pipeline.py +1 -2
- mage_ai/data_preparation/models/pipelines/seed.py +1 -1
- mage_ai/data_preparation/models/project/__init__.py +66 -18
- mage_ai/data_preparation/models/project/constants.py +2 -0
- mage_ai/data_preparation/models/triggers/__init__.py +120 -24
- mage_ai/data_preparation/models/utils.py +467 -17
- mage_ai/data_preparation/models/variable.py +1028 -137
- mage_ai/data_preparation/models/variables/__init__.py +0 -0
- mage_ai/data_preparation/models/variables/cache.py +149 -0
- mage_ai/data_preparation/models/variables/constants.py +72 -0
- mage_ai/data_preparation/models/variables/summarizer.py +336 -0
- mage_ai/data_preparation/models/variables/utils.py +77 -0
- mage_ai/data_preparation/models/widget/__init__.py +63 -41
- mage_ai/data_preparation/models/widget/charts.py +40 -27
- mage_ai/data_preparation/models/widget/constants.py +2 -0
- mage_ai/data_preparation/models/widget/utils.py +3 -3
- mage_ai/data_preparation/preferences.py +3 -3
- mage_ai/data_preparation/repo_manager.py +55 -21
- mage_ai/data_preparation/storage/base_storage.py +2 -2
- mage_ai/data_preparation/storage/gcs_storage.py +7 -4
- mage_ai/data_preparation/storage/local_storage.py +6 -3
- mage_ai/data_preparation/storage/s3_storage.py +5 -2
- mage_ai/data_preparation/templates/data_exporters/streaming/oracledb.yaml +8 -0
- mage_ai/data_preparation/variable_manager.py +281 -76
- mage_ai/io/base.py +3 -2
- mage_ai/io/bigquery.py +1 -0
- mage_ai/io/redshift.py +7 -5
- mage_ai/kernels/__init__.py +0 -0
- mage_ai/kernels/models.py +188 -0
- mage_ai/kernels/utils.py +169 -0
- mage_ai/orchestration/concurrency.py +6 -2
- mage_ai/orchestration/db/__init__.py +1 -0
- mage_ai/orchestration/db/migrations/versions/0227396a216c_add_userproject_table.py +38 -0
- mage_ai/orchestration/db/models/dynamic/__init__.py +0 -0
- mage_ai/orchestration/db/models/dynamic/controller.py +67 -0
- mage_ai/orchestration/db/models/oauth.py +2 -9
- mage_ai/orchestration/db/models/projects.py +10 -0
- mage_ai/orchestration/db/models/schedules.py +204 -187
- mage_ai/orchestration/db/models/schedules_project_platform.py +18 -12
- mage_ai/orchestration/db/models/utils.py +46 -5
- mage_ai/orchestration/metrics/pipeline_run.py +8 -9
- mage_ai/orchestration/notification/sender.py +1 -0
- mage_ai/orchestration/pipeline_scheduler_original.py +32 -8
- mage_ai/orchestration/pipeline_scheduler_project_platform.py +1 -1
- mage_ai/orchestration/run_status_checker.py +11 -4
- mage_ai/orchestration/triggers/api.py +12 -1
- mage_ai/presenters/charts/data_sources/base.py +4 -2
- mage_ai/presenters/charts/data_sources/block.py +15 -9
- mage_ai/presenters/charts/data_sources/chart_code.py +8 -5
- mage_ai/presenters/charts/data_sources/constants.py +1 -0
- mage_ai/presenters/charts/data_sources/system_metrics.py +22 -0
- mage_ai/presenters/interactions/models.py +11 -7
- mage_ai/presenters/pages/loaders/pipelines.py +5 -3
- mage_ai/presenters/pages/models/page_components/pipeline_schedules.py +3 -1
- mage_ai/presenters/utils.py +2 -0
- mage_ai/server/api/blocks.py +2 -1
- mage_ai/server/api/downloads.py +5 -1
- mage_ai/server/api/triggers.py +3 -1
- mage_ai/server/constants.py +1 -1
- mage_ai/server/frontend_dist/404.html +5 -5
- mage_ai/server/frontend_dist/_next/static/UZLabyPgcxtZvp0O0EUUS/_buildManifest.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/1376-22de38b4ad008d8a.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/{1557-b3502f3f1aa92ac7.js → 1557-25a7d985d5564fd3.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1668-30b4619b9534519b.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/1799-c42db95a015689ee.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/2996-2108b53b9d371d8d.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/3763-61b542dafdbf5754.js → frontend_dist/_next/static/chunks/3763-40780c6d1e4b261d.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/3782-129dd2a2448a2e36.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/3958-bcdfa414ccfa1eb2.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/4168-97fd1578d1a38315.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/4982-fa5a238b139fbdd2.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/5699-176f445e1313f001.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/7162-7dd03f0f605de721.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/7779-68d2b72a90c5f925.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/7966-5446a8e43711e2f9.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/8023-6c2f172f48dcb99b.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/8095-c351b8a735d73e0c.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/{main-77fe248a6fbd12d8.js → main-b99d4e30a88d9dc7.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-9fe2d9d07c94e968.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/{block-layout-14f952f66964022f.js → block-layout-7f4b735c67115df5.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-e7d48e6b0c3068ac.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products-b943f31f050fc3a4.js +1 -0
- 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
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/{[...slug]-7181b086c93784d2.js → [...slug]-7e737f6fc7e83e9b.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-d94488e3f2eeef36.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-cc641a7fa8473796.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-a5c0362763a21fa8.js → block-runs-284309877f3c5a5a.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-26250e5335194ade.js +1 -0
- 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
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-4ebfc8e400315dda.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-e5e0150a256aadb3.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/{profile-3f0df3decc856ee9.js → profile-3ae43c932537b254.js} +1 -1
- 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
- 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
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-47b64ced27c24985.js → [...slug]-5c360f72e4498855.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{permissions-e5a4d3d815cec25d.js → permissions-fb29fa6c2bd90bb0.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-3b76fa959ffa09d3.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-379e1ee292504842.js → [...slug]-3b787b42f1093b1f.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-0b83fbdd39e85f5b.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-a1e6950974d643a8.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-2af9afbe727d88aa.js → [...slug]-0aa019d87db8b0b8.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{users-a4db8710f703c729.js → users-88c694d19207f2ec.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-31d0d50f7f30462b.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/{webpack-d079359c241db804.js → webpack-ac7fdc472bedf682.js} +1 -1
- mage_ai/server/frontend_dist/block-layout.html +3 -3
- mage_ai/server/frontend_dist/compute.html +6 -6
- mage_ai/server/frontend_dist/files.html +6 -6
- mage_ai/server/frontend_dist/global-data-products/[...slug].html +6 -6
- mage_ai/server/frontend_dist/global-data-products.html +6 -6
- mage_ai/server/frontend_dist/global-hooks/[...slug].html +6 -6
- mage_ai/server/frontend_dist/global-hooks.html +6 -6
- mage_ai/server/frontend_dist/index.html +3 -3
- mage_ai/server/frontend_dist/manage/files.html +6 -6
- mage_ai/server/frontend_dist/manage/settings.html +6 -6
- mage_ai/server/frontend_dist/manage/users/[user].html +6 -6
- mage_ai/server/frontend_dist/manage/users/new.html +6 -6
- mage_ai/server/frontend_dist/manage/users.html +6 -6
- mage_ai/server/frontend_dist/manage.html +6 -6
- mage_ai/server/frontend_dist/oauth.html +5 -5
- mage_ai/server/frontend_dist/overview.html +6 -6
- mage_ai/server/frontend_dist/pipeline-runs.html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +3 -3
- mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +6 -6
- mage_ai/server/frontend_dist/pipelines/[pipeline].html +3 -3
- mage_ai/server/frontend_dist/pipelines.html +6 -6
- mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +6 -6
- mage_ai/server/frontend_dist/platform/global-hooks.html +6 -6
- mage_ai/server/frontend_dist/settings/account/profile.html +6 -6
- mage_ai/server/frontend_dist/settings/platform/preferences.html +6 -6
- mage_ai/server/frontend_dist/settings/platform/settings.html +6 -6
- mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +6 -6
- mage_ai/server/frontend_dist/settings/workspace/permissions.html +6 -6
- mage_ai/server/frontend_dist/settings/workspace/preferences.html +6 -6
- mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +6 -6
- mage_ai/server/frontend_dist/settings/workspace/roles.html +6 -6
- mage_ai/server/frontend_dist/settings/workspace/sync-data.html +6 -6
- mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +6 -6
- mage_ai/server/frontend_dist/settings/workspace/users.html +6 -6
- mage_ai/server/frontend_dist/settings.html +3 -3
- mage_ai/server/frontend_dist/sign-in.html +12 -12
- mage_ai/server/frontend_dist/templates/[...slug].html +6 -6
- mage_ai/server/frontend_dist/templates.html +6 -6
- mage_ai/server/frontend_dist/terminal.html +6 -6
- mage_ai/server/frontend_dist/test.html +3 -3
- mage_ai/server/frontend_dist/triggers.html +6 -6
- mage_ai/server/frontend_dist/version-control.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/404.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1376-22de38b4ad008d8a.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{1557-b3502f3f1aa92ac7.js → 1557-25a7d985d5564fd3.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1668-30b4619b9534519b.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1799-c42db95a015689ee.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2996-2108b53b9d371d8d.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/3763-61b542dafdbf5754.js → frontend_dist_base_path_template/_next/static/chunks/3763-40780c6d1e4b261d.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-129dd2a2448a2e36.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3958-bcdfa414ccfa1eb2.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4168-97fd1578d1a38315.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4982-fa5a238b139fbdd2.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-176f445e1313f001.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7162-7dd03f0f605de721.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7779-68d2b72a90c5f925.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-5446a8e43711e2f9.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8023-6c2f172f48dcb99b.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-c351b8a735d73e0c.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{main-70b78159c2bb3fe1.js → main-384298e9133cec76.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-13a578bce3b7f30c.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{block-layout-14f952f66964022f.js → block-layout-7f4b735c67115df5.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-e7d48e6b0c3068ac.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products-b943f31f050fc3a4.js +1 -0
- 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
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/{[...slug]-7181b086c93784d2.js → [...slug]-7e737f6fc7e83e9b.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-d94488e3f2eeef36.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-cc641a7fa8473796.js +1 -0
- 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
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-26250e5335194ade.js +1 -0
- 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
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-4ebfc8e400315dda.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-e5e0150a256aadb3.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/{profile-3f0df3decc856ee9.js → profile-3ae43c932537b254.js} +1 -1
- 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
- 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
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-47b64ced27c24985.js → [...slug]-5c360f72e4498855.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{permissions-e5a4d3d815cec25d.js → permissions-fb29fa6c2bd90bb0.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-3b76fa959ffa09d3.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-379e1ee292504842.js → [...slug]-3b787b42f1093b1f.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-0b83fbdd39e85f5b.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-a1e6950974d643a8.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-2af9afbe727d88aa.js → [...slug]-0aa019d87db8b0b8.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{users-a4db8710f703c729.js → users-88c694d19207f2ec.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-31d0d50f7f30462b.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-68c003fb6a175cd7.js → webpack-481689d9989710cd.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/kcptwoOU-JJJg6Vwpkfmx/_buildManifest.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/block-layout.html +3 -3
- mage_ai/server/frontend_dist_base_path_template/compute.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/files.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +6 -6
- mage_ai/server/frontend_dist_base_path_template/global-data-products.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +6 -6
- mage_ai/server/frontend_dist_base_path_template/global-hooks.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/index.html +3 -3
- mage_ai/server/frontend_dist_base_path_template/manage/files.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/manage/settings.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +6 -6
- mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/manage/users.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/manage.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/oauth.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/overview.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +3 -3
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +3 -3
- mage_ai/server/frontend_dist_base_path_template/pipelines.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +6 -6
- mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +6 -6
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +6 -6
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +6 -6
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/settings.html +3 -3
- mage_ai/server/frontend_dist_base_path_template/sign-in.html +12 -12
- mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +6 -6
- mage_ai/server/frontend_dist_base_path_template/templates.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/terminal.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/test.html +3 -3
- mage_ai/server/frontend_dist_base_path_template/triggers.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/version-control.html +6 -6
- mage_ai/server/kernel_output_parser.py +4 -1
- mage_ai/server/scheduler_manager.py +9 -0
- mage_ai/server/server.py +35 -31
- mage_ai/server/utils/custom_output.py +284 -0
- mage_ai/server/utils/execute_custom_code.py +245 -0
- mage_ai/server/utils/output_display.py +123 -289
- mage_ai/server/websocket_server.py +116 -69
- mage_ai/services/k8s/config.py +23 -0
- mage_ai/services/k8s/job_manager.py +6 -1
- mage_ai/services/ssh/aws/emr/utils.py +8 -8
- mage_ai/settings/keys/auth.py +1 -0
- mage_ai/settings/platform/__init__.py +159 -38
- mage_ai/settings/platform/constants.py +5 -0
- mage_ai/settings/platform/utils.py +53 -10
- mage_ai/settings/repo.py +26 -12
- mage_ai/settings/server.py +128 -37
- mage_ai/shared/array.py +24 -1
- mage_ai/shared/complex.py +45 -0
- mage_ai/shared/config.py +2 -1
- mage_ai/shared/custom_logger.py +11 -0
- mage_ai/shared/dates.py +10 -6
- mage_ai/shared/files.py +63 -8
- mage_ai/shared/hash.py +33 -9
- mage_ai/shared/io.py +9 -5
- mage_ai/shared/models.py +82 -24
- mage_ai/shared/outputs.py +87 -0
- mage_ai/shared/parsers.py +141 -15
- mage_ai/shared/path_fixer.py +11 -7
- mage_ai/shared/singletons/__init__.py +0 -0
- mage_ai/shared/singletons/base.py +47 -0
- mage_ai/shared/singletons/memory.py +38 -0
- mage_ai/shared/strings.py +34 -1
- mage_ai/shared/yaml.py +24 -0
- mage_ai/streaming/sinks/oracledb.py +57 -0
- mage_ai/streaming/sinks/sink_factory.py +4 -0
- mage_ai/system/__init__.py +0 -0
- mage_ai/system/constants.py +14 -0
- mage_ai/system/memory/__init__.py +0 -0
- mage_ai/system/memory/constants.py +1 -0
- mage_ai/system/memory/manager.py +174 -0
- mage_ai/system/memory/presenters.py +158 -0
- mage_ai/system/memory/process.py +216 -0
- mage_ai/system/memory/samples.py +13 -0
- mage_ai/system/memory/utils.py +656 -0
- mage_ai/system/memory/wrappers.py +177 -0
- mage_ai/system/models.py +58 -0
- mage_ai/system/storage/__init__.py +0 -0
- mage_ai/system/storage/utils.py +29 -0
- mage_ai/tests/api/endpoints/mixins.py +2 -2
- mage_ai/tests/api/endpoints/test_blocks.py +2 -1
- mage_ai/tests/api/endpoints/test_custom_designs.py +4 -4
- mage_ai/tests/api/endpoints/test_pipeline_runs.py +2 -2
- mage_ai/tests/api/endpoints/test_projects.py +2 -1
- mage_ai/tests/api/operations/base/test_base.py +27 -27
- mage_ai/tests/api/operations/base/test_base_with_user_authentication.py +27 -27
- mage_ai/tests/api/operations/base/test_base_with_user_permissions.py +23 -23
- mage_ai/tests/api/operations/test_syncs.py +6 -4
- mage_ai/tests/api/resources/test_pipeline_resource.py +9 -2
- mage_ai/tests/authentication/providers/test_oidc.py +59 -0
- mage_ai/tests/base_test.py +2 -2
- mage_ai/tests/data/__init__.py +0 -0
- mage_ai/tests/data/models/__init__.py +0 -0
- mage_ai/tests/data_preparation/executors/test_block_executor.py +23 -16
- mage_ai/tests/data_preparation/git/test_git.py +4 -1
- mage_ai/tests/data_preparation/models/block/dynamic/test_combos.py +305 -0
- mage_ai/tests/data_preparation/models/block/dynamic/test_counter.py +212 -0
- mage_ai/tests/data_preparation/models/block/dynamic/test_factory.py +360 -0
- mage_ai/tests/data_preparation/models/block/dynamic/test_variables.py +332 -0
- mage_ai/tests/data_preparation/models/block/hook/test_hook_block.py +2 -2
- mage_ai/tests/data_preparation/models/block/platform/test_mixins.py +1 -1
- mage_ai/tests/data_preparation/models/block/sql/utils/test_shared.py +26 -1
- mage_ai/tests/data_preparation/models/block/test_global_data_product.py +3 -2
- mage_ai/tests/data_preparation/models/custom_templates/test_utils.py +5 -4
- mage_ai/tests/data_preparation/models/global_hooks/test_hook.py +3 -0
- mage_ai/tests/data_preparation/models/global_hooks/test_predicates.py +9 -3
- mage_ai/tests/data_preparation/models/test_block.py +115 -120
- mage_ai/tests/data_preparation/models/test_blocks_helper.py +114 -0
- mage_ai/tests/data_preparation/models/test_global_data_product.py +41 -24
- mage_ai/tests/data_preparation/models/test_pipeline.py +9 -6
- mage_ai/tests/data_preparation/models/test_project.py +4 -1
- mage_ai/tests/data_preparation/models/test_utils.py +80 -0
- mage_ai/tests/data_preparation/models/test_variable.py +242 -69
- mage_ai/tests/data_preparation/models/variables/__init__.py +0 -0
- mage_ai/tests/data_preparation/models/variables/test_summarizer.py +481 -0
- mage_ai/tests/data_preparation/storage/shared/__init__.py +0 -0
- mage_ai/tests/data_preparation/test_repo_manager.py +6 -7
- mage_ai/tests/data_preparation/test_variable_manager.py +57 -48
- mage_ai/tests/factory.py +64 -43
- mage_ai/tests/orchestration/db/models/test_schedules.py +3 -3
- mage_ai/tests/orchestration/db/models/test_schedules_dynamic_blocks.py +279 -0
- mage_ai/tests/orchestration/test_pipeline_scheduler.py +1 -0
- mage_ai/tests/orchestration/triggers/test_global_data_product.py +3 -2
- mage_ai/tests/orchestration/triggers/test_utils.py +3 -2
- mage_ai/tests/services/k8s/test_job_manager.py +18 -0
- mage_ai/tests/streaming/sinks/test_oracledb.py +38 -0
- mage_ai/tests/test_shared.py +61 -0
- mage_ai/usage_statistics/logger.py +7 -2
- mage_ai/utils/code.py +33 -19
- {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/METADATA +5 -2
- {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/RECORD +513 -417
- mage_ai/data_preparation/models/global_data_product/constants.py +0 -6
- mage_ai/server/frontend_dist/_next/static/RhDiJSkcjCsh4xxX4BFBk/_buildManifest.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2631-b9f9bea3f1cf906d.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/3782-ef4cd4f0b52072d0.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/4783-422429203610c318.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/5699-6d708c6b2153ea08.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/635-0d6b7c8804bcd2dc.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/7022-0d52dd8868621fb0.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/7361-8a23dd8360593e7a.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/7966-b9b85ba10667e654.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/8095-bdce03896ef9639a.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/8146-6bed4e7401e067e6.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9265-d2a1aaec75ec69b8.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9440-4069842b90d4b801.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9832-67896490f6e8a014.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-2a69553d8c6eeb53.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-591abd392dc50ed4.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products-78e8e88f2a757a18.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-95ffcd3e2b27e567.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-b645a6d13ab9fe3a.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-1ed9045b2f1dfd65.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-349af617d05f001b.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-36fa165a48af586b.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-60d01d3887e31136.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-3433c8b22e8342aa.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/TdpLLFome13qvM0gXvpHs/_buildManifest.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2631-b9f9bea3f1cf906d.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3782-ef4cd4f0b52072d0.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4783-422429203610c318.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-6d708c6b2153ea08.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/635-0d6b7c8804bcd2dc.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-0d52dd8868621fb0.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-8a23dd8360593e7a.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-b9b85ba10667e654.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-bdce03896ef9639a.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-6bed4e7401e067e6.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9265-d2a1aaec75ec69b8.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-4069842b90d4b801.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9832-67896490f6e8a014.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-2a69553d8c6eeb53.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-591abd392dc50ed4.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products-78e8e88f2a757a18.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-95ffcd3e2b27e567.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-b645a6d13ab9fe3a.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-1ed9045b2f1dfd65.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-349af617d05f001b.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-36fa165a48af586b.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-60d01d3887e31136.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-3433c8b22e8342aa.js +0 -1
- mage_ai/shared/memory.py +0 -90
- mage_ai/tests/data_preparation/models/block/dynamic/test_dynamic_helpers.py +0 -48
- /mage_ai/{tests/data_preparation/shared → ai/utils}/__init__.py +0 -0
- /mage_ai/server/frontend_dist/_next/static/{RhDiJSkcjCsh4xxX4BFBk → UZLabyPgcxtZvp0O0EUUS}/_ssgManifest.js +0 -0
- /mage_ai/server/frontend_dist_base_path_template/_next/static/{TdpLLFome13qvM0gXvpHs → kcptwoOU-JJJg6Vwpkfmx}/_ssgManifest.js +0 -0
- /mage_ai/tests/data_preparation/{shared → storage/shared}/test_secrets.py +0 -0
- {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/LICENSE +0 -0
- {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/WHEEL +0 -0
- {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/entry_points.txt +0 -0
- {mage_ai-0.9.70.dist-info → mage_ai-0.9.71.dist-info}/top_level.txt +0 -0
|
@@ -2,10 +2,27 @@ import json
|
|
|
2
2
|
import os
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
4
|
from enum import Enum
|
|
5
|
-
from typing import Any, Dict, List, Tuple, Union
|
|
5
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
6
6
|
|
|
7
7
|
import pandas as pd
|
|
8
|
+
import polars as pl
|
|
9
|
+
from scipy.sparse import csr_matrix
|
|
8
10
|
|
|
11
|
+
from mage_ai.data_preparation.models.block.dynamic.shared import (
|
|
12
|
+
has_dynamic_block_upstream_parent as has_dynamic_block_upstream_parent_v1,
|
|
13
|
+
)
|
|
14
|
+
from mage_ai.data_preparation.models.block.dynamic.shared import (
|
|
15
|
+
has_reduce_output_from_upstreams as has_reduce_output_from_upstreams_v1,
|
|
16
|
+
)
|
|
17
|
+
from mage_ai.data_preparation.models.block.dynamic.shared import (
|
|
18
|
+
is_dynamic_block as is_dynamic_block_v1,
|
|
19
|
+
)
|
|
20
|
+
from mage_ai.data_preparation.models.block.dynamic.shared import (
|
|
21
|
+
is_dynamic_block_child as is_dynamic_block_child_v1,
|
|
22
|
+
)
|
|
23
|
+
from mage_ai.data_preparation.models.block.dynamic.shared import (
|
|
24
|
+
should_reduce_output as should_reduce_output_v1,
|
|
25
|
+
)
|
|
9
26
|
from mage_ai.data_preparation.models.block.dynamic.variables import (
|
|
10
27
|
get_outputs_for_dynamic_block,
|
|
11
28
|
)
|
|
@@ -13,6 +30,11 @@ from mage_ai.data_preparation.models.constants import (
|
|
|
13
30
|
DATAFRAME_ANALYSIS_MAX_COLUMNS,
|
|
14
31
|
DATAFRAME_SAMPLE_COUNT_PREVIEW,
|
|
15
32
|
)
|
|
33
|
+
from mage_ai.data_preparation.models.utils import (
|
|
34
|
+
is_basic_iterable,
|
|
35
|
+
is_dataframe_or_series,
|
|
36
|
+
prepare_data_for_output,
|
|
37
|
+
)
|
|
16
38
|
from mage_ai.server.kernel_output_parser import DataType
|
|
17
39
|
from mage_ai.shared.array import find
|
|
18
40
|
from mage_ai.shared.custom_logger import DX_PRINTER
|
|
@@ -76,66 +98,23 @@ def extract_dynamic_block_index(block_run_block_uuid: str) -> int:
|
|
|
76
98
|
|
|
77
99
|
|
|
78
100
|
def is_dynamic_block(block) -> bool:
|
|
79
|
-
|
|
80
|
-
Checks if the given block is a dynamic block.
|
|
81
|
-
|
|
82
|
-
Args:
|
|
83
|
-
block: The block.
|
|
84
|
-
|
|
85
|
-
Returns:
|
|
86
|
-
bool: True if the block is a dynamic block, False otherwise.
|
|
87
|
-
"""
|
|
88
|
-
return block and block.configuration and block.configuration.get('dynamic', False)
|
|
101
|
+
return is_dynamic_block_v1(block)
|
|
89
102
|
|
|
90
103
|
|
|
91
104
|
def should_reduce_output(block) -> bool:
|
|
92
|
-
|
|
93
|
-
Checks if the given block should reduce its output.
|
|
94
|
-
|
|
95
|
-
Args:
|
|
96
|
-
block: The block.
|
|
97
|
-
|
|
98
|
-
Returns:
|
|
99
|
-
bool: True if the block should reduce its output, False otherwise.
|
|
100
|
-
"""
|
|
101
|
-
if not block or not block.configuration or not block.configuration.get('reduce_output', False):
|
|
102
|
-
return False
|
|
103
|
-
return True
|
|
105
|
+
return should_reduce_output_v1(block)
|
|
104
106
|
|
|
105
107
|
|
|
106
108
|
def has_reduce_output_from_upstreams(block) -> bool:
|
|
107
|
-
return
|
|
109
|
+
return has_reduce_output_from_upstreams_v1(block)
|
|
108
110
|
|
|
109
111
|
|
|
110
112
|
def has_dynamic_block_upstream_parent(block) -> bool:
|
|
111
|
-
return
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
def is_dynamic_block_child(block) -> bool:
|
|
115
|
-
"""
|
|
116
|
-
Checks if the given block is a dynamic block child.
|
|
117
|
-
|
|
118
|
-
Args:
|
|
119
|
-
block: The block.
|
|
120
|
-
|
|
121
|
-
Returns:
|
|
122
|
-
bool: True if the block is a dynamic block child, False otherwise.
|
|
123
|
-
"""
|
|
124
|
-
if not block:
|
|
125
|
-
return False
|
|
126
|
-
|
|
127
|
-
dynamic_or_child = []
|
|
113
|
+
return has_dynamic_block_upstream_parent_v1(block)
|
|
128
114
|
|
|
129
|
-
for upstream_block in block.upstream_blocks:
|
|
130
|
-
if is_dynamic_block(upstream_block) or is_dynamic_block_child(upstream_block):
|
|
131
|
-
dynamic_or_child.append(upstream_block)
|
|
132
|
-
|
|
133
|
-
if len(dynamic_or_child) == 0:
|
|
134
|
-
return False
|
|
135
115
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
return len(dynamic_or_child) > len(dynamic_or_child_with_reduce)
|
|
116
|
+
def is_dynamic_block_child(block, include_reduce_output: Optional[bool] = None) -> bool:
|
|
117
|
+
return is_dynamic_block_child_v1(block, include_reduce_output=include_reduce_output)
|
|
139
118
|
|
|
140
119
|
|
|
141
120
|
def is_replicated_block(block) -> bool:
|
|
@@ -152,6 +131,7 @@ def is_original_dynamic_child_block(
|
|
|
152
131
|
|
|
153
132
|
def __get_block_run(block_run_id=block_run_id):
|
|
154
133
|
from mage_ai.orchestration.db.models.schedules import BlockRun
|
|
134
|
+
|
|
155
135
|
return BlockRun.query.get(block_run_id)
|
|
156
136
|
|
|
157
137
|
if block:
|
|
@@ -179,10 +159,10 @@ def is_original_dynamic_child_block(
|
|
|
179
159
|
|
|
180
160
|
def uuid_for_output_variables(
|
|
181
161
|
block,
|
|
182
|
-
block_uuid: str = None,
|
|
183
|
-
dynamic_block_index: int = None,
|
|
184
|
-
dynamic_block_uuid: str = None,
|
|
185
|
-
join_character: str = None,
|
|
162
|
+
block_uuid: Optional[str] = None,
|
|
163
|
+
dynamic_block_index: Optional[int] = None,
|
|
164
|
+
dynamic_block_uuid: Optional[str] = None,
|
|
165
|
+
join_character: Optional[str] = None,
|
|
186
166
|
**kwargs,
|
|
187
167
|
) -> Tuple[str, bool]:
|
|
188
168
|
changed = False
|
|
@@ -199,9 +179,9 @@ def uuid_for_output_variables(
|
|
|
199
179
|
return os.path.join(block.uuid, str(dynamic_block_index)), True
|
|
200
180
|
|
|
201
181
|
is_dynamic = is_dynamic_block(block)
|
|
202
|
-
if (not is_dynamic and (dynamic_block_index is None or is_dynamic_child)) or
|
|
203
|
-
|
|
204
|
-
|
|
182
|
+
if (not is_dynamic and (dynamic_block_index is None or is_dynamic_child)) or (
|
|
183
|
+
is_dynamic and is_dynamic_child
|
|
184
|
+
):
|
|
205
185
|
parts = block_uuid.split(':')
|
|
206
186
|
|
|
207
187
|
if len(parts) >= 2:
|
|
@@ -239,28 +219,38 @@ def uuid_for_output_variables(
|
|
|
239
219
|
return (block_uuid, changed)
|
|
240
220
|
|
|
241
221
|
|
|
242
|
-
def transform_dataframe_for_display(
|
|
222
|
+
def transform_dataframe_for_display(
|
|
223
|
+
dataframe: pd.DataFrame,
|
|
224
|
+
is_dynamic: bool = False,
|
|
225
|
+
is_dynamic_child: bool = False,
|
|
226
|
+
sample_columns: int = DATAFRAME_ANALYSIS_MAX_COLUMNS,
|
|
227
|
+
sample_count: int = DATAFRAME_SAMPLE_COUNT_PREVIEW,
|
|
228
|
+
shape: Optional[Tuple[int, int]] = None,
|
|
229
|
+
) -> Dict:
|
|
243
230
|
data = None
|
|
231
|
+
|
|
232
|
+
column_name = '-'
|
|
233
|
+
if is_dynamic:
|
|
234
|
+
column_name = 'dynamic child blocks'
|
|
235
|
+
elif is_dynamic_child:
|
|
236
|
+
column_name = 'output'
|
|
237
|
+
|
|
244
238
|
if isinstance(dataframe, pd.DataFrame):
|
|
245
|
-
columns_to_display = dataframe.columns.tolist()[:
|
|
246
|
-
row_count, column_count = dataframe.shape
|
|
239
|
+
columns_to_display = dataframe.columns.tolist()[:sample_columns]
|
|
240
|
+
row_count, column_count = shape or dataframe.shape
|
|
241
|
+
|
|
242
|
+
df = dataframe.iloc[:sample_count][columns_to_display]
|
|
247
243
|
|
|
248
244
|
data = dict(
|
|
249
245
|
columns=columns_to_display,
|
|
250
|
-
rows=json.loads(
|
|
251
|
-
dataframe[columns_to_display][:DATAFRAME_SAMPLE_COUNT_PREVIEW].to_json(
|
|
252
|
-
orient='split',
|
|
253
|
-
)
|
|
254
|
-
)['data'],
|
|
255
|
-
index=list(dataframe.index),
|
|
246
|
+
rows=json.loads(df.to_json(orient='split'))['data'],
|
|
256
247
|
shape=[row_count, column_count],
|
|
257
248
|
)
|
|
258
249
|
else:
|
|
259
250
|
data = dict(
|
|
260
|
-
columns=[
|
|
261
|
-
rows=[[dataframe[:
|
|
262
|
-
|
|
263
|
-
shape=[1, 1],
|
|
251
|
+
columns=[column_name],
|
|
252
|
+
rows=[[dataframe[:sample_count]]],
|
|
253
|
+
shape=list(shape) if shape else [1, 1],
|
|
264
254
|
)
|
|
265
255
|
|
|
266
256
|
return dict(
|
|
@@ -269,10 +259,26 @@ def transform_dataframe_for_display(dataframe: pd.DataFrame) -> Dict:
|
|
|
269
259
|
)
|
|
270
260
|
|
|
271
261
|
|
|
272
|
-
def coerce_into_dataframe(
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
262
|
+
def coerce_into_dataframe(
|
|
263
|
+
child_data: Union[
|
|
264
|
+
List[Union[Dict, int, str, pd.DataFrame]],
|
|
265
|
+
Dict,
|
|
266
|
+
int,
|
|
267
|
+
str,
|
|
268
|
+
pd.DataFrame,
|
|
269
|
+
],
|
|
270
|
+
is_dynamic: bool = False,
|
|
271
|
+
is_dynamic_child: bool = False,
|
|
272
|
+
single_item_only: bool = False,
|
|
273
|
+
) -> pd.DataFrame:
|
|
274
|
+
child_data, _ = prepare_data_for_output(child_data, single_item_only=single_item_only)
|
|
275
|
+
|
|
276
|
+
column_name = '-'
|
|
277
|
+
if is_dynamic:
|
|
278
|
+
column_name = 'dynamic child blocks'
|
|
279
|
+
elif is_dynamic_child:
|
|
280
|
+
column_name = 'output'
|
|
281
|
+
|
|
276
282
|
if isinstance(child_data, list) and len(child_data) >= 1:
|
|
277
283
|
item = child_data[0]
|
|
278
284
|
if isinstance(item, pd.DataFrame):
|
|
@@ -281,34 +287,51 @@ def coerce_into_dataframe(child_data: Union[
|
|
|
281
287
|
child_data = pd.DataFrame(child_data)
|
|
282
288
|
else:
|
|
283
289
|
child_data = pd.DataFrame(
|
|
284
|
-
[
|
|
290
|
+
[
|
|
291
|
+
{
|
|
292
|
+
column_name: value,
|
|
293
|
+
}
|
|
294
|
+
for value in child_data
|
|
295
|
+
],
|
|
285
296
|
)
|
|
286
|
-
elif isinstance(child_data, pd.DataFrame):
|
|
297
|
+
elif isinstance(child_data, (pd.DataFrame, pl.DataFrame)):
|
|
287
298
|
return child_data
|
|
288
299
|
else:
|
|
289
|
-
child_data = pd.DataFrame([
|
|
300
|
+
child_data = pd.DataFrame([
|
|
301
|
+
{
|
|
302
|
+
column_name: child_data,
|
|
303
|
+
}
|
|
304
|
+
])
|
|
290
305
|
|
|
291
306
|
return child_data
|
|
292
307
|
|
|
293
308
|
|
|
294
|
-
def limit_output(
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
309
|
+
def limit_output(
|
|
310
|
+
output: Union[List, pd.DataFrame, pd.Series, csr_matrix],
|
|
311
|
+
sample_count: int = DATAFRAME_SAMPLE_COUNT_PREVIEW,
|
|
312
|
+
sample_columns: Optional[int] = DATAFRAME_ANALYSIS_MAX_COLUMNS,
|
|
313
|
+
) -> Union[List, pd.DataFrame, pd.Series, csr_matrix]:
|
|
314
|
+
if sample_count is not None and output is not None:
|
|
315
|
+
if isinstance(output, list):
|
|
316
|
+
output = output[:sample_count]
|
|
317
|
+
elif isinstance(output, pd.Series):
|
|
318
|
+
output = output.iloc[:sample_count]
|
|
319
|
+
elif isinstance(output, pd.DataFrame):
|
|
320
|
+
if sample_columns is not None:
|
|
321
|
+
output = output.iloc[:sample_count, :sample_columns]
|
|
322
|
+
else:
|
|
300
323
|
output = output.iloc[:sample_count]
|
|
324
|
+
elif isinstance(output, csr_matrix):
|
|
325
|
+
output = output[:sample_count] # For csr_matrix, this slices rows
|
|
326
|
+
if sample_columns is not None:
|
|
327
|
+
output = output[:, :sample_columns]
|
|
301
328
|
return output
|
|
302
329
|
|
|
303
330
|
|
|
304
331
|
def transform_output(
|
|
305
|
-
output: Tuple[
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
pd.DataFrame
|
|
309
|
-
],
|
|
310
|
-
List[Dict]
|
|
311
|
-
],
|
|
332
|
+
output: Tuple[Union[List[Union[Dict, int, str, pd.DataFrame]], pd.DataFrame], List[Dict]],
|
|
333
|
+
is_dynamic: bool = False,
|
|
334
|
+
is_dynamic_child: bool = False,
|
|
312
335
|
):
|
|
313
336
|
child_data = None
|
|
314
337
|
metadata = None
|
|
@@ -321,39 +344,66 @@ def transform_output(
|
|
|
321
344
|
if child_data is None:
|
|
322
345
|
return []
|
|
323
346
|
|
|
324
|
-
child_data = coerce_into_dataframe(
|
|
347
|
+
child_data = coerce_into_dataframe(
|
|
348
|
+
child_data,
|
|
349
|
+
is_dynamic=is_dynamic,
|
|
350
|
+
is_dynamic_child=is_dynamic_child,
|
|
351
|
+
)
|
|
325
352
|
|
|
326
353
|
if isinstance(child_data, tuple):
|
|
327
|
-
return transform_output(
|
|
354
|
+
return transform_output(
|
|
355
|
+
child_data,
|
|
356
|
+
is_dynamic=is_dynamic,
|
|
357
|
+
is_dynamic_child=is_dynamic_child,
|
|
358
|
+
)
|
|
328
359
|
elif isinstance(child_data, list):
|
|
329
|
-
child_data = [
|
|
360
|
+
child_data = [
|
|
361
|
+
transform_dataframe_for_display(
|
|
362
|
+
data,
|
|
363
|
+
is_dynamic=is_dynamic,
|
|
364
|
+
is_dynamic_child=is_dynamic_child,
|
|
365
|
+
)
|
|
366
|
+
for data in child_data
|
|
367
|
+
]
|
|
330
368
|
else:
|
|
331
|
-
child_data = transform_dataframe_for_display(
|
|
369
|
+
child_data = transform_dataframe_for_display(
|
|
370
|
+
child_data,
|
|
371
|
+
is_dynamic=is_dynamic,
|
|
372
|
+
is_dynamic_child=is_dynamic_child,
|
|
373
|
+
)
|
|
332
374
|
|
|
333
375
|
if metadata is not None:
|
|
334
|
-
metadata = transform_dataframe_for_display(
|
|
376
|
+
metadata = transform_dataframe_for_display(
|
|
377
|
+
coerce_into_dataframe(
|
|
378
|
+
metadata,
|
|
379
|
+
is_dynamic=is_dynamic,
|
|
380
|
+
is_dynamic_child=is_dynamic_child,
|
|
381
|
+
),
|
|
382
|
+
is_dynamic=is_dynamic,
|
|
383
|
+
is_dynamic_child=is_dynamic_child,
|
|
384
|
+
)
|
|
335
385
|
|
|
336
386
|
return child_data, metadata
|
|
337
387
|
|
|
338
388
|
|
|
339
389
|
def transform_output_for_display(
|
|
340
|
-
output: Tuple[
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
List[Dict]
|
|
346
|
-
],
|
|
347
|
-
sample_count: int = None,
|
|
390
|
+
output: Tuple[Union[List[Union[Dict, int, str, pd.DataFrame]], pd.DataFrame], List[Dict]],
|
|
391
|
+
is_dynamic: bool = False,
|
|
392
|
+
is_dynamic_child: bool = False,
|
|
393
|
+
sample_count: Optional[int] = None,
|
|
394
|
+
sample_columns: Optional[int] = None,
|
|
348
395
|
) -> List[Dict]:
|
|
349
|
-
child_data, metadata = transform_output(
|
|
350
|
-
|
|
351
|
-
|
|
396
|
+
child_data, metadata = transform_output(
|
|
397
|
+
output,
|
|
398
|
+
is_dynamic=is_dynamic,
|
|
399
|
+
is_dynamic_child=is_dynamic_child,
|
|
400
|
+
)
|
|
401
|
+
child_data = limit_output(child_data, sample_count, sample_columns=sample_columns)
|
|
402
|
+
metadata = limit_output(metadata, sample_count, sample_columns=sample_columns)
|
|
352
403
|
|
|
353
404
|
return dict(
|
|
354
405
|
data=dict(
|
|
355
|
-
columns=['
|
|
356
|
-
index=[0, 1],
|
|
406
|
+
columns=['dynamic children data', 'metadata'],
|
|
357
407
|
rows=[child_data, metadata],
|
|
358
408
|
shape=[2, 2],
|
|
359
409
|
),
|
|
@@ -364,34 +414,54 @@ def transform_output_for_display(
|
|
|
364
414
|
|
|
365
415
|
def transform_output_for_display_reduce_output(
|
|
366
416
|
output: List[Any],
|
|
367
|
-
|
|
417
|
+
is_dynamic: bool = False,
|
|
418
|
+
is_dynamic_child: bool = False,
|
|
419
|
+
sample_count: Optional[int] = None,
|
|
420
|
+
sample_columns: Optional[int] = None,
|
|
368
421
|
) -> List[Dict]:
|
|
369
|
-
output =
|
|
422
|
+
output = [
|
|
423
|
+
limit_output(
|
|
424
|
+
values,
|
|
425
|
+
sample_count=sample_count,
|
|
426
|
+
sample_columns=sample_columns,
|
|
427
|
+
)
|
|
428
|
+
for values in output
|
|
429
|
+
]
|
|
370
430
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
431
|
+
output = limit_output(output, sample_count=sample_count, sample_columns=sample_columns)
|
|
432
|
+
|
|
433
|
+
arr = [
|
|
434
|
+
dict(
|
|
435
|
+
text_data=data,
|
|
436
|
+
type=DataType.TEXT,
|
|
437
|
+
variable_uuid=f'reduced output {idx}',
|
|
438
|
+
)
|
|
439
|
+
for idx, data in enumerate(output)
|
|
440
|
+
]
|
|
376
441
|
|
|
377
442
|
return arr
|
|
378
443
|
|
|
379
444
|
|
|
380
|
-
def combine_transformed_output_for_multi_output(
|
|
381
|
-
|
|
382
|
-
|
|
445
|
+
def combine_transformed_output_for_multi_output(
|
|
446
|
+
transform_outputs: List[Dict],
|
|
447
|
+
columns: Optional[List[str]] = None,
|
|
448
|
+
is_grouping: bool = False,
|
|
449
|
+
) -> Dict[str, Union[DataType, Dict, bool, str]]:
|
|
450
|
+
columns_use = columns or []
|
|
383
451
|
for i in range(len(transform_outputs)):
|
|
384
|
-
columns
|
|
385
|
-
|
|
452
|
+
if not columns:
|
|
453
|
+
columns_use.append(f'output {i}')
|
|
386
454
|
|
|
387
455
|
return dict(
|
|
388
456
|
data=dict(
|
|
389
|
-
columns=
|
|
390
|
-
index=index,
|
|
457
|
+
columns=columns_use,
|
|
391
458
|
rows=transform_outputs,
|
|
392
|
-
shape=[
|
|
459
|
+
shape=[
|
|
460
|
+
len(transform_outputs),
|
|
461
|
+
len(columns_use),
|
|
462
|
+
],
|
|
393
463
|
),
|
|
394
|
-
type=DataType.TABLE,
|
|
464
|
+
type=DataType.GROUP if is_grouping else DataType.TABLE,
|
|
395
465
|
multi_output=True,
|
|
396
466
|
)
|
|
397
467
|
|
|
@@ -403,25 +473,41 @@ def transform_output_for_display_dynamic_child(
|
|
|
403
473
|
Dict,
|
|
404
474
|
int,
|
|
405
475
|
str,
|
|
406
|
-
pd.DataFrame
|
|
407
|
-
]
|
|
476
|
+
pd.DataFrame,
|
|
477
|
+
],
|
|
408
478
|
],
|
|
409
479
|
is_dynamic: bool = False,
|
|
410
|
-
|
|
480
|
+
is_dynamic_child: bool = False,
|
|
481
|
+
single_item_only: bool = False,
|
|
411
482
|
) -> List[Dict]:
|
|
412
483
|
df = None
|
|
413
484
|
for output_from_variable_object in output:
|
|
414
|
-
df_inner = coerce_into_dataframe(
|
|
485
|
+
df_inner = coerce_into_dataframe(
|
|
486
|
+
output_from_variable_object,
|
|
487
|
+
is_dynamic=is_dynamic,
|
|
488
|
+
is_dynamic_child=is_dynamic_child,
|
|
489
|
+
single_item_only=single_item_only,
|
|
490
|
+
)
|
|
415
491
|
if df is None:
|
|
416
492
|
df = df_inner
|
|
417
493
|
else:
|
|
418
|
-
df
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
494
|
+
df.reset_index(drop=True, inplace=True)
|
|
495
|
+
df_inner.reset_index(drop=True, inplace=True)
|
|
496
|
+
df = pd.concat([df, df_inner], axis=1, ignore_index=True)
|
|
497
|
+
|
|
498
|
+
shape = None
|
|
499
|
+
if hasattr(df, 'shape'):
|
|
500
|
+
shape = df.shape
|
|
501
|
+
|
|
502
|
+
if isinstance(df, pd.DataFrame) and len(set(df.columns)) == 1:
|
|
503
|
+
df.columns = [str(idx) for idx, col in enumerate(df.columns)]
|
|
504
|
+
|
|
505
|
+
return transform_dataframe_for_display(
|
|
506
|
+
df,
|
|
507
|
+
is_dynamic=is_dynamic,
|
|
508
|
+
is_dynamic_child=is_dynamic_child,
|
|
509
|
+
shape=shape,
|
|
510
|
+
)
|
|
425
511
|
|
|
426
512
|
|
|
427
513
|
def create_combinations(combinations: List[Any]) -> List[Any]:
|
|
@@ -430,7 +516,7 @@ def create_combinations(combinations: List[Any]) -> List[Any]:
|
|
|
430
516
|
|
|
431
517
|
for idx, arr in enumerate(combinations_inner):
|
|
432
518
|
for value in arr:
|
|
433
|
-
combinations_next = combinations_inner[(idx + 1):]
|
|
519
|
+
combinations_next = combinations_inner[(idx + 1) :]
|
|
434
520
|
if len(combinations_next) >= 1:
|
|
435
521
|
for combos_down in __create_combinations(combinations_next):
|
|
436
522
|
combos.append([value] + combos_down)
|
|
@@ -447,6 +533,7 @@ def create_combinations(combinations: List[Any]) -> List[Any]:
|
|
|
447
533
|
def build_combinations_for_dynamic_child(
|
|
448
534
|
block,
|
|
449
535
|
execution_partition: str = None,
|
|
536
|
+
origin_block: Optional[Any] = None,
|
|
450
537
|
**kwargs,
|
|
451
538
|
):
|
|
452
539
|
"""
|
|
@@ -469,6 +556,9 @@ def build_combinations_for_dynamic_child(
|
|
|
469
556
|
[0, 1],
|
|
470
557
|
]
|
|
471
558
|
"""
|
|
559
|
+
if origin_block is None:
|
|
560
|
+
origin_block = block
|
|
561
|
+
|
|
472
562
|
dynamic_counts = []
|
|
473
563
|
|
|
474
564
|
for upstream_block in block.upstream_blocks:
|
|
@@ -493,16 +583,22 @@ def build_combinations_for_dynamic_child(
|
|
|
493
583
|
children_created = build_combinations_for_dynamic_child(
|
|
494
584
|
upstream_block,
|
|
495
585
|
execution_partition=execution_partition,
|
|
586
|
+
origin_block=origin_block,
|
|
496
587
|
)
|
|
497
588
|
if is_dynamic:
|
|
498
589
|
for dynamic_block_index in range(len(children_created)):
|
|
499
590
|
values, _metadata = get_outputs_for_dynamic_block(
|
|
500
591
|
upstream_block,
|
|
501
592
|
execution_partition=execution_partition,
|
|
502
|
-
dynamic_block_index=dynamic_block_index
|
|
593
|
+
dynamic_block_index=dynamic_block_index,
|
|
594
|
+
origin_block=origin_block,
|
|
503
595
|
)
|
|
504
596
|
if values is not None:
|
|
505
|
-
|
|
597
|
+
if is_basic_iterable(values) or is_dataframe_or_series(values):
|
|
598
|
+
count = len(values)
|
|
599
|
+
else:
|
|
600
|
+
count = 1
|
|
601
|
+
arr.extend([idx for idx in range(count)])
|
|
506
602
|
else:
|
|
507
603
|
arr.append(0)
|
|
508
604
|
else:
|
|
@@ -511,8 +607,12 @@ def build_combinations_for_dynamic_child(
|
|
|
511
607
|
arr, _metadata = get_outputs_for_dynamic_block(
|
|
512
608
|
upstream_block,
|
|
513
609
|
execution_partition=execution_partition,
|
|
610
|
+
origin_block=origin_block,
|
|
514
611
|
)
|
|
515
|
-
|
|
612
|
+
if arr is not None:
|
|
613
|
+
if not is_basic_iterable(arr) and not is_dataframe_or_series(arr):
|
|
614
|
+
arr = [0]
|
|
615
|
+
if arr is not None and hasattr(arr, '__len__') and len(arr) > 0:
|
|
516
616
|
dynamic_counts.append([idx for idx in range(len(arr))])
|
|
517
617
|
else:
|
|
518
618
|
dynamic_counts.append([0])
|
|
@@ -542,10 +642,12 @@ def build_combinations_for_dynamic_child(
|
|
|
542
642
|
if is_dynamic_child or is_dynamic:
|
|
543
643
|
dynamic_block_indexes[upstream_block.uuid] = parent_index
|
|
544
644
|
|
|
545
|
-
settings.append(
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
645
|
+
settings.append(
|
|
646
|
+
dict(
|
|
647
|
+
dynamic_block_index=dynamic_block_index,
|
|
648
|
+
dynamic_block_indexes=dynamic_block_indexes,
|
|
649
|
+
)
|
|
650
|
+
)
|
|
549
651
|
|
|
550
652
|
return settings
|
|
551
653
|
|
|
@@ -596,7 +698,9 @@ class DynamicBlockWrapper(BaseDataClass):
|
|
|
596
698
|
# Upstream blocks that are dynamic blocks.
|
|
597
699
|
upstream_dynamic_blocks: List[DynamicBlockWrapperBase] = field(default_factory=lambda: [])
|
|
598
700
|
# Upstream blocks that are dynamic child blocks.
|
|
599
|
-
upstream_dynamic_child_blocks: List[DynamicBlockWrapperBase] = field(
|
|
701
|
+
upstream_dynamic_child_blocks: List[DynamicBlockWrapperBase] = field(
|
|
702
|
+
default_factory=lambda: []
|
|
703
|
+
)
|
|
600
704
|
# Unique identifier used as a suffix in the block run.
|
|
601
705
|
uuid: str = None
|
|
602
706
|
|
|
@@ -650,8 +754,9 @@ class DynamicBlockWrapper(BaseDataClass):
|
|
|
650
754
|
if not self.block:
|
|
651
755
|
return False
|
|
652
756
|
|
|
653
|
-
return self.block.uuid == self.block_run_block_uuid or
|
|
654
|
-
|
|
757
|
+
return self.block.uuid == self.block_run_block_uuid or (
|
|
758
|
+
self.is_replicated() and self.block.uuid_replicated == self.block_run_block_uuid
|
|
759
|
+
)
|
|
655
760
|
|
|
656
761
|
def is_replicated(self) -> bool:
|
|
657
762
|
return DynamicBlockFlag.REPLICATED in (self.flags or []) or is_replicated_block(self.block)
|
|
@@ -676,11 +781,15 @@ class DynamicBlockWrapper(BaseDataClass):
|
|
|
676
781
|
if DynamicBlockFlag.SPAWN_OF_DYNAMIC_CHILD in (self.flags or []):
|
|
677
782
|
return True
|
|
678
783
|
|
|
679
|
-
return (
|
|
680
|
-
self.
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
784
|
+
return (
|
|
785
|
+
(self.block or self.block_uuid)
|
|
786
|
+
and self.block_run_block_uuid
|
|
787
|
+
and (
|
|
788
|
+
(self.block and self.block.uuid != self.block_run_block_uuid)
|
|
789
|
+
or (self.block_uuid and self.block_uuid != self.block_run_block_uuid)
|
|
790
|
+
)
|
|
791
|
+
and not self.is_original(include_clone=True)
|
|
792
|
+
)
|
|
684
793
|
|
|
685
794
|
def should_reduce_output(self) -> bool:
|
|
686
795
|
if DynamicBlockFlag.REDUCE_OUTPUT in (self.flags or []):
|
|
@@ -769,11 +878,13 @@ class DynamicBlockWrapper(BaseDataClass):
|
|
|
769
878
|
**kwargs,
|
|
770
879
|
) -> dict:
|
|
771
880
|
if use_metadata_instructions:
|
|
772
|
-
return ignore_keys_with_blank_values(
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
881
|
+
return ignore_keys_with_blank_values(
|
|
882
|
+
dict(
|
|
883
|
+
clone_original=self.metadata_instructions.clone_original,
|
|
884
|
+
original=self.metadata_instructions.original.to_dict_base(),
|
|
885
|
+
upstream=self.metadata_instructions.upstream.to_dict_base(),
|
|
886
|
+
)
|
|
887
|
+
)
|
|
777
888
|
|
|
778
889
|
data = self.to_dict_base(**kwargs)
|
|
779
890
|
if include_all:
|
|
@@ -906,11 +1017,14 @@ def check_all_dynamic_upstreams_completed(
|
|
|
906
1017
|
|
|
907
1018
|
from mage_ai.orchestration.db.models.schedules import BlockRun
|
|
908
1019
|
|
|
909
|
-
upstreams_done = all([
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1020
|
+
upstreams_done = all([
|
|
1021
|
+
check_all_dynamic_upstreams_completed(
|
|
1022
|
+
b,
|
|
1023
|
+
block_runs=block_runs,
|
|
1024
|
+
execution_partition=execution_partition,
|
|
1025
|
+
)
|
|
1026
|
+
for b in upstream_block.upstream_blocks
|
|
1027
|
+
])
|
|
914
1028
|
|
|
915
1029
|
if not upstreams_done:
|
|
916
1030
|
return False
|
|
@@ -922,17 +1036,26 @@ def check_all_dynamic_upstreams_completed(
|
|
|
922
1036
|
execution_partition=execution_partition,
|
|
923
1037
|
)
|
|
924
1038
|
|
|
925
|
-
selected = [
|
|
926
|
-
br
|
|
927
|
-
|
|
1039
|
+
selected = [
|
|
1040
|
+
br
|
|
1041
|
+
for br in block_runs
|
|
1042
|
+
if pipeline.get_block(
|
|
1043
|
+
br.block_uuid,
|
|
1044
|
+
).uuid
|
|
1045
|
+
== upstream_block.uuid
|
|
1046
|
+
and br.status == BlockRun.BlockRunStatus.COMPLETED
|
|
1047
|
+
]
|
|
928
1048
|
|
|
929
1049
|
if len(list(selected)) < len(combos) + 1:
|
|
930
1050
|
return False
|
|
931
1051
|
|
|
932
|
-
return all([
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
1052
|
+
return all([
|
|
1053
|
+
br.status == BlockRun.BlockRunStatus.COMPLETED
|
|
1054
|
+
for br in filter(
|
|
1055
|
+
lambda br: pipeline.get_block(br.block_uuid).uuid == upstream_block.uuid,
|
|
1056
|
+
block_runs,
|
|
1057
|
+
)
|
|
1058
|
+
])
|
|
936
1059
|
|
|
937
1060
|
# 1. Are all the upstream blocks for my upstream blocks completed?
|
|
938
1061
|
# 2. Then, are my immediate upstream blocks completed?
|