mage-ai 0.9.58__py3-none-any.whl → 0.9.59__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/api/logging.py +11 -7
- mage_ai/api/policies/BlockPolicy.py +1 -0
- mage_ai/api/policies/CommandCenterItemPolicy.py +56 -0
- mage_ai/api/policies/CustomTemplatePolicy.py +0 -3
- mage_ai/api/policies/GitBranchPolicy.py +8 -1
- mage_ai/api/policies/GitFilePolicy.py +1 -0
- mage_ai/api/policies/PipelinePolicy.py +2 -0
- mage_ai/api/policies/PipelineSchedulePolicy.py +1 -0
- mage_ai/api/policies/VersionControlBranchPolicy.py +98 -0
- mage_ai/api/policies/VersionControlFilePolicy.py +96 -0
- mage_ai/api/policies/VersionControlProjectPolicy.py +92 -0
- mage_ai/api/policies/VersionControlRemotePolicy.py +94 -0
- mage_ai/api/presenters/CommandCenterItemPresenter.py +19 -0
- mage_ai/api/presenters/GitBranchPresenter.py +2 -0
- mage_ai/api/presenters/GitCustomBranchPresenter.py +1 -0
- mage_ai/api/presenters/PipelinePresenter.py +5 -5
- mage_ai/api/presenters/PipelineSchedulePresenter.py +4 -0
- mage_ai/api/presenters/VersionControlBranchPresenter.py +15 -0
- mage_ai/api/presenters/VersionControlFilePresenter.py +15 -0
- mage_ai/api/presenters/VersionControlProjectPresenter.py +14 -0
- mage_ai/api/presenters/VersionControlRemotePresenter.py +15 -0
- mage_ai/api/resources/BlockResource.py +110 -80
- mage_ai/api/resources/CommandCenterItemResource.py +29 -0
- mage_ai/api/resources/FileResource.py +15 -1
- mage_ai/api/resources/FolderResource.py +2 -1
- mage_ai/api/resources/GitBranchResource.py +183 -108
- mage_ai/api/resources/GitCustomBranchResource.py +9 -2
- mage_ai/api/resources/GitFileResource.py +26 -13
- mage_ai/api/resources/KernelResource.py +9 -1
- mage_ai/api/resources/LogResource.py +1 -1
- mage_ai/api/resources/OauthResource.py +4 -5
- mage_ai/api/resources/PipelineResource.py +71 -38
- mage_ai/api/resources/PipelineRunResource.py +7 -2
- mage_ai/api/resources/PullRequestResource.py +12 -3
- mage_ai/api/resources/SearchResultResource.py +4 -4
- mage_ai/api/resources/VersionControlBranchResource.py +85 -0
- mage_ai/api/resources/VersionControlFileResource.py +65 -0
- mage_ai/api/resources/VersionControlProjectResource.py +46 -0
- mage_ai/api/resources/VersionControlRemoteResource.py +64 -0
- mage_ai/authentication/oauth/constants.py +13 -16
- mage_ai/authentication/operation_history/models.py +11 -32
- mage_ai/authentication/operation_history/utils.py +14 -14
- mage_ai/authentication/permissions/constants.py +5 -0
- mage_ai/authentication/providers/active_directory.py +2 -2
- mage_ai/authentication/providers/bitbucket.py +2 -2
- mage_ai/authentication/providers/constants.py +6 -12
- mage_ai/authentication/providers/ghe.py +2 -2
- mage_ai/authentication/providers/google.py +2 -2
- mage_ai/authentication/providers/okta.py +2 -2
- mage_ai/cache/base.py +11 -3
- mage_ai/cache/block.py +116 -32
- mage_ai/cache/block_action_object/__init__.py +52 -43
- mage_ai/cache/constants.py +1 -0
- mage_ai/cache/file.py +114 -0
- mage_ai/cache/pipeline.py +34 -8
- mage_ai/cache/tag.py +51 -10
- mage_ai/cache/utils.py +44 -3
- mage_ai/cluster_manager/kubernetes/workload_manager.py +9 -1
- mage_ai/command_center/__init__.py +0 -0
- mage_ai/command_center/applications/__init__.py +0 -0
- mage_ai/command_center/applications/constants.py +96 -0
- mage_ai/command_center/applications/factory.py +54 -0
- mage_ai/command_center/blocks/__init__.py +0 -0
- mage_ai/command_center/blocks/factory.py +39 -0
- mage_ai/command_center/blocks/utils.py +127 -0
- mage_ai/command_center/constants.py +66 -0
- mage_ai/command_center/factory.py +161 -0
- mage_ai/command_center/files/__init__.py +0 -0
- mage_ai/command_center/files/constants.py +235 -0
- mage_ai/command_center/files/factory.py +86 -0
- mage_ai/command_center/models.py +442 -0
- mage_ai/command_center/pipeline_runs/__init__.py +0 -0
- mage_ai/command_center/pipeline_runs/utils.py +141 -0
- mage_ai/command_center/pipelines/__init__.py +0 -0
- mage_ai/command_center/pipelines/constants.py +118 -0
- mage_ai/command_center/pipelines/factory.py +132 -0
- mage_ai/command_center/pipelines/utils.py +120 -0
- mage_ai/command_center/service.py +45 -0
- mage_ai/command_center/settings.py +37 -0
- mage_ai/command_center/support/__init__.py +0 -0
- mage_ai/command_center/support/constants.py +46 -0
- mage_ai/command_center/triggers/__init__.py +0 -0
- mage_ai/command_center/triggers/factory.py +49 -0
- mage_ai/command_center/triggers/utils.py +463 -0
- mage_ai/command_center/utils.py +30 -0
- mage_ai/data_preparation/executors/azure_container_instance_executor.py +1 -1
- mage_ai/data_preparation/executors/block_executor.py +68 -19
- mage_ai/data_preparation/executors/ecs_block_executor.py +2 -2
- mage_ai/data_preparation/executors/executor_factory.py +2 -0
- mage_ai/data_preparation/executors/gcp_cloud_run_block_executor.py +1 -1
- mage_ai/data_preparation/executors/k8s_block_executor.py +2 -2
- mage_ai/data_preparation/executors/pyspark_block_executor.py +7 -1
- mage_ai/data_preparation/git/__init__.py +29 -11
- mage_ai/data_preparation/git/api.py +14 -13
- mage_ai/data_preparation/git/clients/base.py +4 -8
- mage_ai/data_preparation/git/clients/github.py +1 -0
- mage_ai/data_preparation/git/utils.py +5 -7
- mage_ai/data_preparation/models/block/__init__.py +556 -329
- mage_ai/data_preparation/models/block/content.py +111 -0
- mage_ai/data_preparation/models/block/data_integration/mixins.py +1 -0
- mage_ai/data_preparation/models/block/dbt/block.py +29 -19
- mage_ai/data_preparation/models/block/dbt/block_sql.py +50 -260
- mage_ai/data_preparation/models/block/dbt/block_yaml.py +74 -156
- mage_ai/data_preparation/models/block/dbt/dbt_adapter.py +22 -10
- mage_ai/data_preparation/models/block/dbt/profiles.py +19 -15
- mage_ai/data_preparation/models/block/dbt/project.py +3 -0
- mage_ai/data_preparation/models/block/dynamic/constants.py +0 -0
- mage_ai/data_preparation/models/block/dynamic/dynamic_child.py +507 -47
- mage_ai/data_preparation/models/block/dynamic/utils.py +432 -1
- mage_ai/data_preparation/models/block/platform/mixins.py +68 -44
- mage_ai/data_preparation/models/block/r/__init__.py +19 -9
- mage_ai/data_preparation/models/block/sql/__init__.py +34 -20
- mage_ai/data_preparation/models/block/sql/utils/shared.py +4 -1
- mage_ai/data_preparation/models/block/utils.py +176 -71
- mage_ai/data_preparation/models/constants.py +7 -0
- mage_ai/data_preparation/models/file.py +21 -2
- mage_ai/data_preparation/models/pipeline.py +20 -8
- mage_ai/data_preparation/models/project/__init__.py +12 -7
- mage_ai/data_preparation/models/project/constants.py +1 -0
- mage_ai/data_preparation/models/triggers/__init__.py +7 -0
- mage_ai/data_preparation/models/utils.py +20 -0
- mage_ai/data_preparation/models/variable.py +113 -15
- mage_ai/data_preparation/shared/utils.py +6 -3
- mage_ai/data_preparation/storage/base_storage.py +17 -0
- mage_ai/data_preparation/storage/gcs_storage.py +4 -0
- mage_ai/data_preparation/storage/local_storage.py +15 -0
- mage_ai/data_preparation/storage/s3_storage.py +4 -0
- mage_ai/data_preparation/templates/data_exporters/qdrant.py +0 -1
- mage_ai/data_preparation/templates/data_loaders/qdrant.py +2 -1
- mage_ai/data_preparation/variable_manager.py +1 -0
- mage_ai/io/base.py +4 -1
- mage_ai/io/bigquery.py +25 -16
- mage_ai/io/clickhouse.py +3 -0
- mage_ai/io/druid.py +3 -0
- mage_ai/io/mongodb.py +1 -1
- mage_ai/io/pinot.py +3 -0
- mage_ai/io/postgres.py +13 -0
- mage_ai/io/snowflake.py +4 -0
- mage_ai/io/spark.py +8 -3
- mage_ai/io/sql.py +6 -0
- mage_ai/orchestration/db/__init__.py +26 -19
- mage_ai/orchestration/db/cache.py +4 -3
- mage_ai/orchestration/db/models/schedules.py +72 -16
- mage_ai/orchestration/db/models/schedules_project_platform.py +2 -3
- mage_ai/orchestration/pipeline_scheduler_original.py +19 -11
- mage_ai/orchestration/pipeline_scheduler_project_platform.py +20 -11
- mage_ai/presenters/interactions/constants.py +1 -0
- mage_ai/presenters/interactions/models.py +4 -3
- mage_ai/presenters/pages/models/client_pages/pipeline_schedules.py +1 -1
- mage_ai/server/constants.py +1 -1
- mage_ai/server/frontend_dist/404.html +11 -11
- mage_ai/server/frontend_dist/_next/static/PPQxHOmWVJ0iQFzG2rc8m/_buildManifest.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/1235.c9ed47779baccc05.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/125-029194ff22eb33a5.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/1557-4f7485c2e2228f77.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/2474-8e702cea23ddd16d.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/2479-727fa69ee9be6fab.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/26-38bc9380422f3900.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/2717-3e7ea8543b3825b7.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/3366-420721116ea5a665.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/3449-a9c98239582cd6f0.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/3548-13563a1ff815f922.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/3943-9e0a8ba0db34b35f.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/4371-ef23f95888d6cd11.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/4632.a4171dbf46b31c7c.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/523-be11ad59861d00ca.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/5457-d582b00545b4cb5e.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/5831-2abc4063e887a03e.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/6085-692d2f784c0504f2.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/635-1e8857c2b6dde289.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/7022-0d52dd8868621fb0.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/7264-d05f4b7088533f6f.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/7361-b3d661ec743bfadf.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/737-cc6467310a130dd9.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/{4495-4f0340aa82e0c623.js → 7674-9ec4fe64b5bf64d5.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/8038-85d715c8c8394827.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/8095-bdce03896ef9639a.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/8146-6bed4e7401e067e6.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/8192-0c0b91523a38c4ca.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/8432-f736d101fc6d9215.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/8513-d207733b485c8d03.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/9264-e7e040a54d34360c.js → frontend_dist/_next/static/chunks/9264-7cd9cd0ba86ec5e4.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9265-d2a1aaec75ec69b8.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/9440-54add041c392517f.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/9624-59b2f803f9c88cd6.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/9832-67896490f6e8a014.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/bd1a647f.fe5d87096be24a62.js → frontend_dist/_next/static/chunks/bd1a647f.04f7913662092327.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/404-7cabe357906f44f2.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-a11bd2ebe11b3fd2.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/block-layout-ffca51945cd154ef.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/compute-3ba957769292db80.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/files-45679fd18b3edd82.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-95735a218106aa99.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/{global-data-products-cf98c2e4d20fd92c.js → global-data-products-81d6c7fd9a9cff38.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-eb4421d51fb7368f.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks-a8c712e20512fede.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/files-f1be1d4735ba6919.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-febe676687966276.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/[user]-70efe222130490b5.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-0914c36b3c8fd59f.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/{users-81e6e5319a59cd07.js → users-4f12e989e7809ef9.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-809d4c99b44991a1.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/oauth-0436d395963cd27a.js → frontend_dist/_next/static/chunks/pages/oauth-aa9079c8dbaea3a5.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-4e30fb5b18383b71.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipeline-runs-5d31c3aace39182d.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-85a80ee66f60a65c.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-0bd74047e257e6d9.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-80619dc504d0103b.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-3cc8d74ff8525bfd.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-cdc379ff24ff8858.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-03396d6086003e16.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-d6d920758654f6d9.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-27727bb87be506c3.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-16aab67743651a0b.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-e3ca1bedb660b252.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-9d58701fe7213727.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-0041fd76ee15e49f.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-780be9a2da697915.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-db8bb970b1f2273f.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-a3422b0ab1dbacd7.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks/[...slug]-987a1603f4201943.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks-3dc8bf89cab2722b.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-43d3f2a5071b9537.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-c97b1a39b22c112a.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/settings-49efb66da67554ca.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-be6aaec07c138656.js → [...slug]-5117d3555972484c.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions-ee1c19d4a192ae4d.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-4dc5724486ee3396.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-f380d293cff7592b.js → [...slug]-fa095aac732368c3.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{roles-ddce04fae28bd7f6.js → roles-db6d71f8692a33e7.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-99c6a263d2ab9553.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/{[...slug]-213a43564fdfbe17.js → [...slug]-9d881ac0a3db9baa.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users-bee414d57c4b55d7.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/sign-in-e7030e1a7a9e88e1.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/templates/[...slug]-312afc9a3f8d0a4f.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/templates-e5300c340aa94c6b.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-fa7ca0c86142d146.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/test-bd51b3918b39329e.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-5158a9d98d2459e8.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-5ce099a7abb354ff.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/{webpack-fea697dd168c6d0c.js → webpack-efa55343114c8128.js} +1 -1
- mage_ai/server/{frontend_dist_base_path_template/_next/static/css/d1e8e64d0b07af2f.css → frontend_dist/_next/static/css/b59541b123fd7191.css} +1 -1
- mage_ai/server/frontend_dist/block-layout.html +3 -3
- mage_ai/server/frontend_dist/compute.html +11 -11
- mage_ai/server/frontend_dist/files.html +11 -11
- mage_ai/server/frontend_dist/global-data-products/[...slug].html +11 -11
- mage_ai/server/frontend_dist/global-data-products.html +11 -11
- mage_ai/server/frontend_dist/global-hooks/[...slug].html +11 -11
- mage_ai/server/frontend_dist/global-hooks.html +11 -11
- mage_ai/server/frontend_dist/index.html +3 -3
- mage_ai/server/frontend_dist/manage/files.html +11 -11
- mage_ai/server/frontend_dist/manage/settings.html +11 -11
- mage_ai/server/frontend_dist/manage/users/[user].html +11 -11
- mage_ai/server/frontend_dist/manage/users/new.html +11 -11
- mage_ai/server/frontend_dist/manage/users.html +11 -11
- mage_ai/server/frontend_dist/manage.html +11 -11
- mage_ai/server/frontend_dist/oauth.html +8 -8
- mage_ai/server/frontend_dist/overview.html +11 -11
- mage_ai/server/frontend_dist/pipeline-runs.html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +3 -3
- mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +11 -11
- mage_ai/server/frontend_dist/pipelines/[pipeline].html +3 -3
- mage_ai/server/frontend_dist/pipelines.html +11 -11
- mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +11 -11
- mage_ai/server/frontend_dist/platform/global-hooks.html +11 -11
- mage_ai/server/frontend_dist/settings/account/profile.html +11 -11
- mage_ai/server/frontend_dist/settings/platform/preferences.html +11 -11
- mage_ai/server/frontend_dist/settings/platform/settings.html +11 -11
- mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +11 -11
- mage_ai/server/frontend_dist/settings/workspace/permissions.html +11 -11
- mage_ai/server/frontend_dist/settings/workspace/preferences.html +11 -11
- mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +11 -11
- mage_ai/server/frontend_dist/settings/workspace/roles.html +11 -11
- mage_ai/server/frontend_dist/settings/workspace/sync-data.html +11 -11
- mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +11 -11
- mage_ai/server/frontend_dist/settings/workspace/users.html +11 -11
- mage_ai/server/frontend_dist/settings.html +3 -3
- mage_ai/server/frontend_dist/sign-in.html +41 -41
- mage_ai/server/frontend_dist/templates/[...slug].html +11 -11
- mage_ai/server/frontend_dist/templates.html +11 -11
- mage_ai/server/frontend_dist/terminal.html +11 -11
- mage_ai/server/frontend_dist/test.html +3 -5
- mage_ai/server/frontend_dist/triggers.html +11 -11
- mage_ai/server/frontend_dist/version-control.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/404.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1235.c9ed47779baccc05.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/125-029194ff22eb33a5.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-4f7485c2e2228f77.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2474-8e702cea23ddd16d.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2479-727fa69ee9be6fab.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/26-38bc9380422f3900.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2717-3e7ea8543b3825b7.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3366-420721116ea5a665.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3449-a9c98239582cd6f0.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3548-13563a1ff815f922.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3943-9e0a8ba0db34b35f.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4371-ef23f95888d6cd11.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4632.a4171dbf46b31c7c.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/523-be11ad59861d00ca.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-d582b00545b4cb5e.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5831-2abc4063e887a03e.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6085-692d2f784c0504f2.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/635-1e8857c2b6dde289.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-0d52dd8868621fb0.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7264-d05f4b7088533f6f.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-b3d661ec743bfadf.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/737-cc6467310a130dd9.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{4495-4f0340aa82e0c623.js → 7674-9ec4fe64b5bf64d5.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8038-85d715c8c8394827.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8095-bdce03896ef9639a.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-6bed4e7401e067e6.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8192-0c0b91523a38c4ca.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8432-f736d101fc6d9215.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8513-d207733b485c8d03.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/9264-e7e040a54d34360c.js → frontend_dist_base_path_template/_next/static/chunks/9264-7cd9cd0ba86ec5e4.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9265-d2a1aaec75ec69b8.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-54add041c392517f.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9624-59b2f803f9c88cd6.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9832-67896490f6e8a014.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/bd1a647f.fe5d87096be24a62.js → frontend_dist_base_path_template/_next/static/chunks/bd1a647f.04f7913662092327.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/404-7cabe357906f44f2.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-a11bd2ebe11b3fd2.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/block-layout-ffca51945cd154ef.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/compute-3ba957769292db80.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-45679fd18b3edd82.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-95735a218106aa99.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{global-data-products-cf98c2e4d20fd92c.js → global-data-products-81d6c7fd9a9cff38.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-eb4421d51fb7368f.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks-a8c712e20512fede.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/files-f1be1d4735ba6919.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-febe676687966276.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-70efe222130490b5.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-0914c36b3c8fd59f.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/{users-81e6e5319a59cd07.js → users-4f12e989e7809ef9.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-809d4c99b44991a1.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/oauth-0436d395963cd27a.js → frontend_dist_base_path_template/_next/static/chunks/pages/oauth-aa9079c8dbaea3a5.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-4e30fb5b18383b71.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-5d31c3aace39182d.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-85a80ee66f60a65c.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-0bd74047e257e6d9.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-80619dc504d0103b.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-3cc8d74ff8525bfd.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-cdc379ff24ff8858.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-03396d6086003e16.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-d6d920758654f6d9.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-27727bb87be506c3.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-16aab67743651a0b.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-e3ca1bedb660b252.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-9d58701fe7213727.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-0041fd76ee15e49f.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-780be9a2da697915.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-db8bb970b1f2273f.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-a3422b0ab1dbacd7.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks/[...slug]-987a1603f4201943.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks-3dc8bf89cab2722b.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-43d3f2a5071b9537.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-c97b1a39b22c112a.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-49efb66da67554ca.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/{[...slug]-be6aaec07c138656.js → [...slug]-5117d3555972484c.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions-ee1c19d4a192ae4d.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-4dc5724486ee3396.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/{[...slug]-f380d293cff7592b.js → [...slug]-fa095aac732368c3.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{roles-ddce04fae28bd7f6.js → roles-db6d71f8692a33e7.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-99c6a263d2ab9553.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/{[...slug]-213a43564fdfbe17.js → [...slug]-9d881ac0a3db9baa.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users-bee414d57c4b55d7.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-e7030e1a7a9e88e1.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates/[...slug]-312afc9a3f8d0a4f.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates-e5300c340aa94c6b.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-fa7ca0c86142d146.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-bd51b3918b39329e.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-5158a9d98d2459e8.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-5ce099a7abb354ff.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{webpack-d30cb09c85b4c4f0.js → webpack-bd35e1c7bd7b5a9a.js} +1 -1
- mage_ai/server/{frontend_dist/_next/static/css/d1e8e64d0b07af2f.css → frontend_dist_base_path_template/_next/static/css/b59541b123fd7191.css} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/do4WOsw7lNhouR0mtPTFi/_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 +11 -11
- mage_ai/server/frontend_dist_base_path_template/files.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +11 -11
- mage_ai/server/frontend_dist_base_path_template/global-data-products.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +11 -11
- mage_ai/server/frontend_dist_base_path_template/global-hooks.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/index.html +3 -3
- mage_ai/server/frontend_dist_base_path_template/manage/files.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/manage/settings.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +11 -11
- mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/manage/users.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/manage.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/oauth.html +8 -8
- mage_ai/server/frontend_dist_base_path_template/overview.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +11 -11
- 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 +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +3 -3
- mage_ai/server/frontend_dist_base_path_template/pipelines.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +11 -11
- mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +11 -11
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +11 -11
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +11 -11
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/settings.html +3 -3
- mage_ai/server/frontend_dist_base_path_template/sign-in.html +39 -39
- mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +11 -11
- mage_ai/server/frontend_dist_base_path_template/templates.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/terminal.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/test.html +3 -5
- mage_ai/server/frontend_dist_base_path_template/triggers.html +11 -11
- mage_ai/server/frontend_dist_base_path_template/version-control.html +11 -11
- mage_ai/server/logger.py +8 -2
- mage_ai/server/server.py +18 -1
- mage_ai/services/aws/ecs/config.py +3 -3
- mage_ai/services/aws/ecs/ecs.py +2 -2
- mage_ai/services/search/block_action_objects.py +59 -5
- mage_ai/settings/models/configuration_option.py +3 -1
- mage_ai/settings/platform/__init__.py +54 -18
- mage_ai/settings/repo.py +5 -4
- mage_ai/shared/custom_logger.py +213 -0
- mage_ai/shared/environments.py +4 -0
- mage_ai/shared/files.py +52 -1
- mage_ai/shared/models.py +2 -1
- mage_ai/shared/parsers.py +8 -1
- mage_ai/shared/path_fixer.py +62 -5
- mage_ai/shared/retry.py +4 -0
- mage_ai/shared/strings.py +4 -0
- mage_ai/tests/api/endpoints/test_blocks.py +101 -1
- mage_ai/tests/api/operations/base/test_base_with_user_permissions.py +4 -1
- mage_ai/tests/base_test.py +21 -2
- mage_ai/tests/cache/test_pipeline_cache.py +11 -8
- mage_ai/tests/data_preparation/executors/test_block_executor.py +55 -45
- mage_ai/tests/data_preparation/git/test_api.py +4 -4
- mage_ai/tests/data_preparation/models/block/dbt/test_block.py +75 -43
- mage_ai/tests/data_preparation/models/block/dbt/test_block_sql.py +329 -329
- mage_ai/tests/data_preparation/models/block/dbt/test_block_yaml.py +296 -296
- mage_ai/tests/data_preparation/models/block/dbt/test_dbt_adapter.py +2 -2
- mage_ai/tests/data_preparation/models/block/dbt/test_dbt_cli.py +4 -4
- mage_ai/tests/data_preparation/models/block/dbt/test_profiles.py +2 -2
- mage_ai/tests/data_preparation/models/block/dbt/test_project.py +2 -2
- mage_ai/tests/data_preparation/models/block/dbt/test_sources.py +2 -2
- mage_ai/tests/data_preparation/models/block/dynamic/test_dynamic_child_block_factory.py +477 -474
- mage_ai/tests/data_preparation/models/block/dynamic/test_dynamic_helpers.py +25 -24
- mage_ai/tests/data_preparation/models/block/platform/test_mixins.py +16 -25
- mage_ai/tests/data_preparation/models/block/test_utils.py +8 -8
- mage_ai/tests/data_preparation/models/test_block.py +6 -8
- mage_ai/tests/data_preparation/models/test_project.py +10 -5
- mage_ai/tests/data_preparation/models/test_variable.py +51 -4
- mage_ai/tests/orchestration/test_pipeline_scheduler_project_platform.py +1 -0
- mage_ai/version_control/__init__.py +0 -0
- mage_ai/version_control/models.py +288 -0
- {mage_ai-0.9.58.dist-info → mage_ai-0.9.59.dist-info}/METADATA +6 -6
- {mage_ai-0.9.58.dist-info → mage_ai-0.9.59.dist-info}/RECORD +490 -476
- mage_ai/server/frontend_dist/_next/static/0XnQ0C0nTr1w0o9CGC7wQ/_buildManifest.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1124-d8fc76201b83b376.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1154-2f262f7eb38ebaa1.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1235.53172e14801844e5.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1550-32333b36ac6b061b.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1557-7cfe722a9b83b935.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1598-dd776e3a92e9cccd.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1751-5adf859690505d7b.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1952-b2197a87dd67d8e0.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2056-0ea1faa46646a77e.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2213-52267f1e9ef5751c.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2474-352ae192b826d896.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2512-46141494a1b75897.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2717-accc279ae116b1b9.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2852872c-15b31a7081e6a868.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2886-9e73e1f48f248741.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2920.86a65e5f26ff1795.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/3437-6055fd5aa82880f6.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/3449-214fce1a0e623b47.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/3494-23a9cc2cd649abac.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/3745-3662911c364d917b.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/3763-70c7eb1fc203c903.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/3943-a49377acc514e77f.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/4052-f89c85d2c8f51931.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/4296-14eaf96d6479e673.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/4804-1254a474f238d078.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/5283-9df961e430a79bea.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/5457-b373ebdf4d05d8e2.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/5499-bc2528f8e18f61a6.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/5810-e66141c1271bced6.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/5849-f30d8694e3318a81.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/5896-7b8e36634d7d94eb.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/6043-728790621ca9014c.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/6050-e48b7f97e96bbcb6.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/6285-648f9a732e100b2f.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/6639-74eefed142e14ea6.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/6965-c613d1834c8ed92d.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/7022-ea92cb336bd1aab8.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/7361-06ef4c642a8fe8c4.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/7858-677c641010ac9160.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/8125-b9d53e425b6ddc7e.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/8146-fb8f445644e573b0.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/8432-0ace6fb7bdbc6864.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/844-1e171f361e63b36d.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9269-40e2101f56399dcc.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9302-913007e2f801ad65.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9440-c51bf1e8f271cb25.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9624-89a4b20eb3b3c754.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/976-0a8c2c4d7acd957b.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9775-c1142b1312e8f95d.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/404-5ddd12931e0e3e41.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-ec5e62e8e5bb4e4c.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/block-layout-44d7291d8f29eb36.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/compute-a6661a9c3647532a.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/files-26b899d3adb4ed19.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/[...slug]-9bd164317e652311.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks/[...slug]-c87d46dc53e35638.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/global-hooks-24785a5ed4eb340d.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/files-2c5fd116ecfacb33.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-8c9285af31efa3fd.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/[user]-ec7e0419a64ae3b2.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-039e083cc068da54.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-8e4d4f6edc515265.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-b73185fdcb7a131c.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipeline-runs-97b3335bf60f8b07.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-83de126136539668.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-50f45e96892cfb63.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-5fe0f1de6fd365f8.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-306db9e11fa94d21.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-ebea4be0562b08e3.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-f09d21d5c2661504.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-61e770f155ae22ef.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors-d347a4614130e2ab.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-056c5e5080a3754f.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-208fa8de91f152bc.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-a32e02f46a816eb3.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-8012388b15f0e0a5.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-6714c72f90923cfb.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-afc0525ef27fe1f2.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-a91e7d86cd0540d9.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks/[...slug]-7c8e5a8908fe9c83.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/platform/global-hooks-be0684d1527587d8.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-147660a34351147c.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-ec5f01b683920ced.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/settings-28aa4512c0e23ec5.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions-a2850b2e0a282d16.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-b1df80674dca4713.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-41abcd2241958dc8.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users-a2c5859f53b5e9e1.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/sign-in-1aea2a0c373bc6ae.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/templates/[...slug]-e7485742708215d2.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/templates-b4086d30a89d6801.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-3cd171f43f0a0df8.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/test-6a22493285c47ba2.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-ad20a31dde4fe59b.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-267952b4c87927c7.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/RC0Yenm06LvZI-RWFoT5C/_buildManifest.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1124-d8fc76201b83b376.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1154-2f262f7eb38ebaa1.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1235.53172e14801844e5.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1550-32333b36ac6b061b.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-7cfe722a9b83b935.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1598-dd776e3a92e9cccd.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1751-5adf859690505d7b.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1952-b2197a87dd67d8e0.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2056-0ea1faa46646a77e.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2213-52267f1e9ef5751c.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2474-352ae192b826d896.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2512-46141494a1b75897.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2717-accc279ae116b1b9.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2852872c-15b31a7081e6a868.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2886-9e73e1f48f248741.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2920.86a65e5f26ff1795.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3437-6055fd5aa82880f6.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3449-214fce1a0e623b47.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3494-23a9cc2cd649abac.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3745-3662911c364d917b.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3763-70c7eb1fc203c903.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3943-a49377acc514e77f.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4052-f89c85d2c8f51931.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4296-14eaf96d6479e673.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4804-1254a474f238d078.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5283-9df961e430a79bea.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-b373ebdf4d05d8e2.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5499-bc2528f8e18f61a6.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5810-e66141c1271bced6.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5849-f30d8694e3318a81.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5896-7b8e36634d7d94eb.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6043-728790621ca9014c.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6050-e48b7f97e96bbcb6.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6285-648f9a732e100b2f.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6639-74eefed142e14ea6.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6965-c613d1834c8ed92d.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-ea92cb336bd1aab8.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-06ef4c642a8fe8c4.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7858-677c641010ac9160.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8125-b9d53e425b6ddc7e.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-fb8f445644e573b0.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8432-0ace6fb7bdbc6864.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/844-1e171f361e63b36d.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9269-40e2101f56399dcc.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9302-913007e2f801ad65.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9440-c51bf1e8f271cb25.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9624-89a4b20eb3b3c754.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/976-0a8c2c4d7acd957b.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9775-c1142b1312e8f95d.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/404-5ddd12931e0e3e41.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-ec5e62e8e5bb4e4c.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/block-layout-44d7291d8f29eb36.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/compute-a6661a9c3647532a.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-26b899d3adb4ed19.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/[...slug]-9bd164317e652311.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks/[...slug]-c87d46dc53e35638.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-hooks-24785a5ed4eb340d.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/files-2c5fd116ecfacb33.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-8c9285af31efa3fd.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-ec7e0419a64ae3b2.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-039e083cc068da54.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-8e4d4f6edc515265.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-b73185fdcb7a131c.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-97b3335bf60f8b07.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-83de126136539668.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-50f45e96892cfb63.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-5fe0f1de6fd365f8.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-306db9e11fa94d21.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-ebea4be0562b08e3.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runs-f09d21d5c2661504.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/block-runtime-61e770f155ae22ef.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors-d347a4614130e2ab.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-056c5e5080a3754f.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-208fa8de91f152bc.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-a32e02f46a816eb3.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-8012388b15f0e0a5.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-6714c72f90923cfb.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-afc0525ef27fe1f2.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-a91e7d86cd0540d9.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks/[...slug]-7c8e5a8908fe9c83.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/platform/global-hooks-be0684d1527587d8.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-147660a34351147c.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-ec5f01b683920ced.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-28aa4512c0e23ec5.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions-a2850b2e0a282d16.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-b1df80674dca4713.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-41abcd2241958dc8.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users-a2c5859f53b5e9e1.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-1aea2a0c373bc6ae.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates/[...slug]-e7485742708215d2.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates-b4086d30a89d6801.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-3cd171f43f0a0df8.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/test-6a22493285c47ba2.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-ad20a31dde4fe59b.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-267952b4c87927c7.js +0 -1
- /mage_ai/server/frontend_dist/_next/static/{0XnQ0C0nTr1w0o9CGC7wQ → PPQxHOmWVJ0iQFzG2rc8m}/_ssgManifest.js +0 -0
- /mage_ai/server/frontend_dist_base_path_template/_next/static/{RC0Yenm06LvZI-RWFoT5C → do4WOsw7lNhouR0mtPTFi}/_ssgManifest.js +0 -0
- {mage_ai-0.9.58.dist-info → mage_ai-0.9.59.dist-info}/LICENSE +0 -0
- {mage_ai-0.9.58.dist-info → mage_ai-0.9.59.dist-info}/WHEEL +0 -0
- {mage_ai-0.9.58.dist-info → mage_ai-0.9.59.dist-info}/entry_points.txt +0 -0
- {mage_ai-0.9.58.dist-info → mage_ai-0.9.59.dist-info}/top_level.txt +0 -0
|
@@ -18,6 +18,7 @@ from typing import Any, Callable, Dict, Generator, List, Set, Tuple, Union
|
|
|
18
18
|
|
|
19
19
|
import inflection
|
|
20
20
|
import pandas as pd
|
|
21
|
+
import polars as pl
|
|
21
22
|
import simplejson
|
|
22
23
|
import yaml
|
|
23
24
|
from jinja2 import Template
|
|
@@ -28,12 +29,20 @@ from mage_ai.data_cleaner.shared.utils import is_geo_dataframe, is_spark_datafra
|
|
|
28
29
|
from mage_ai.data_integrations.sources.constants import SQL_SOURCES_MAPPING
|
|
29
30
|
from mage_ai.data_preparation.logging.logger import DictLogger
|
|
30
31
|
from mage_ai.data_preparation.logging.logger_manager_factory import LoggerManagerFactory
|
|
32
|
+
from mage_ai.data_preparation.models.block.content import hydrate_block_outputs
|
|
31
33
|
from mage_ai.data_preparation.models.block.data_integration.mixins import (
|
|
32
34
|
DataIntegrationMixin,
|
|
33
35
|
)
|
|
34
36
|
from mage_ai.data_preparation.models.block.data_integration.utils import (
|
|
35
37
|
execute_data_integration,
|
|
36
38
|
)
|
|
39
|
+
from mage_ai.data_preparation.models.block.dynamic.utils import (
|
|
40
|
+
DynamicBlockFlag,
|
|
41
|
+
is_dynamic_block,
|
|
42
|
+
is_dynamic_block_child,
|
|
43
|
+
should_reduce_output,
|
|
44
|
+
uuid_for_output_variables,
|
|
45
|
+
)
|
|
37
46
|
from mage_ai.data_preparation.models.block.errors import HasDownstreamDependencies
|
|
38
47
|
from mage_ai.data_preparation.models.block.extension.utils import handle_run_tests
|
|
39
48
|
from mage_ai.data_preparation.models.block.platform.mixins import (
|
|
@@ -45,12 +54,9 @@ from mage_ai.data_preparation.models.block.utils import (
|
|
|
45
54
|
clean_name,
|
|
46
55
|
fetch_input_variables,
|
|
47
56
|
input_variables,
|
|
48
|
-
is_dynamic_block,
|
|
49
|
-
is_dynamic_block_child,
|
|
50
57
|
is_output_variable,
|
|
51
58
|
is_valid_print_variable,
|
|
52
59
|
output_variables,
|
|
53
|
-
should_reduce_output,
|
|
54
60
|
)
|
|
55
61
|
from mage_ai.data_preparation.models.constants import (
|
|
56
62
|
BLOCK_LANGUAGE_TO_FILE_EXTENSION,
|
|
@@ -76,20 +82,22 @@ from mage_ai.data_preparation.shared.stream import StreamToLogger
|
|
|
76
82
|
from mage_ai.data_preparation.shared.utils import get_template_vars
|
|
77
83
|
from mage_ai.data_preparation.templates.data_integrations.utils import get_templates
|
|
78
84
|
from mage_ai.data_preparation.templates.template import load_template
|
|
79
|
-
from mage_ai.data_preparation.templates.utils import get_variable_for_template
|
|
80
85
|
from mage_ai.server.kernel_output_parser import DataType
|
|
81
86
|
from mage_ai.services.spark.config import SparkConfig
|
|
82
87
|
from mage_ai.services.spark.spark import get_spark_session
|
|
83
88
|
from mage_ai.settings.platform.constants import project_platform_activated
|
|
84
89
|
from mage_ai.settings.repo import get_repo_path
|
|
85
90
|
from mage_ai.shared.constants import ENV_DEV, ENV_TEST
|
|
91
|
+
from mage_ai.shared.custom_logger import DX_PRINTER
|
|
86
92
|
from mage_ai.shared.environments import get_env, is_debug
|
|
87
93
|
from mage_ai.shared.hash import extract, ignore_keys, merge_dict
|
|
88
94
|
from mage_ai.shared.logger import BlockFunctionExec
|
|
89
95
|
from mage_ai.shared.parsers import encode_complex
|
|
90
96
|
from mage_ai.shared.path_fixer import (
|
|
97
|
+
add_absolute_path,
|
|
91
98
|
add_root_repo_path_to_relative_path,
|
|
92
99
|
get_path_parts,
|
|
100
|
+
remove_base_repo_path,
|
|
93
101
|
)
|
|
94
102
|
from mage_ai.shared.strings import format_enum
|
|
95
103
|
from mage_ai.shared.utils import clean_name as clean_name_orig
|
|
@@ -337,14 +345,8 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
337
345
|
|
|
338
346
|
# Replicate block
|
|
339
347
|
self.replicated_block = replicated_block
|
|
340
|
-
self.
|
|
341
|
-
|
|
342
|
-
self.replicated_block_object = Block(
|
|
343
|
-
self.replicated_block,
|
|
344
|
-
self.replicated_block,
|
|
345
|
-
self.type,
|
|
346
|
-
language=self.language,
|
|
347
|
-
)
|
|
348
|
+
self.replicated_blocks = {}
|
|
349
|
+
self._replicated_block_object = None
|
|
348
350
|
|
|
349
351
|
# Module for the block functions. Will be set when the block is executed from a notebook.
|
|
350
352
|
self.module = None
|
|
@@ -399,9 +401,26 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
399
401
|
def configuration(self, x) -> None:
|
|
400
402
|
self._configuration = self.clean_file_paths(x) if x else x
|
|
401
403
|
|
|
404
|
+
def get_original_block(self) -> 'Block':
|
|
405
|
+
if self.replicated_block:
|
|
406
|
+
return self.replicated_block_object.get_original_block()
|
|
407
|
+
return self
|
|
408
|
+
|
|
409
|
+
@property
|
|
410
|
+
def replicated_block_object(self) -> 'Block':
|
|
411
|
+
if self._replicated_block_object:
|
|
412
|
+
return self._replicated_block_object
|
|
413
|
+
|
|
414
|
+
if self.replicated_block and self.pipeline:
|
|
415
|
+
self._replicated_block_object = self.pipeline.get_block(self.replicated_block)
|
|
416
|
+
if self._replicated_block_object:
|
|
417
|
+
self._replicated_block_object.replicated_blocks[self.uuid] = self
|
|
418
|
+
|
|
419
|
+
return self._replicated_block_object
|
|
420
|
+
|
|
402
421
|
@property
|
|
403
422
|
def content(self) -> str:
|
|
404
|
-
if self.replicated_block:
|
|
423
|
+
if self.replicated_block and self.replicated_block_object:
|
|
405
424
|
self._content = self.replicated_block_object.content
|
|
406
425
|
|
|
407
426
|
if self._content is None:
|
|
@@ -422,7 +441,7 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
422
441
|
return None
|
|
423
442
|
|
|
424
443
|
async def content_async(self) -> str:
|
|
425
|
-
if self.replicated_block:
|
|
444
|
+
if self.replicated_block and self.replicated_block_object:
|
|
426
445
|
self._content = await self.replicated_block_object.content_async()
|
|
427
446
|
|
|
428
447
|
if self._content is None:
|
|
@@ -430,6 +449,44 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
430
449
|
|
|
431
450
|
return self._content
|
|
432
451
|
|
|
452
|
+
def interpolate_content(
|
|
453
|
+
self,
|
|
454
|
+
content: str,
|
|
455
|
+
dynamic_block_index: int = None,
|
|
456
|
+
dynamic_block_indexes: int = None,
|
|
457
|
+
dynamic_upstream_block_uuids: int = None,
|
|
458
|
+
execution_partition: str = None,
|
|
459
|
+
from_notebook: bool = False,
|
|
460
|
+
outputs_from_input_vars: Dict = None,
|
|
461
|
+
upstream_block_uuids: List[str] = None,
|
|
462
|
+
variables: Dict = None,
|
|
463
|
+
**kwargs,
|
|
464
|
+
) -> str:
|
|
465
|
+
variables = variables or {}
|
|
466
|
+
if self.pipeline and self.pipeline.variables:
|
|
467
|
+
variables.update(self.pipeline.variables)
|
|
468
|
+
|
|
469
|
+
if upstream_block_uuids is None:
|
|
470
|
+
upstream_block_uuids = self.upstream_block_uuids
|
|
471
|
+
|
|
472
|
+
if outputs_from_input_vars is None:
|
|
473
|
+
outputs_from_input_vars, _input_vars, _kwargs_vars, upstream_block_uuids = \
|
|
474
|
+
self.__get_outputs_from_input_vars(
|
|
475
|
+
dynamic_block_index=dynamic_block_index,
|
|
476
|
+
dynamic_block_indexes=dynamic_block_indexes,
|
|
477
|
+
dynamic_upstream_block_uuids=dynamic_upstream_block_uuids,
|
|
478
|
+
execution_partition=execution_partition,
|
|
479
|
+
from_notebook=from_notebook,
|
|
480
|
+
global_vars=variables,
|
|
481
|
+
)
|
|
482
|
+
|
|
483
|
+
return hydrate_block_outputs(
|
|
484
|
+
content,
|
|
485
|
+
outputs_from_input_vars=outputs_from_input_vars,
|
|
486
|
+
upstream_block_uuids=upstream_block_uuids,
|
|
487
|
+
variables=variables,
|
|
488
|
+
)
|
|
489
|
+
|
|
433
490
|
async def metadata_async(self) -> Dict:
|
|
434
491
|
if self.is_data_integration():
|
|
435
492
|
grouped_templates = get_templates(group_templates=True)
|
|
@@ -437,59 +494,7 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
437
494
|
if BlockLanguage.YAML == self.language:
|
|
438
495
|
content = await self.content_async()
|
|
439
496
|
if content:
|
|
440
|
-
|
|
441
|
-
if self.pipeline and self.pipeline.variables:
|
|
442
|
-
variables.update(self.pipeline.variables)
|
|
443
|
-
|
|
444
|
-
def _block_output(
|
|
445
|
-
block_uuid: str,
|
|
446
|
-
parse: str = None,
|
|
447
|
-
current_block=self,
|
|
448
|
-
global_vars=variables,
|
|
449
|
-
) -> Any:
|
|
450
|
-
data = None
|
|
451
|
-
|
|
452
|
-
if not self.fetched_inputs_from_blocks:
|
|
453
|
-
input_vars_fetched, _kwargs_vars, _upstream_block_uuids = \
|
|
454
|
-
self.fetch_input_variables_and_catalog(
|
|
455
|
-
None,
|
|
456
|
-
None,
|
|
457
|
-
global_vars=global_vars,
|
|
458
|
-
from_notebook=True,
|
|
459
|
-
)
|
|
460
|
-
self.fetched_inputs_from_blocks = input_vars_fetched
|
|
461
|
-
|
|
462
|
-
if block_uuid in self.upstream_block_uuids and \
|
|
463
|
-
self.data_integration_inputs and \
|
|
464
|
-
block_uuid in self.data_integration_inputs:
|
|
465
|
-
|
|
466
|
-
up_uuids = [i for i in
|
|
467
|
-
self.upstream_block_uuids if i in
|
|
468
|
-
self.data_integration_inputs]
|
|
469
|
-
|
|
470
|
-
index = up_uuids.index(block_uuid)
|
|
471
|
-
data = self.fetched_inputs_from_blocks[index]
|
|
472
|
-
|
|
473
|
-
if parse:
|
|
474
|
-
results = {}
|
|
475
|
-
exec(f'_parse_func = {parse}', results)
|
|
476
|
-
try:
|
|
477
|
-
return results['_parse_func'](data)
|
|
478
|
-
except Exception:
|
|
479
|
-
pass
|
|
480
|
-
|
|
481
|
-
return data
|
|
482
|
-
|
|
483
|
-
text = Template(content).render(
|
|
484
|
-
block_output=_block_output,
|
|
485
|
-
variables=lambda x, p=None, v=variables: get_variable_for_template(
|
|
486
|
-
x,
|
|
487
|
-
parse=p,
|
|
488
|
-
variables=v,
|
|
489
|
-
),
|
|
490
|
-
**get_template_vars(),
|
|
491
|
-
)
|
|
492
|
-
|
|
497
|
+
text = self.interpolate_content(content)
|
|
493
498
|
settings = yaml.safe_load(text)
|
|
494
499
|
uuid = settings.get('source') or settings.get('destination')
|
|
495
500
|
mapping = grouped_templates.get(uuid) or {}
|
|
@@ -570,6 +575,11 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
570
575
|
|
|
571
576
|
@property
|
|
572
577
|
def repo_path(self) -> str:
|
|
578
|
+
if self.project_platform_activated:
|
|
579
|
+
repo_path = self.get_repo_path_from_configuration()
|
|
580
|
+
if repo_path:
|
|
581
|
+
return repo_path
|
|
582
|
+
|
|
573
583
|
return self.pipeline.repo_path if self.pipeline is not None else get_repo_path()
|
|
574
584
|
|
|
575
585
|
@classmethod
|
|
@@ -591,9 +601,15 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
591
601
|
|
|
592
602
|
@property
|
|
593
603
|
def file_path(self) -> str:
|
|
604
|
+
if self.replicated_block and self.replicated_block_object:
|
|
605
|
+
return self.replicated_block_object.file_path
|
|
606
|
+
|
|
594
607
|
file_path = self.get_file_path_from_source()
|
|
608
|
+
if not file_path:
|
|
609
|
+
file_path = self.configuration.get('file_path')
|
|
610
|
+
|
|
595
611
|
if file_path:
|
|
596
|
-
return
|
|
612
|
+
return add_absolute_path(file_path)
|
|
597
613
|
|
|
598
614
|
return self.__build_file_path(
|
|
599
615
|
self.repo_path or os.getcwd(),
|
|
@@ -604,6 +620,9 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
604
620
|
|
|
605
621
|
@property
|
|
606
622
|
def file(self) -> File:
|
|
623
|
+
if self.replicated_block and self.replicated_block_object:
|
|
624
|
+
return self.replicated_block_object.file
|
|
625
|
+
|
|
607
626
|
if self.project_platform_activated:
|
|
608
627
|
file = self.build_file()
|
|
609
628
|
if file:
|
|
@@ -660,23 +679,16 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
660
679
|
downstream_block_uuids = kwargs.get('downstream_block_uuids', [])
|
|
661
680
|
upstream_block_uuids = kwargs.get('upstream_block_uuids', [])
|
|
662
681
|
|
|
663
|
-
if BlockType.DBT == block.type
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
pipeline.add_block(
|
|
674
|
-
block,
|
|
675
|
-
downstream_block_uuids=downstream_block_uuids,
|
|
676
|
-
upstream_block_uuids=upstream_block_uuids,
|
|
677
|
-
priority=priority,
|
|
678
|
-
widget=widget,
|
|
679
|
-
)
|
|
682
|
+
if BlockType.DBT == block.type:
|
|
683
|
+
block.set_default_configurations()
|
|
684
|
+
|
|
685
|
+
pipeline.add_block(
|
|
686
|
+
block,
|
|
687
|
+
downstream_block_uuids=downstream_block_uuids,
|
|
688
|
+
upstream_block_uuids=upstream_block_uuids,
|
|
689
|
+
priority=priority,
|
|
690
|
+
widget=widget,
|
|
691
|
+
)
|
|
680
692
|
|
|
681
693
|
@classmethod
|
|
682
694
|
def block_class_from_type(self, block_type: str, language=None, pipeline=None) -> 'Block':
|
|
@@ -1052,8 +1064,10 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1052
1064
|
logger=logger,
|
|
1053
1065
|
logging_tags=logging_tags,
|
|
1054
1066
|
)
|
|
1055
|
-
conditional_message
|
|
1056
|
-
f'Conditional block
|
|
1067
|
+
conditional_message = (
|
|
1068
|
+
f'{conditional_message}Conditional block '
|
|
1069
|
+
f'{conditional_block.uuid} evaluated to {block_result}.\n'
|
|
1070
|
+
)
|
|
1057
1071
|
result = result and block_result
|
|
1058
1072
|
|
|
1059
1073
|
# Print result to block output
|
|
@@ -1071,6 +1085,33 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1071
1085
|
callback_arr += self.callback_blocks
|
|
1072
1086
|
|
|
1073
1087
|
try:
|
|
1088
|
+
# {
|
|
1089
|
+
# "dynamic_block_index": 1,
|
|
1090
|
+
# "dynamic_block_indexes": {
|
|
1091
|
+
# "dynamic_b": 0
|
|
1092
|
+
# },
|
|
1093
|
+
# "dynamic_upstream_block_uuids": [
|
|
1094
|
+
# "child_upstreams:0:b0_0"
|
|
1095
|
+
# ],
|
|
1096
|
+
# "metadata": {
|
|
1097
|
+
# "dynamic_b": {
|
|
1098
|
+
# "block_uuid": "b1_1",
|
|
1099
|
+
# "upstream_blocks": [
|
|
1100
|
+
# "b0_0"
|
|
1101
|
+
# ]
|
|
1102
|
+
# }
|
|
1103
|
+
# }
|
|
1104
|
+
# }
|
|
1105
|
+
if from_notebook:
|
|
1106
|
+
for upstream_block in self.upstream_blocks:
|
|
1107
|
+
if is_dynamic_block(upstream_block) or is_dynamic_block_child(upstream_block):
|
|
1108
|
+
if 'dynamic_block_index' not in kwargs:
|
|
1109
|
+
kwargs['dynamic_block_index'] = 0
|
|
1110
|
+
if 'dynamic_block_indexes' not in kwargs:
|
|
1111
|
+
kwargs['dynamic_block_indexes'] = {}
|
|
1112
|
+
if upstream_block.uuid not in kwargs['dynamic_block_indexes']:
|
|
1113
|
+
kwargs['dynamic_block_indexes'][upstream_block.uuid] = 0
|
|
1114
|
+
|
|
1074
1115
|
output = self.execute_sync(
|
|
1075
1116
|
global_vars=global_vars,
|
|
1076
1117
|
logger=logger,
|
|
@@ -1129,6 +1170,7 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1129
1170
|
disable_json_serialization: bool = False,
|
|
1130
1171
|
data_integration_runtime_settings: Dict = None,
|
|
1131
1172
|
execution_partition_previous: str = None,
|
|
1173
|
+
metadata: Dict = None,
|
|
1132
1174
|
**kwargs,
|
|
1133
1175
|
) -> Dict:
|
|
1134
1176
|
if logging_tags is None:
|
|
@@ -1185,55 +1227,68 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1185
1227
|
run_settings=run_settings,
|
|
1186
1228
|
data_integration_runtime_settings=data_integration_runtime_settings,
|
|
1187
1229
|
execution_partition_previous=execution_partition_previous,
|
|
1230
|
+
metadata=metadata,
|
|
1188
1231
|
**kwargs,
|
|
1189
1232
|
)
|
|
1190
1233
|
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
if BlockType.CHART == self.type:
|
|
1195
|
-
variable_mapping = block_output
|
|
1196
|
-
output = dict(
|
|
1197
|
-
output=simplejson.dumps(
|
|
1198
|
-
block_output,
|
|
1199
|
-
default=encode_complex,
|
|
1200
|
-
ignore_nan=True,
|
|
1201
|
-
) if not disable_json_serialization else block_output,
|
|
1202
|
-
)
|
|
1234
|
+
if self.configuration and self.configuration.get('disable_query_preprocessing'):
|
|
1235
|
+
output = dict(output=None)
|
|
1203
1236
|
else:
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1237
|
+
block_output = self.post_process_output(output)
|
|
1238
|
+
variable_mapping = dict()
|
|
1239
|
+
|
|
1240
|
+
if BlockType.CHART == self.type:
|
|
1241
|
+
variable_mapping = block_output
|
|
1242
|
+
output = dict(
|
|
1243
|
+
output=simplejson.dumps(
|
|
1244
|
+
block_output,
|
|
1245
|
+
default=encode_complex,
|
|
1246
|
+
ignore_nan=True,
|
|
1247
|
+
) if not disable_json_serialization else block_output,
|
|
1248
|
+
)
|
|
1249
|
+
else:
|
|
1250
|
+
output_count = len(block_output)
|
|
1251
|
+
variable_keys = [f'output_{idx}' for idx in range(output_count)]
|
|
1252
|
+
variable_mapping = dict(zip(variable_keys, block_output))
|
|
1207
1253
|
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1254
|
+
if store_variables and \
|
|
1255
|
+
self.pipeline and \
|
|
1256
|
+
self.pipeline.type != PipelineType.INTEGRATION:
|
|
1211
1257
|
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1258
|
+
try:
|
|
1259
|
+
self.store_variables(
|
|
1260
|
+
variable_mapping,
|
|
1261
|
+
execution_partition=execution_partition,
|
|
1262
|
+
override_outputs=True,
|
|
1263
|
+
spark=self.__get_spark_session_from_global_vars(
|
|
1264
|
+
global_vars=global_vars,
|
|
1265
|
+
),
|
|
1266
|
+
dynamic_block_uuid=dynamic_block_uuid,
|
|
1267
|
+
)
|
|
1268
|
+
except ValueError as e:
|
|
1269
|
+
if str(e) == 'Circular reference detected':
|
|
1270
|
+
raise ValueError(
|
|
1271
|
+
'Please provide dataframe or json serializable data as output.'
|
|
1272
|
+
)
|
|
1273
|
+
raise e
|
|
1274
|
+
# Reset outputs cache
|
|
1275
|
+
self._outputs = None
|
|
1276
|
+
|
|
1277
|
+
if BlockType.CHART != self.type:
|
|
1278
|
+
if analyze_outputs:
|
|
1279
|
+
self.analyze_outputs(
|
|
1280
|
+
variable_mapping,
|
|
1281
|
+
execution_partition=execution_partition,
|
|
1282
|
+
)
|
|
1283
|
+
else:
|
|
1284
|
+
self.analyze_outputs(
|
|
1285
|
+
variable_mapping,
|
|
1286
|
+
execution_partition=execution_partition,
|
|
1287
|
+
shape_only=True,
|
|
1224
1288
|
)
|
|
1225
|
-
raise e
|
|
1226
|
-
# Reset outputs cache
|
|
1227
|
-
self._outputs = None
|
|
1228
1289
|
|
|
1229
1290
|
if update_status:
|
|
1230
1291
|
self.status = BlockStatus.EXECUTED
|
|
1231
|
-
|
|
1232
|
-
if BlockType.CHART != self.type:
|
|
1233
|
-
if analyze_outputs:
|
|
1234
|
-
self.analyze_outputs(variable_mapping)
|
|
1235
|
-
else:
|
|
1236
|
-
self.analyze_outputs(variable_mapping, shape_only=True)
|
|
1237
1292
|
except Exception as err:
|
|
1238
1293
|
if update_status:
|
|
1239
1294
|
self.status = BlockStatus.FAILED
|
|
@@ -1348,6 +1403,59 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1348
1403
|
|
|
1349
1404
|
return block_function
|
|
1350
1405
|
|
|
1406
|
+
def __get_outputs_from_input_vars(
|
|
1407
|
+
self,
|
|
1408
|
+
block_run_outputs_cache: Dict[str, List] = None,
|
|
1409
|
+
dynamic_block_index: int = None,
|
|
1410
|
+
dynamic_block_indexes: Dict = None,
|
|
1411
|
+
dynamic_upstream_block_uuids: List[str] = None,
|
|
1412
|
+
execution_partition: str = None,
|
|
1413
|
+
from_notebook: bool = False,
|
|
1414
|
+
global_vars: Dict = None,
|
|
1415
|
+
input_args: List = None,
|
|
1416
|
+
metadata: Dict = None,
|
|
1417
|
+
) -> Tuple[Dict, List, Dict, List[str]]:
|
|
1418
|
+
# Only fetch the input variables that the destination block explicitly declares.
|
|
1419
|
+
# If all the input variables are fetched, there is a chance that a lot of data from
|
|
1420
|
+
# an upstream source block is loaded just to be used as inputs for the block’s
|
|
1421
|
+
# decorated functions. Only do this for the notebook because
|
|
1422
|
+
if from_notebook and self.is_data_integration():
|
|
1423
|
+
input_vars, kwargs_vars, upstream_block_uuids = \
|
|
1424
|
+
self.fetch_input_variables_and_catalog(
|
|
1425
|
+
input_args,
|
|
1426
|
+
execution_partition,
|
|
1427
|
+
global_vars,
|
|
1428
|
+
dynamic_block_index=dynamic_block_index,
|
|
1429
|
+
dynamic_block_indexes=dynamic_block_indexes,
|
|
1430
|
+
dynamic_upstream_block_uuids=dynamic_upstream_block_uuids,
|
|
1431
|
+
from_notebook=from_notebook,
|
|
1432
|
+
)
|
|
1433
|
+
else:
|
|
1434
|
+
input_vars, kwargs_vars, upstream_block_uuids = self.fetch_input_variables(
|
|
1435
|
+
input_args,
|
|
1436
|
+
block_run_outputs_cache=block_run_outputs_cache,
|
|
1437
|
+
dynamic_block_index=dynamic_block_index,
|
|
1438
|
+
dynamic_block_indexes=dynamic_block_indexes,
|
|
1439
|
+
dynamic_upstream_block_uuids=dynamic_upstream_block_uuids,
|
|
1440
|
+
execution_partition=execution_partition,
|
|
1441
|
+
from_notebook=from_notebook,
|
|
1442
|
+
global_vars=global_vars,
|
|
1443
|
+
metadata=metadata,
|
|
1444
|
+
)
|
|
1445
|
+
|
|
1446
|
+
outputs_from_input_vars = {}
|
|
1447
|
+
if input_args is None:
|
|
1448
|
+
upstream_block_uuids_length = len(upstream_block_uuids)
|
|
1449
|
+
for idx, input_var in enumerate(input_vars):
|
|
1450
|
+
if idx < upstream_block_uuids_length:
|
|
1451
|
+
upstream_block_uuid = upstream_block_uuids[idx]
|
|
1452
|
+
outputs_from_input_vars[upstream_block_uuid] = input_var
|
|
1453
|
+
outputs_from_input_vars[f'df_{idx + 1}'] = input_var
|
|
1454
|
+
else:
|
|
1455
|
+
outputs_from_input_vars = dict()
|
|
1456
|
+
|
|
1457
|
+
return outputs_from_input_vars, input_vars, kwargs_vars, upstream_block_uuids
|
|
1458
|
+
|
|
1351
1459
|
def execute_block(
|
|
1352
1460
|
self,
|
|
1353
1461
|
block_run_outputs_cache: Dict[str, List] = None,
|
|
@@ -1367,6 +1475,7 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1367
1475
|
run_settings: Dict = None,
|
|
1368
1476
|
data_integration_runtime_settings: str = None,
|
|
1369
1477
|
execution_partition_previous: str = None,
|
|
1478
|
+
metadata: Dict = None,
|
|
1370
1479
|
**kwargs,
|
|
1371
1480
|
) -> Dict:
|
|
1372
1481
|
if logging_tags is None:
|
|
@@ -1388,25 +1497,8 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1388
1497
|
logging_tags=logging_tags,
|
|
1389
1498
|
):
|
|
1390
1499
|
# Fetch input variables
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
# If all the input variables are fetched, there is a chance that a lot of data from
|
|
1394
|
-
# an upstream source block is loaded just to be used as inputs for the block’s
|
|
1395
|
-
# decorated functions. Only do this for the notebook because
|
|
1396
|
-
if from_notebook and self.is_data_integration():
|
|
1397
|
-
input_vars, kwargs_vars, upstream_block_uuids = \
|
|
1398
|
-
self.fetch_input_variables_and_catalog(
|
|
1399
|
-
input_args,
|
|
1400
|
-
execution_partition,
|
|
1401
|
-
global_vars,
|
|
1402
|
-
dynamic_block_index=dynamic_block_index,
|
|
1403
|
-
dynamic_block_indexes=dynamic_block_indexes,
|
|
1404
|
-
dynamic_upstream_block_uuids=dynamic_upstream_block_uuids,
|
|
1405
|
-
from_notebook=from_notebook,
|
|
1406
|
-
)
|
|
1407
|
-
else:
|
|
1408
|
-
input_vars, kwargs_vars, upstream_block_uuids = self.fetch_input_variables(
|
|
1409
|
-
input_args,
|
|
1500
|
+
outputs_from_input_vars, input_vars, kwargs_vars, upstream_block_uuids = \
|
|
1501
|
+
self.__get_outputs_from_input_vars(
|
|
1410
1502
|
block_run_outputs_cache=block_run_outputs_cache,
|
|
1411
1503
|
dynamic_block_index=dynamic_block_index,
|
|
1412
1504
|
dynamic_block_indexes=dynamic_block_indexes,
|
|
@@ -1414,23 +1506,15 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1414
1506
|
execution_partition=execution_partition,
|
|
1415
1507
|
from_notebook=from_notebook,
|
|
1416
1508
|
global_vars=global_vars,
|
|
1509
|
+
input_args=input_args,
|
|
1510
|
+
metadata=metadata,
|
|
1417
1511
|
)
|
|
1418
1512
|
|
|
1419
|
-
outputs_from_input_vars = {}
|
|
1420
|
-
if input_args is None:
|
|
1421
|
-
upstream_block_uuids_length = len(upstream_block_uuids)
|
|
1422
|
-
for idx, input_var in enumerate(input_vars):
|
|
1423
|
-
if idx < upstream_block_uuids_length:
|
|
1424
|
-
upstream_block_uuid = upstream_block_uuids[idx]
|
|
1425
|
-
outputs_from_input_vars[upstream_block_uuid] = input_var
|
|
1426
|
-
outputs_from_input_vars[f'df_{idx + 1}'] = input_var
|
|
1427
|
-
else:
|
|
1428
|
-
outputs_from_input_vars = dict()
|
|
1429
|
-
|
|
1430
1513
|
global_vars_copy = global_vars.copy()
|
|
1431
1514
|
for kwargs_var in kwargs_vars:
|
|
1432
1515
|
if kwargs_var:
|
|
1433
|
-
global_vars_copy
|
|
1516
|
+
if isinstance(global_vars_copy, dict) and isinstance(kwargs_var, dict):
|
|
1517
|
+
global_vars_copy.update(kwargs_var)
|
|
1434
1518
|
|
|
1435
1519
|
outputs = self._execute_block(
|
|
1436
1520
|
outputs_from_input_vars,
|
|
@@ -1641,9 +1725,9 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1641
1725
|
# Initialize module
|
|
1642
1726
|
block_uuid = self.uuid
|
|
1643
1727
|
block_file_path = self.file_path
|
|
1644
|
-
if self.replicated_block:
|
|
1645
|
-
block_uuid = self.replicated_block
|
|
1728
|
+
if self.replicated_block and self.replicated_block_object:
|
|
1646
1729
|
block_file_path = self.replicated_block_object.file_path
|
|
1730
|
+
block_uuid = self.replicated_block
|
|
1647
1731
|
|
|
1648
1732
|
spec = importlib.util.spec_from_file_location(block_uuid, block_file_path)
|
|
1649
1733
|
module = importlib.util.module_from_spec(spec)
|
|
@@ -1686,6 +1770,7 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1686
1770
|
from_notebook: bool = False,
|
|
1687
1771
|
global_vars: Dict = None,
|
|
1688
1772
|
upstream_block_uuids: List[str] = None,
|
|
1773
|
+
metadata: Dict = None,
|
|
1689
1774
|
) -> Tuple[List, List, List]:
|
|
1690
1775
|
"""
|
|
1691
1776
|
Fetch input variables for the current block's execution.
|
|
@@ -1709,6 +1794,13 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1709
1794
|
Tuple[List, List, List]: A tuple containing the input variables, kwargs variables, and
|
|
1710
1795
|
upstream block UUIDs.
|
|
1711
1796
|
"""
|
|
1797
|
+
|
|
1798
|
+
dynamic_block_flags = []
|
|
1799
|
+
if is_dynamic_block(self):
|
|
1800
|
+
dynamic_block_flags.append(DynamicBlockFlag.DYNAMIC)
|
|
1801
|
+
if is_dynamic_block_child(self):
|
|
1802
|
+
dynamic_block_flags.append(DynamicBlockFlag.DYNAMIC_CHILD)
|
|
1803
|
+
|
|
1712
1804
|
variables = fetch_input_variables(
|
|
1713
1805
|
self.pipeline,
|
|
1714
1806
|
upstream_block_uuids or self.upstream_block_uuids,
|
|
@@ -1721,6 +1813,22 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1721
1813
|
execution_partition=execution_partition,
|
|
1722
1814
|
from_notebook=from_notebook,
|
|
1723
1815
|
global_vars=global_vars,
|
|
1816
|
+
dynamic_block_flags=dynamic_block_flags,
|
|
1817
|
+
metadata=metadata,
|
|
1818
|
+
)
|
|
1819
|
+
|
|
1820
|
+
DX_PRINTER.critical(
|
|
1821
|
+
block=self,
|
|
1822
|
+
metadata=metadata,
|
|
1823
|
+
dynamic_block_index=dynamic_block_index,
|
|
1824
|
+
dynamic_block_indexes=dynamic_block_indexes,
|
|
1825
|
+
dynamic_upstream_block_uuids=dynamic_upstream_block_uuids,
|
|
1826
|
+
dynamic_block_flags=dynamic_block_flags,
|
|
1827
|
+
execution_partition=execution_partition,
|
|
1828
|
+
upstream_block_uuids=self.upstream_block_uuids,
|
|
1829
|
+
upstream_block_uuids_override=upstream_block_uuids,
|
|
1830
|
+
variables=len(variables) if variables else 'nothing',
|
|
1831
|
+
__uuid='fetch_input_variables',
|
|
1724
1832
|
)
|
|
1725
1833
|
|
|
1726
1834
|
return variables
|
|
@@ -1753,19 +1861,30 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1753
1861
|
):
|
|
1754
1862
|
variable_manager = self.pipeline.variable_manager
|
|
1755
1863
|
|
|
1756
|
-
block_uuid_use =
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1864
|
+
block_uuid_use, changed = uuid_for_output_variables(
|
|
1865
|
+
self,
|
|
1866
|
+
block_uuid=block_uuid,
|
|
1867
|
+
dynamic_block_index=dynamic_block_index,
|
|
1868
|
+
)
|
|
1761
1869
|
|
|
1762
|
-
|
|
1870
|
+
res = variable_manager.get_variables_by_block(
|
|
1763
1871
|
self.pipeline.uuid,
|
|
1764
1872
|
block_uuid=block_uuid_use,
|
|
1765
|
-
clean_block_uuid=
|
|
1873
|
+
clean_block_uuid=not changed,
|
|
1766
1874
|
partition=partition,
|
|
1767
1875
|
)
|
|
1768
1876
|
|
|
1877
|
+
DX_PRINTER.debug(
|
|
1878
|
+
str(res),
|
|
1879
|
+
block=self,
|
|
1880
|
+
block_uuid_use=block_uuid_use,
|
|
1881
|
+
clean_block_uuid=not changed,
|
|
1882
|
+
partition=partition,
|
|
1883
|
+
__uuid='get_variables_by_block',
|
|
1884
|
+
)
|
|
1885
|
+
|
|
1886
|
+
return res
|
|
1887
|
+
|
|
1769
1888
|
def get_variable(
|
|
1770
1889
|
self,
|
|
1771
1890
|
block_uuid: str,
|
|
@@ -1777,22 +1896,34 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1777
1896
|
):
|
|
1778
1897
|
variable_manager = self.pipeline.variable_manager
|
|
1779
1898
|
|
|
1780
|
-
block_uuid_use =
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1899
|
+
block_uuid_use, changed = uuid_for_output_variables(
|
|
1900
|
+
self,
|
|
1901
|
+
block_uuid=block_uuid,
|
|
1902
|
+
dynamic_block_index=dynamic_block_index,
|
|
1903
|
+
)
|
|
1785
1904
|
|
|
1786
|
-
|
|
1905
|
+
value = variable_manager.get_variable(
|
|
1787
1906
|
self.pipeline.uuid,
|
|
1788
1907
|
block_uuid=block_uuid_use,
|
|
1789
|
-
clean_block_uuid=
|
|
1908
|
+
clean_block_uuid=not changed,
|
|
1790
1909
|
partition=partition,
|
|
1791
1910
|
raise_exception=raise_exception,
|
|
1792
1911
|
spark=spark,
|
|
1793
1912
|
variable_uuid=variable_uuid,
|
|
1794
1913
|
)
|
|
1795
1914
|
|
|
1915
|
+
DX_PRINTER.debug(
|
|
1916
|
+
'get_variable',
|
|
1917
|
+
block=self,
|
|
1918
|
+
block_uuid_use=block_uuid_use,
|
|
1919
|
+
clean_block_uuid=not changed,
|
|
1920
|
+
partition=partition,
|
|
1921
|
+
value=value,
|
|
1922
|
+
__uuid='output_variables'
|
|
1923
|
+
)
|
|
1924
|
+
|
|
1925
|
+
return value
|
|
1926
|
+
|
|
1796
1927
|
def get_variable_object(
|
|
1797
1928
|
self,
|
|
1798
1929
|
block_uuid: str,
|
|
@@ -1802,16 +1933,16 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1802
1933
|
):
|
|
1803
1934
|
variable_manager = self.pipeline.variable_manager
|
|
1804
1935
|
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1936
|
+
block_uuid, changed = uuid_for_output_variables(
|
|
1937
|
+
self,
|
|
1938
|
+
block_uuid=block_uuid,
|
|
1939
|
+
dynamic_block_index=dynamic_block_index,
|
|
1940
|
+
)
|
|
1810
1941
|
|
|
1811
1942
|
return variable_manager.get_variable_object(
|
|
1812
1943
|
self.pipeline.uuid,
|
|
1813
|
-
block_uuid=
|
|
1814
|
-
clean_block_uuid=
|
|
1944
|
+
block_uuid=block_uuid,
|
|
1945
|
+
clean_block_uuid=not changed,
|
|
1815
1946
|
partition=partition,
|
|
1816
1947
|
spark=self.get_spark_session(),
|
|
1817
1948
|
variable_uuid=variable_uuid,
|
|
@@ -1855,6 +1986,7 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1855
1986
|
variable_type: VariableType = None,
|
|
1856
1987
|
block_uuid: str = None,
|
|
1857
1988
|
selected_variables: List[str] = None,
|
|
1989
|
+
metadata: Dict = None,
|
|
1858
1990
|
) -> List[Dict]:
|
|
1859
1991
|
if self.pipeline is None:
|
|
1860
1992
|
return
|
|
@@ -1862,9 +1994,17 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1862
1994
|
if not block_uuid:
|
|
1863
1995
|
block_uuid = self.uuid
|
|
1864
1996
|
|
|
1997
|
+
# The block_run’s block_uuid for replicated blocks will be in this format:
|
|
1998
|
+
# [block_uuid]:[replicated_block_uuid]
|
|
1999
|
+
# We need to use the original block_uuid to get the proper output.
|
|
2000
|
+
|
|
2001
|
+
# Block runs for dynamic child blocks will have the following block UUID:
|
|
2002
|
+
# [block.uuid]:[index]
|
|
2003
|
+
# Don’t use the original UUID even if the block is a replica because it will get rid of
|
|
2004
|
+
# the dynamic child block index.
|
|
2005
|
+
|
|
1865
2006
|
data_products = []
|
|
1866
2007
|
outputs = []
|
|
1867
|
-
variable_manager = self.pipeline.variable_manager
|
|
1868
2008
|
|
|
1869
2009
|
all_variables = self.get_variables_by_block(
|
|
1870
2010
|
block_uuid=block_uuid,
|
|
@@ -1876,6 +2016,11 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1876
2016
|
execution_partition=execution_partition,
|
|
1877
2017
|
)
|
|
1878
2018
|
|
|
2019
|
+
DX_PRINTER.debug(
|
|
2020
|
+
all_variables=all_variables,
|
|
2021
|
+
__uuid='get_variables_by_block',
|
|
2022
|
+
)
|
|
2023
|
+
|
|
1879
2024
|
for v in all_variables:
|
|
1880
2025
|
if selected_variables and v not in selected_variables:
|
|
1881
2026
|
continue
|
|
@@ -1894,91 +2039,22 @@ class Block(DataIntegrationMixin, SparkBlock, ProjectPlatformAccessible):
|
|
|
1894
2039
|
sample_count=sample_count,
|
|
1895
2040
|
spark=self.get_spark_session(),
|
|
1896
2041
|
)
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
self.pipeline.uuid,
|
|
1906
|
-
block_uuid,
|
|
1907
|
-
v,
|
|
1908
|
-
dataframe_analysis_keys=['metadata', 'statistics'],
|
|
1909
|
-
partition=execution_partition,
|
|
1910
|
-
variable_type=VariableType.DATAFRAME_ANALYSIS,
|
|
1911
|
-
)
|
|
1912
|
-
except Exception:
|
|
1913
|
-
analysis = None
|
|
1914
|
-
if analysis is not None and \
|
|
1915
|
-
(analysis.get('statistics') or analysis.get('metadata')):
|
|
1916
|
-
|
|
1917
|
-
stats = analysis.get('statistics', {})
|
|
1918
|
-
column_types = (analysis.get('metadata') or {}).get('column_types', {})
|
|
1919
|
-
row_count = stats.get('original_row_count', stats.get('count'))
|
|
1920
|
-
column_count = stats.get('original_column_count', len(column_types))
|
|
1921
|
-
else:
|
|
1922
|
-
row_count, column_count = data.shape
|
|
1923
|
-
|
|
1924
|
-
columns_to_display = data.columns.tolist()[:DATAFRAME_ANALYSIS_MAX_COLUMNS]
|
|
1925
|
-
data = dict(
|
|
1926
|
-
sample_data=dict(
|
|
1927
|
-
columns=columns_to_display,
|
|
1928
|
-
rows=json.loads(
|
|
1929
|
-
data[columns_to_display].to_json(orient='split')
|
|
1930
|
-
)['data']
|
|
1931
|
-
),
|
|
1932
|
-
shape=[row_count, column_count],
|
|
1933
|
-
type=DataType.TABLE,
|
|
1934
|
-
variable_uuid=v,
|
|
1935
|
-
)
|
|
1936
|
-
data_products.append(data)
|
|
1937
|
-
continue
|
|
1938
|
-
elif is_geo_dataframe(data):
|
|
1939
|
-
data = dict(
|
|
1940
|
-
text_data=f'''Use the code in a scratchpad to get the output of the block:
|
|
1941
|
-
|
|
1942
|
-
from mage_ai.data_preparation.variable_manager import get_variable
|
|
1943
|
-
df = get_variable('{self.pipeline.uuid}', '{self.uuid}', 'df')
|
|
1944
|
-
''',
|
|
1945
|
-
type=DataType.TEXT,
|
|
1946
|
-
variable_uuid=v,
|
|
1947
|
-
)
|
|
1948
|
-
elif type(data) is str:
|
|
1949
|
-
data = dict(
|
|
1950
|
-
text_data=data,
|
|
1951
|
-
type=DataType.TEXT,
|
|
1952
|
-
variable_uuid=v,
|
|
1953
|
-
)
|
|
1954
|
-
elif type(data) is dict or type(data) is list:
|
|
1955
|
-
data = dict(
|
|
1956
|
-
text_data=simplejson.dumps(
|
|
1957
|
-
data,
|
|
1958
|
-
default=datetime.isoformat,
|
|
1959
|
-
ignore_nan=True,
|
|
1960
|
-
),
|
|
1961
|
-
type=DataType.TEXT,
|
|
1962
|
-
variable_uuid=v,
|
|
1963
|
-
)
|
|
1964
|
-
elif is_spark_dataframe(data):
|
|
1965
|
-
df = data.toPandas()
|
|
1966
|
-
columns_to_display = df.columns.tolist()[:DATAFRAME_ANALYSIS_MAX_COLUMNS]
|
|
1967
|
-
data = dict(
|
|
1968
|
-
sample_data=dict(
|
|
1969
|
-
columns=columns_to_display,
|
|
1970
|
-
rows=json.loads(df[columns_to_display].to_json(orient='split'))['data']
|
|
1971
|
-
),
|
|
1972
|
-
type=DataType.TABLE,
|
|
1973
|
-
variable_uuid=v,
|
|
1974
|
-
)
|
|
2042
|
+
data, is_data_product = self.__format_output_data(
|
|
2043
|
+
data,
|
|
2044
|
+
v,
|
|
2045
|
+
block_uuid=block_uuid,
|
|
2046
|
+
csv_lines_only=csv_lines_only,
|
|
2047
|
+
execution_partition=execution_partition,
|
|
2048
|
+
)
|
|
2049
|
+
if is_data_product:
|
|
1975
2050
|
data_products.append(data)
|
|
1976
|
-
|
|
1977
|
-
|
|
2051
|
+
else:
|
|
2052
|
+
outputs.append(data)
|
|
1978
2053
|
return outputs + data_products
|
|
1979
2054
|
|
|
1980
2055
|
async def __get_outputs_async(
|
|
1981
2056
|
self,
|
|
2057
|
+
csv_lines_only: bool = False,
|
|
1982
2058
|
execution_partition: str = None,
|
|
1983
2059
|
include_print_outputs: bool = True,
|
|
1984
2060
|
sample_count: int = DATAFRAME_SAMPLE_COUNT_PREVIEW,
|
|
@@ -2021,19 +2097,55 @@ df = get_variable('{self.pipeline.uuid}', '{self.uuid}', 'df')
|
|
|
2021
2097
|
sample_count=sample_count,
|
|
2022
2098
|
spark=self.get_spark_session(),
|
|
2023
2099
|
)
|
|
2024
|
-
|
|
2100
|
+
data, is_data_product = self.__format_output_data(
|
|
2101
|
+
data,
|
|
2102
|
+
v,
|
|
2103
|
+
block_uuid=block_uuid,
|
|
2104
|
+
csv_lines_only=csv_lines_only,
|
|
2105
|
+
execution_partition=execution_partition,
|
|
2106
|
+
)
|
|
2107
|
+
if is_data_product:
|
|
2108
|
+
data_products.append(data)
|
|
2109
|
+
else:
|
|
2110
|
+
outputs.append(data)
|
|
2111
|
+
return outputs + data_products
|
|
2112
|
+
|
|
2113
|
+
def __format_output_data(
|
|
2114
|
+
self,
|
|
2115
|
+
data: Any,
|
|
2116
|
+
variable_uuid: str,
|
|
2117
|
+
block_uuid: str = None,
|
|
2118
|
+
csv_lines_only: bool = False,
|
|
2119
|
+
execution_partition: str = None,
|
|
2120
|
+
) -> Tuple[Dict, bool]:
|
|
2121
|
+
"""
|
|
2122
|
+
Takes variable data and formats it to return to the frontend.
|
|
2123
|
+
|
|
2124
|
+
Returns:
|
|
2125
|
+
Tuple[Dict, bool]: Tuple of the formatted data and is_data_product boolean. Data product
|
|
2126
|
+
outputs and non data product outputs are handled slightly differently.
|
|
2127
|
+
"""
|
|
2128
|
+
variable_manager = self.pipeline.variable_manager
|
|
2129
|
+
if isinstance(data, pd.DataFrame):
|
|
2130
|
+
if csv_lines_only:
|
|
2131
|
+
data = dict(
|
|
2132
|
+
table=data.to_csv(header=True, index=False).strip('\n').split('\n')
|
|
2133
|
+
)
|
|
2134
|
+
else:
|
|
2025
2135
|
try:
|
|
2026
2136
|
analysis = variable_manager.get_variable(
|
|
2027
2137
|
self.pipeline.uuid,
|
|
2028
2138
|
block_uuid,
|
|
2029
|
-
|
|
2139
|
+
variable_uuid,
|
|
2030
2140
|
dataframe_analysis_keys=['metadata', 'statistics'],
|
|
2031
2141
|
partition=execution_partition,
|
|
2032
2142
|
variable_type=VariableType.DATAFRAME_ANALYSIS,
|
|
2033
2143
|
)
|
|
2034
2144
|
except Exception:
|
|
2035
2145
|
analysis = None
|
|
2036
|
-
if analysis is not None
|
|
2146
|
+
if analysis is not None and \
|
|
2147
|
+
(analysis.get('statistics') or analysis.get('metadata')):
|
|
2148
|
+
|
|
2037
2149
|
stats = analysis.get('statistics', {})
|
|
2038
2150
|
column_types = (analysis.get('metadata') or {}).get('column_types', {})
|
|
2039
2151
|
row_count = stats.get('original_row_count', stats.get('count'))
|
|
@@ -2045,55 +2157,90 @@ df = get_variable('{self.pipeline.uuid}', '{self.uuid}', 'df')
|
|
|
2045
2157
|
data = dict(
|
|
2046
2158
|
sample_data=dict(
|
|
2047
2159
|
columns=columns_to_display,
|
|
2048
|
-
rows=json.loads(
|
|
2160
|
+
rows=json.loads(
|
|
2161
|
+
data[columns_to_display].to_json(orient='split')
|
|
2162
|
+
)['data']
|
|
2049
2163
|
),
|
|
2050
2164
|
shape=[row_count, column_count],
|
|
2051
2165
|
type=DataType.TABLE,
|
|
2052
|
-
variable_uuid=
|
|
2166
|
+
variable_uuid=variable_uuid,
|
|
2053
2167
|
)
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2168
|
+
return data, True
|
|
2169
|
+
elif isinstance(data, pl.DataFrame):
|
|
2170
|
+
try:
|
|
2171
|
+
analysis = variable_manager.get_variable(
|
|
2172
|
+
self.pipeline.uuid,
|
|
2173
|
+
block_uuid,
|
|
2174
|
+
variable_uuid,
|
|
2175
|
+
dataframe_analysis_keys=['statistics'],
|
|
2176
|
+
partition=execution_partition,
|
|
2177
|
+
variable_type=VariableType.DATAFRAME_ANALYSIS,
|
|
2178
|
+
)
|
|
2179
|
+
except Exception:
|
|
2180
|
+
analysis = None
|
|
2181
|
+
if analysis is not None:
|
|
2182
|
+
stats = analysis.get('statistics', {})
|
|
2183
|
+
row_count = stats.get('original_row_count')
|
|
2184
|
+
column_count = stats.get('original_column_count')
|
|
2185
|
+
else:
|
|
2186
|
+
row_count, column_count = data.shape
|
|
2187
|
+
columns_to_display = data.columns[:DATAFRAME_ANALYSIS_MAX_COLUMNS]
|
|
2188
|
+
data = dict(
|
|
2189
|
+
sample_data=dict(
|
|
2190
|
+
columns=columns_to_display,
|
|
2191
|
+
rows=[
|
|
2192
|
+
list(row.values()) for row in json.loads(
|
|
2193
|
+
data[columns_to_display].write_json(row_oriented=True)
|
|
2194
|
+
)
|
|
2195
|
+
]
|
|
2196
|
+
),
|
|
2197
|
+
shape=[row_count, column_count],
|
|
2198
|
+
type=DataType.TABLE,
|
|
2199
|
+
variable_uuid=variable_uuid,
|
|
2200
|
+
)
|
|
2201
|
+
return data, True
|
|
2202
|
+
elif is_geo_dataframe(data):
|
|
2203
|
+
data = dict(
|
|
2204
|
+
text_data=f'''Use the code in a scratchpad to get the output of the block:
|
|
2059
2205
|
|
|
2060
2206
|
from mage_ai.data_preparation.variable_manager import get_variable
|
|
2061
|
-
df = get_variable('{self.pipeline.uuid}', '{
|
|
2207
|
+
df = get_variable('{self.pipeline.uuid}', '{self.uuid}', 'df')
|
|
2062
2208
|
''',
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
)
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2209
|
+
type=DataType.TEXT,
|
|
2210
|
+
variable_uuid=variable_uuid,
|
|
2211
|
+
)
|
|
2212
|
+
return data, False
|
|
2213
|
+
elif type(data) is str:
|
|
2214
|
+
data = dict(
|
|
2215
|
+
text_data=data,
|
|
2216
|
+
type=DataType.TEXT,
|
|
2217
|
+
variable_uuid=variable_uuid,
|
|
2218
|
+
)
|
|
2219
|
+
return data, False
|
|
2220
|
+
elif type(data) is dict or type(data) is list:
|
|
2221
|
+
data = dict(
|
|
2222
|
+
text_data=simplejson.dumps(
|
|
2223
|
+
data,
|
|
2224
|
+
default=datetime.isoformat,
|
|
2225
|
+
ignore_nan=True,
|
|
2226
|
+
),
|
|
2227
|
+
type=DataType.TEXT,
|
|
2228
|
+
variable_uuid=variable_uuid,
|
|
2229
|
+
)
|
|
2230
|
+
return data, False
|
|
2231
|
+
elif is_spark_dataframe(data):
|
|
2232
|
+
df = data.toPandas()
|
|
2233
|
+
columns_to_display = df.columns.tolist()[:DATAFRAME_ANALYSIS_MAX_COLUMNS]
|
|
2234
|
+
data = dict(
|
|
2235
|
+
sample_data=dict(
|
|
2236
|
+
columns=columns_to_display,
|
|
2237
|
+
rows=json.loads(df[columns_to_display].to_json(orient='split'))['data']
|
|
2238
|
+
),
|
|
2239
|
+
type=DataType.TABLE,
|
|
2240
|
+
variable_uuid=variable_uuid,
|
|
2241
|
+
)
|
|
2242
|
+
return data, True
|
|
2243
|
+
return data, False
|
|
2097
2244
|
|
|
2098
2245
|
def __save_outputs_prepare(self, outputs, override_output_variable: bool = False) -> Dict:
|
|
2099
2246
|
variable_mapping = dict()
|
|
@@ -2225,7 +2372,7 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2225
2372
|
self.replicated_block and \
|
|
2226
2373
|
BlockType.GLOBAL_DATA_PRODUCT != self.type:
|
|
2227
2374
|
|
|
2228
|
-
file_path = self.
|
|
2375
|
+
file_path = self.file_path
|
|
2229
2376
|
if not os.path.isfile(file_path):
|
|
2230
2377
|
data['error'] = dict(
|
|
2231
2378
|
error='No such file or directory',
|
|
@@ -2384,6 +2531,9 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2384
2531
|
widget=False,
|
|
2385
2532
|
error_if_file_missing: bool = True,
|
|
2386
2533
|
) -> 'Block':
|
|
2534
|
+
if self.replicated_block:
|
|
2535
|
+
return self
|
|
2536
|
+
|
|
2387
2537
|
if error_if_file_missing and not self.file.exists():
|
|
2388
2538
|
raise Exception(f'File for block {self.uuid} does not exist at {self.file.file_path}.')
|
|
2389
2539
|
|
|
@@ -2400,6 +2550,9 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2400
2550
|
error_if_file_missing: bool = True,
|
|
2401
2551
|
widget: bool = False,
|
|
2402
2552
|
) -> 'Block':
|
|
2553
|
+
if self.replicated_block:
|
|
2554
|
+
return self
|
|
2555
|
+
|
|
2403
2556
|
if error_if_file_missing and not self.file.exists():
|
|
2404
2557
|
raise Exception(f'File for block {self.uuid} does not exist at {self.file.file_path}.')
|
|
2405
2558
|
|
|
@@ -2583,7 +2736,12 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2583
2736
|
logging_tags=logging_tags,
|
|
2584
2737
|
)
|
|
2585
2738
|
|
|
2586
|
-
def analyze_outputs(
|
|
2739
|
+
def analyze_outputs(
|
|
2740
|
+
self,
|
|
2741
|
+
variable_mapping,
|
|
2742
|
+
execution_partition: str = None,
|
|
2743
|
+
shape_only: bool = False,
|
|
2744
|
+
) -> None:
|
|
2587
2745
|
if self.pipeline is None:
|
|
2588
2746
|
return
|
|
2589
2747
|
for uuid, data in variable_mapping.items():
|
|
@@ -2599,6 +2757,7 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2599
2757
|
original_column_count=data.shape[1],
|
|
2600
2758
|
),
|
|
2601
2759
|
),
|
|
2760
|
+
partition=execution_partition,
|
|
2602
2761
|
variable_type=VariableType.DATAFRAME_ANALYSIS,
|
|
2603
2762
|
)
|
|
2604
2763
|
continue
|
|
@@ -2626,6 +2785,7 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2626
2785
|
insights=analysis['insights'],
|
|
2627
2786
|
suggestions=analysis['suggestions'],
|
|
2628
2787
|
),
|
|
2788
|
+
partition=execution_partition,
|
|
2629
2789
|
variable_type=VariableType.DATAFRAME_ANALYSIS,
|
|
2630
2790
|
)
|
|
2631
2791
|
except Exception:
|
|
@@ -2633,6 +2793,20 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2633
2793
|
# TODO: we use to silently fail, but it looks bad when using BigQuery
|
|
2634
2794
|
# print('\nFailed to analyze dataframe:')
|
|
2635
2795
|
# print(traceback.format_exc())
|
|
2796
|
+
elif type(data) is pl.DataFrame:
|
|
2797
|
+
self.pipeline.variable_manager.add_variable(
|
|
2798
|
+
self.pipeline.uuid,
|
|
2799
|
+
self.uuid,
|
|
2800
|
+
uuid,
|
|
2801
|
+
dict(
|
|
2802
|
+
statistics=dict(
|
|
2803
|
+
original_row_count=data.shape[0],
|
|
2804
|
+
original_column_count=data.shape[1],
|
|
2805
|
+
),
|
|
2806
|
+
),
|
|
2807
|
+
partition=execution_partition,
|
|
2808
|
+
variable_type=VariableType.DATAFRAME_ANALYSIS,
|
|
2809
|
+
)
|
|
2636
2810
|
|
|
2637
2811
|
def set_global_vars(self, global_vars: Dict) -> None:
|
|
2638
2812
|
self.global_vars = global_vars
|
|
@@ -2794,11 +2968,11 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2794
2968
|
) -> Dict:
|
|
2795
2969
|
self.dynamic_block_uuid = dynamic_block_uuid
|
|
2796
2970
|
|
|
2797
|
-
block_uuid =
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2971
|
+
block_uuid, changed = uuid_for_output_variables(
|
|
2972
|
+
self,
|
|
2973
|
+
block_uuid=self.uuid,
|
|
2974
|
+
dynamic_block_uuid=dynamic_block_uuid,
|
|
2975
|
+
)
|
|
2802
2976
|
|
|
2803
2977
|
if self.pipeline is None:
|
|
2804
2978
|
return
|
|
@@ -2807,7 +2981,7 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2807
2981
|
self.pipeline.uuid,
|
|
2808
2982
|
block_uuid=block_uuid,
|
|
2809
2983
|
partition=execution_partition,
|
|
2810
|
-
clean_block_uuid=
|
|
2984
|
+
clean_block_uuid=not changed,
|
|
2811
2985
|
)
|
|
2812
2986
|
|
|
2813
2987
|
variable_mapping = self.__consolidate_variables(variable_mapping)
|
|
@@ -2844,24 +3018,23 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2844
3018
|
dynamic_block_uuid=dynamic_block_uuid,
|
|
2845
3019
|
)
|
|
2846
3020
|
|
|
2847
|
-
block_uuid =
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
3021
|
+
block_uuid, changed = uuid_for_output_variables(
|
|
3022
|
+
self,
|
|
3023
|
+
block_uuid=self.uuid,
|
|
3024
|
+
dynamic_block_uuid=dynamic_block_uuid,
|
|
3025
|
+
)
|
|
2852
3026
|
|
|
2853
3027
|
for uuid, data in variables_data['variable_mapping'].items():
|
|
2854
3028
|
if spark is not None and self.pipeline.type == PipelineType.PYSPARK \
|
|
2855
3029
|
and type(data) is pd.DataFrame:
|
|
2856
3030
|
data = spark.createDataFrame(data)
|
|
2857
|
-
|
|
2858
3031
|
self.pipeline.variable_manager.add_variable(
|
|
2859
3032
|
self.pipeline.uuid,
|
|
2860
3033
|
block_uuid,
|
|
2861
3034
|
uuid,
|
|
2862
3035
|
data,
|
|
2863
3036
|
partition=execution_partition,
|
|
2864
|
-
clean_block_uuid=
|
|
3037
|
+
clean_block_uuid=not changed,
|
|
2865
3038
|
)
|
|
2866
3039
|
|
|
2867
3040
|
for uuid in variables_data['removed_variables']:
|
|
@@ -2888,11 +3061,11 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2888
3061
|
dynamic_block_uuid,
|
|
2889
3062
|
)
|
|
2890
3063
|
|
|
2891
|
-
block_uuid =
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
3064
|
+
block_uuid, changed = uuid_for_output_variables(
|
|
3065
|
+
self,
|
|
3066
|
+
block_uuid=self.uuid,
|
|
3067
|
+
dynamic_block_uuid=dynamic_block_uuid,
|
|
3068
|
+
)
|
|
2896
3069
|
|
|
2897
3070
|
for uuid, data in variables_data['variable_mapping'].items():
|
|
2898
3071
|
if spark is not None and type(data) is pd.DataFrame:
|
|
@@ -2904,7 +3077,7 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2904
3077
|
uuid,
|
|
2905
3078
|
data,
|
|
2906
3079
|
partition=execution_partition,
|
|
2907
|
-
clean_block_uuid=
|
|
3080
|
+
clean_block_uuid=not changed,
|
|
2908
3081
|
)
|
|
2909
3082
|
|
|
2910
3083
|
for uuid in variables_data['removed_variables']:
|
|
@@ -2912,7 +3085,7 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
2912
3085
|
self.pipeline.uuid,
|
|
2913
3086
|
block_uuid,
|
|
2914
3087
|
uuid,
|
|
2915
|
-
clean_block_uuid=
|
|
3088
|
+
clean_block_uuid=not changed,
|
|
2916
3089
|
)
|
|
2917
3090
|
|
|
2918
3091
|
def input_variables(self, execution_partition: str = None) -> Dict[str, List[str]]:
|
|
@@ -3055,18 +3228,72 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
3055
3228
|
2. Update the folder of variable
|
|
3056
3229
|
3. Update upstream and downstream relationships
|
|
3057
3230
|
"""
|
|
3231
|
+
file_extension = Path(self.file_path).suffix if self.file_path else ''
|
|
3232
|
+
directory_name = self.file_directory_name(self.type)
|
|
3233
|
+
|
|
3058
3234
|
old_uuid = self.uuid
|
|
3059
3235
|
# This has to be here
|
|
3060
3236
|
old_file_path = self.file_path
|
|
3061
3237
|
block_content = self.content
|
|
3062
3238
|
|
|
3239
|
+
# load_titanic
|
|
3063
3240
|
new_uuid = clean_name(name)
|
|
3064
3241
|
self.name = name
|
|
3065
3242
|
self.uuid = new_uuid
|
|
3243
|
+
|
|
3244
|
+
# This file has a path in its file_source that must be updated.
|
|
3245
|
+
if project_platform_activated() and \
|
|
3246
|
+
self.file_source_path() and \
|
|
3247
|
+
add_absolute_path(self.file_source_path()) == self.file_path:
|
|
3248
|
+
|
|
3249
|
+
# /home/src/data-vault/perftools/mage/data_loaders/team/illusory_glitter
|
|
3250
|
+
old_file_path_without_extension = str(Path(old_file_path).with_suffix(''))
|
|
3251
|
+
# /home/src/data-vault/perftools/mage/data_loaders/team
|
|
3252
|
+
old_file_path_without_uuid = str(Path(old_file_path_without_extension.replace(
|
|
3253
|
+
str(Path(old_uuid)),
|
|
3254
|
+
'',
|
|
3255
|
+
)))
|
|
3256
|
+
|
|
3257
|
+
# perftools/mage/data_loaders/team
|
|
3258
|
+
old_file_path_without_repo_path = remove_base_repo_path(old_file_path_without_uuid)
|
|
3259
|
+
# perftools/mage
|
|
3260
|
+
path_without_block_directory = str(old_file_path_without_repo_path).split(
|
|
3261
|
+
directory_name,
|
|
3262
|
+
)[0]
|
|
3263
|
+
|
|
3264
|
+
file_extension_new = Path(self.uuid).suffix or file_extension
|
|
3265
|
+
# perftools/mage/data_loaders/load_titanic.py
|
|
3266
|
+
new_path = str(Path(os.path.join(
|
|
3267
|
+
path_without_block_directory,
|
|
3268
|
+
directory_name,
|
|
3269
|
+
str(Path(self.uuid).with_suffix('')),
|
|
3270
|
+
)).with_suffix(file_extension_new))
|
|
3271
|
+
|
|
3272
|
+
configuration = self.configuration or {}
|
|
3273
|
+
if not configuration.get('file_source'):
|
|
3274
|
+
configuration['file_source'] = {}
|
|
3275
|
+
configuration['file_source']['path'] = new_path
|
|
3276
|
+
self.configuration = configuration
|
|
3277
|
+
|
|
3066
3278
|
# This has to be here
|
|
3067
3279
|
new_file_path = self.file_path
|
|
3068
3280
|
|
|
3069
3281
|
if self.pipeline is not None:
|
|
3282
|
+
DX_PRINTER.critical(
|
|
3283
|
+
block=self,
|
|
3284
|
+
old_uuid=old_uuid,
|
|
3285
|
+
old_file_path=old_file_path,
|
|
3286
|
+
block_content=block_content,
|
|
3287
|
+
new_uuid=new_uuid,
|
|
3288
|
+
name=self.name,
|
|
3289
|
+
uuid=self.uuid,
|
|
3290
|
+
file_path=new_file_path,
|
|
3291
|
+
pipeline=self.pipeline.uuid,
|
|
3292
|
+
repo_path=self.pipeline.repo_path,
|
|
3293
|
+
configuration=self.configuration,
|
|
3294
|
+
__uuid='__update_name',
|
|
3295
|
+
)
|
|
3296
|
+
|
|
3070
3297
|
if self.pipeline.has_block(
|
|
3071
3298
|
new_uuid,
|
|
3072
3299
|
block_type=self.type,
|
|
@@ -3110,7 +3337,7 @@ df = get_variable('{self.pipeline.uuid}', '{block_uuid}', 'df')
|
|
|
3110
3337
|
language=self.language,
|
|
3111
3338
|
pipeline=self.pipeline,
|
|
3112
3339
|
)
|
|
3113
|
-
cache.remove_pipeline(old_block, self.pipeline.uuid)
|
|
3340
|
+
cache.remove_pipeline(old_block, self.pipeline.uuid, self.pipeline.repo_path)
|
|
3114
3341
|
else:
|
|
3115
3342
|
cache.move_pipelines(self, dict(
|
|
3116
3343
|
type=self.type,
|