mage-ai 0.9.68__py3-none-any.whl → 0.9.70__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/policies/BackfillPolicy.py +1 -0
- mage_ai/api/policies/PipelinePolicy.py +1 -0
- mage_ai/api/policies/WorkspacePolicy.py +1 -0
- mage_ai/api/presenters/BackfillPresenter.py +1 -0
- mage_ai/api/resources/GitBranchResource.py +56 -23
- mage_ai/api/resources/GitCustomBranchResource.py +29 -1
- mage_ai/api/resources/OauthResource.py +1 -1
- mage_ai/api/resources/PipelineResource.py +11 -5
- mage_ai/api/resources/PipelineRunResource.py +41 -4
- mage_ai/api/resources/PipelineScheduleResource.py +4 -0
- mage_ai/api/resources/PullRequestResource.py +6 -4
- mage_ai/api/resources/SeedResource.py +2 -1
- mage_ai/api/resources/SessionResource.py +13 -1
- mage_ai/api/resources/WorkspaceResource.py +5 -4
- mage_ai/authentication/permissions/constants.py +2 -0
- mage_ai/authentication/permissions/seed.py +32 -21
- mage_ai/authentication/providers/active_directory.py +4 -3
- mage_ai/authentication/providers/okta.py +22 -83
- mage_ai/cache/block_action_object/__init__.py +1 -1
- mage_ai/cluster_manager/kubernetes/workload_manager.py +52 -1
- mage_ai/cluster_manager/workspace/base.py +6 -0
- mage_ai/cluster_manager/workspace/kubernetes.py +22 -1
- mage_ai/command_center/applications/utils.py +2 -2
- mage_ai/command_center/presenters/text.py +1 -1
- mage_ai/data_preparation/executors/k8s_block_executor.py +30 -7
- mage_ai/data_preparation/executors/k8s_pipeline_executor.py +30 -7
- mage_ai/data_preparation/executors/streaming_pipeline_executor.py +78 -8
- mage_ai/data_preparation/git/__init__.py +50 -22
- mage_ai/data_preparation/git/api.py +62 -7
- mage_ai/data_preparation/git/utils.py +45 -21
- mage_ai/data_preparation/models/block/__init__.py +31 -8
- mage_ai/data_preparation/models/block/data_integration/mixins.py +16 -5
- mage_ai/data_preparation/models/block/dynamic/child.py +3 -0
- mage_ai/data_preparation/models/block/dynamic/utils.py +9 -4
- mage_ai/data_preparation/models/block/dynamic/variables.py +2 -2
- mage_ai/data_preparation/models/block/extension/utils.py +1 -0
- mage_ai/data_preparation/models/block/global_data_product/__init__.py +25 -2
- mage_ai/data_preparation/models/block/integration/__init__.py +1 -1
- mage_ai/data_preparation/models/block/remote/__init__.py +0 -0
- mage_ai/data_preparation/models/block/remote/models.py +58 -0
- mage_ai/data_preparation/models/block/sql/__init__.py +1 -1
- mage_ai/data_preparation/models/block/utils.py +38 -0
- mage_ai/data_preparation/models/constants.py +2 -0
- mage_ai/data_preparation/models/global_data_product/__init__.py +12 -0
- mage_ai/data_preparation/models/pipeline.py +31 -11
- mage_ai/data_preparation/models/triggers/__init__.py +4 -2
- mage_ai/data_preparation/models/utils.py +6 -0
- mage_ai/data_preparation/models/variable.py +18 -4
- mage_ai/data_preparation/repo_manager.py +3 -2
- mage_ai/data_preparation/shared/utils.py +1 -1
- mage_ai/data_preparation/storage/local_storage.py +12 -6
- mage_ai/data_preparation/templates/data_exporters/mysql.py +2 -2
- mage_ai/data_preparation/templates/data_exporters/oracledb.py +27 -0
- mage_ai/data_preparation/templates/repo/metadata.yaml +1 -0
- mage_ai/io/bigquery.py +131 -58
- mage_ai/io/mysql.py +38 -6
- mage_ai/io/snowflake.py +152 -29
- mage_ai/orchestration/db/migrations/versions/42a14d6143f1_update_token_column_type.py +54 -0
- mage_ai/orchestration/db/models/oauth.py +14 -13
- mage_ai/orchestration/db/models/schedules.py +30 -2
- mage_ai/orchestration/job_manager.py +6 -0
- mage_ai/orchestration/notification/sender.py +37 -15
- mage_ai/orchestration/pipeline_scheduler_original.py +48 -31
- mage_ai/orchestration/queue/celery_queue.py +8 -1
- mage_ai/orchestration/queue/process_queue.py +67 -4
- mage_ai/orchestration/queue/queue.py +8 -0
- mage_ai/orchestration/triggers/api.py +29 -1
- mage_ai/orchestration/triggers/global_data_product.py +9 -4
- mage_ai/orchestration/triggers/utils.py +10 -1
- mage_ai/orchestration/utils/resources.py +3 -0
- mage_ai/server/api/downloads.py +4 -1
- mage_ai/server/api/runs.py +151 -0
- mage_ai/server/constants.py +1 -1
- mage_ai/server/frontend_dist/404.html +6 -6
- mage_ai/server/frontend_dist/_next/static/{i8pymuJDTVHdWjUP1QSh1 → RhDiJSkcjCsh4xxX4BFBk}/_buildManifest.js +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1557-b3502f3f1aa92ac7.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/2717-d9200be634dd6766.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/3548-9d26185b3fb663b1.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/5699-6d708c6b2153ea08.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/7361-8a23dd8360593e7a.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/7966-b9b85ba10667e654.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/9624-8b8e100079ab69e1.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-2a69553d8c6eeb53.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/index-4e12783b064c1cfe.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-4bfc84ff07d7656f.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-a66b4c7641ae03eb.js → frontend_dist/_next/static/chunks/pages/pipeline-runs-6d183f91a2ff6668.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-7181b086c93784d2.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-38e1fbcfbfc1014e.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-b645a6d13ab9fe3a.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-eb11c5390c982b49.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{triggers-cb88fd075a357fcf.js → triggers-4612d15a65c35912.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-3591d035bb3bb2b8.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-32985f3f7c7dd3ab.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/settings-c2e9ef989c8bfa73.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-349af617d05f001b.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-60d01d3887e31136.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/{users-86814e581acaf5db.js → users-a4db8710f703c729.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/sign-in-09414a8b66fb6f06.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/triggers-9cba3211434a8966.js → frontend_dist/_next/static/chunks/pages/triggers-a599c6ac89be8c8d.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-3433c8b22e8342aa.js +1 -0
- mage_ai/server/frontend_dist/block-layout.html +2 -2
- mage_ai/server/frontend_dist/compute.html +2 -2
- mage_ai/server/frontend_dist/files.html +2 -2
- mage_ai/server/frontend_dist/global-data-products/[...slug].html +2 -2
- mage_ai/server/frontend_dist/global-data-products.html +2 -2
- mage_ai/server/frontend_dist/global-hooks/[...slug].html +2 -2
- mage_ai/server/frontend_dist/global-hooks.html +2 -2
- mage_ai/server/frontend_dist/index.html +2 -2
- mage_ai/server/frontend_dist/manage/files.html +2 -2
- mage_ai/server/frontend_dist/manage/settings.html +2 -2
- mage_ai/server/frontend_dist/manage/users/[user].html +2 -2
- mage_ai/server/frontend_dist/manage/users/new.html +2 -2
- mage_ai/server/frontend_dist/manage/users.html +2 -2
- mage_ai/server/frontend_dist/manage.html +2 -2
- mage_ai/server/frontend_dist/oauth.html +2 -2
- mage_ai/server/frontend_dist/overview.html +2 -2
- mage_ai/server/frontend_dist/pipeline-runs.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline].html +2 -2
- mage_ai/server/frontend_dist/pipelines.html +2 -2
- mage_ai/server/frontend_dist/platform/global-hooks/[...slug].html +2 -2
- mage_ai/server/frontend_dist/platform/global-hooks.html +2 -2
- mage_ai/server/frontend_dist/settings/account/profile.html +2 -2
- mage_ai/server/frontend_dist/settings/platform/preferences.html +2 -2
- mage_ai/server/frontend_dist/settings/platform/settings.html +2 -2
- mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +2 -2
- mage_ai/server/frontend_dist/settings/workspace/permissions.html +2 -2
- mage_ai/server/frontend_dist/settings/workspace/preferences.html +2 -2
- mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +2 -2
- mage_ai/server/frontend_dist/settings/workspace/roles.html +2 -2
- mage_ai/server/frontend_dist/settings/workspace/sync-data.html +2 -2
- mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +2 -2
- mage_ai/server/frontend_dist/settings/workspace/users.html +2 -2
- mage_ai/server/frontend_dist/settings.html +2 -2
- mage_ai/server/frontend_dist/sign-in.html +6 -6
- mage_ai/server/frontend_dist/templates/[...slug].html +2 -2
- mage_ai/server/frontend_dist/templates.html +2 -2
- mage_ai/server/frontend_dist/terminal.html +2 -2
- mage_ai/server/frontend_dist/test.html +2 -2
- mage_ai/server/frontend_dist/triggers.html +2 -2
- mage_ai/server/frontend_dist/version-control.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/404.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/_next/static/{CKCvjsYCf2imD2X8zAOBf → TdpLLFome13qvM0gXvpHs}/_buildManifest.js +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-b3502f3f1aa92ac7.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2717-d9200be634dd6766.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3548-9d26185b3fb663b1.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-6d708c6b2153ea08.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-8a23dd8360593e7a.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-b9b85ba10667e654.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9624-8b8e100079ab69e1.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-2a69553d8c6eeb53.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/index-4e12783b064c1cfe.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-4bfc84ff07d7656f.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipeline-runs-a66b4c7641ae03eb.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-6d183f91a2ff6668.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-7181b086c93784d2.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-38e1fbcfbfc1014e.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-b645a6d13ab9fe3a.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-59aca25a5b1d3998.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-eb11c5390c982b49.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{triggers-cb88fd075a357fcf.js → triggers-4612d15a65c35912.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-3591d035bb3bb2b8.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-32985f3f7c7dd3ab.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-c2e9ef989c8bfa73.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-349af617d05f001b.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-60d01d3887e31136.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/{users-86814e581acaf5db.js → users-a4db8710f703c729.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-09414a8b66fb6f06.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/triggers-9cba3211434a8966.js → frontend_dist_base_path_template/_next/static/chunks/pages/triggers-a599c6ac89be8c8d.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-3433c8b22e8342aa.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/block-layout.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/compute.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/files.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/global-data-products.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/global-hooks/[...slug].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/global-hooks.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/index.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/manage/files.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/manage/settings.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/manage/users.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/manage.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/oauth.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/overview.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/platform/global-hooks/[...slug].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/platform/global-hooks.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/settings/platform/preferences.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/settings/platform/settings.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/settings.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/sign-in.html +6 -6
- mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/templates.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/terminal.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/test.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/triggers.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/version-control.html +2 -2
- mage_ai/server/scheduler_manager.py +9 -0
- mage_ai/server/server.py +47 -17
- mage_ai/server/utils/output_display.py +2 -2
- mage_ai/server/websocket_server.py +1 -0
- mage_ai/services/aws/ecs/ecs.py +1 -0
- mage_ai/services/k8s/config.py +4 -4
- mage_ai/services/k8s/utils.py +97 -0
- mage_ai/settings/keys/auth.py +2 -0
- mage_ai/settings/server.py +1 -1
- mage_ai/shared/parsers.py +6 -1
- mage_ai/streaming/sources/influxdb.py +2 -0
- mage_ai/streaming/sources/kafka.py +1 -1
- mage_ai/tests/api/endpoints/mixins.py +10 -9
- mage_ai/tests/api/endpoints/test_seeds.py +24 -0
- mage_ai/tests/api/operations/base/mixins.py +1 -1
- mage_ai/tests/api/operations/test_sessions.py +53 -2
- mage_ai/tests/api/resources/test_pipeline_resource.py +2 -2
- mage_ai/tests/authentication/oauth/test_utils.py +1 -1
- mage_ai/tests/authentication/providers/test_okta.py +43 -0
- mage_ai/tests/data_preparation/models/block/test_global_data_product.py +2 -0
- mage_ai/tests/orchestration/db/models/test_oauth.py +3 -3
- mage_ai/tests/orchestration/queue/test_process_queue.py +1 -0
- mage_ai/tests/orchestration/triggers/test_global_data_product.py +138 -136
- mage_ai/tests/server/test_server.py +27 -4
- mage_ai/tests/services/k8s/test_job_manager.py +9 -6
- mage_ai/version_control/branch/utils.py +2 -1
- mage_ai/version_control/models.py +3 -2
- {mage_ai-0.9.68.dist-info → mage_ai-0.9.70.dist-info}/METADATA +5 -5
- {mage_ai-0.9.68.dist-info → mage_ai-0.9.70.dist-info}/RECORD +272 -264
- mage_ai/server/frontend_dist/_next/static/chunks/1557-01f0843dc6ac4971.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2717-b5f9575799b594d5.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/3548-961ff79ca70038c7.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/5699-6efc749f2f8ddd20.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/7361-18d9d8be96e1ce97.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/7966-f07b2913f7326b50.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9624-59b2f803f9c88cd6.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-08790743315de36a.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/index-13760bb72d823b69.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-852d403c7bda21b3.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-ff4bd7a8ec3bab40.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-a8b61d8d239fd16f.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-bd0aff5a5ed8888c.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-d1ee961387c58b7f.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-f028ef3880ed856c.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-ceb06e1616ee9610.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-8ff16ef9566e911a.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/settings-74d76300942dcee8.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-d7a8bc51bb7a1082.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-79a4cf66a623e667.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/sign-in-f59d34429fe022ee.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-5753fac7c1bfdc88.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-01f0843dc6ac4971.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2717-b5f9575799b594d5.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3548-961ff79ca70038c7.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5699-6efc749f2f8ddd20.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-18d9d8be96e1ce97.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7966-f07b2913f7326b50.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9624-59b2f803f9c88cd6.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-08790743315de36a.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/index-13760bb72d823b69.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-852d403c7bda21b3.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-ff4bd7a8ec3bab40.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-a8b61d8d239fd16f.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-bd0aff5a5ed8888c.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-d1ee961387c58b7f.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-f028ef3880ed856c.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-ceb06e1616ee9610.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-8ff16ef9566e911a.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/settings-74d76300942dcee8.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-d7a8bc51bb7a1082.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-79a4cf66a623e667.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-f59d34429fe022ee.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-5753fac7c1bfdc88.js +0 -1
- /mage_ai/server/frontend_dist/_next/static/{i8pymuJDTVHdWjUP1QSh1 → RhDiJSkcjCsh4xxX4BFBk}/_ssgManifest.js +0 -0
- /mage_ai/server/frontend_dist_base_path_template/_next/static/{CKCvjsYCf2imD2X8zAOBf → TdpLLFome13qvM0gXvpHs}/_ssgManifest.js +0 -0
- {mage_ai-0.9.68.dist-info → mage_ai-0.9.70.dist-info}/LICENSE +0 -0
- {mage_ai-0.9.68.dist-info → mage_ai-0.9.70.dist-info}/WHEEL +0 -0
- {mage_ai-0.9.68.dist-info → mage_ai-0.9.70.dist-info}/entry_points.txt +0 -0
- {mage_ai-0.9.68.dist-info → mage_ai-0.9.70.dist-info}/top_level.txt +0 -0
|
@@ -2,6 +2,7 @@ from logging import Logger
|
|
|
2
2
|
from typing import Dict, List
|
|
3
3
|
|
|
4
4
|
from mage_ai.data_preparation.models.block import Block
|
|
5
|
+
from mage_ai.data_preparation.models.block.remote.models import RemoteBlock
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class GlobalDataProductBlock(Block):
|
|
@@ -37,13 +38,35 @@ class GlobalDataProductBlock(Block):
|
|
|
37
38
|
# Avoid circular dependency of Pipeline class
|
|
38
39
|
from mage_ai.orchestration.triggers import global_data_product as trigger
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
global_data_product = self.get_global_data_product()
|
|
42
|
+
|
|
43
|
+
pipeline_run = trigger.trigger_and_check_status(
|
|
44
|
+
global_data_product,
|
|
42
45
|
block=self,
|
|
43
46
|
from_notebook=from_notebook,
|
|
44
47
|
logger=logger,
|
|
45
48
|
logging_tags=logging_tags,
|
|
49
|
+
poll_interval=30,
|
|
50
|
+
remote_blocks=global_vars.get('remote_blocks'),
|
|
46
51
|
variables=global_vars.get('variables') if global_vars else None,
|
|
47
52
|
)
|
|
48
53
|
|
|
54
|
+
if pipeline_run and pipeline_run.pipeline:
|
|
55
|
+
pipeline = pipeline_run.pipeline
|
|
56
|
+
|
|
57
|
+
arr = []
|
|
58
|
+
|
|
59
|
+
for block in global_data_product.get_blocks():
|
|
60
|
+
if block and block.uuid:
|
|
61
|
+
arr.append(RemoteBlock.load(
|
|
62
|
+
block_uuid=block.uuid,
|
|
63
|
+
execution_partition=pipeline_run.execution_partition,
|
|
64
|
+
pipeline_uuid=pipeline.uuid,
|
|
65
|
+
repo_path=pipeline.repo_path,
|
|
66
|
+
))
|
|
67
|
+
|
|
68
|
+
return [
|
|
69
|
+
dict(remote_blocks=arr),
|
|
70
|
+
]
|
|
71
|
+
|
|
49
72
|
return []
|
|
@@ -155,7 +155,7 @@ class IntegrationBlock(Block):
|
|
|
155
155
|
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
156
156
|
|
|
157
157
|
for line in proc.stdout:
|
|
158
|
-
f.write(line.decode())
|
|
158
|
+
f.write(line.decode())
|
|
159
159
|
print_log_from_line(
|
|
160
160
|
line,
|
|
161
161
|
config=config,
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Any, List
|
|
3
|
+
|
|
4
|
+
from mage_ai.shared.models import BaseDataClass
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class RemoteBlock(BaseDataClass):
|
|
9
|
+
block_uuid: str
|
|
10
|
+
execution_partition: str = None
|
|
11
|
+
pipeline_uuid: str = None
|
|
12
|
+
repo_path: str = None
|
|
13
|
+
|
|
14
|
+
def __post_init__(self):
|
|
15
|
+
self._block = None
|
|
16
|
+
self._pipeline = None
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def pipeline(self):
|
|
20
|
+
from mage_ai.data_preparation.models.pipeline import Pipeline
|
|
21
|
+
|
|
22
|
+
if self._pipeline:
|
|
23
|
+
return self._pipeline
|
|
24
|
+
|
|
25
|
+
self._pipeline = Pipeline.get(
|
|
26
|
+
self.pipeline_uuid,
|
|
27
|
+
all_projects=True,
|
|
28
|
+
check_if_exists=False,
|
|
29
|
+
repo_path=self.repo_path,
|
|
30
|
+
use_repo_path=True if self.repo_path else False,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
return self._pipeline
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def block(self):
|
|
37
|
+
if self._block:
|
|
38
|
+
return self._block
|
|
39
|
+
|
|
40
|
+
self._block = self.pipeline.get_block(self.block_uuid)
|
|
41
|
+
|
|
42
|
+
return self._block
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def variable_uuids(self):
|
|
46
|
+
return self.block.output_variables(execution_partition=self.execution_partition)
|
|
47
|
+
|
|
48
|
+
def get_outputs(self, **kwargs) -> List[Any]:
|
|
49
|
+
arr = []
|
|
50
|
+
for variable_uuid in self.variable_uuids:
|
|
51
|
+
output = self.pipeline.get_block_variable(
|
|
52
|
+
self.block_uuid,
|
|
53
|
+
variable_uuid,
|
|
54
|
+
partition=self.execution_partition,
|
|
55
|
+
)
|
|
56
|
+
arr.append(output)
|
|
57
|
+
|
|
58
|
+
return arr
|
|
@@ -29,6 +29,7 @@ from mage_ai.data_preparation.models.block.dynamic.utils import (
|
|
|
29
29
|
from mage_ai.data_preparation.models.block.dynamic.utils import (
|
|
30
30
|
should_reduce_output as should_reduce_output_original,
|
|
31
31
|
)
|
|
32
|
+
from mage_ai.data_preparation.models.block.remote.models import RemoteBlock
|
|
32
33
|
from mage_ai.data_preparation.models.constants import (
|
|
33
34
|
DATAFRAME_ANALYSIS_MAX_COLUMNS,
|
|
34
35
|
BlockType,
|
|
@@ -393,6 +394,7 @@ def fetch_input_variables(
|
|
|
393
394
|
dynamic_block_flags: List[DynamicBlockFlag] = None,
|
|
394
395
|
metadata: Dict = None,
|
|
395
396
|
upstream_block_uuids_override: List[str] = None,
|
|
397
|
+
current_block=None,
|
|
396
398
|
) -> Tuple[List, List, List]:
|
|
397
399
|
"""
|
|
398
400
|
Fetches the input variables for a block.
|
|
@@ -510,6 +512,22 @@ def fetch_input_variables(
|
|
|
510
512
|
if BlockType.GLOBAL_DATA_PRODUCT == upstream_block.type:
|
|
511
513
|
global_data_product = upstream_block.get_global_data_product()
|
|
512
514
|
input_vars[idx] = global_data_product.get_outputs()
|
|
515
|
+
|
|
516
|
+
mds = {}
|
|
517
|
+
variable_uuids = upstream_block.output_variables(
|
|
518
|
+
execution_partition=execution_partition,
|
|
519
|
+
)
|
|
520
|
+
for variable_uuid in variable_uuids:
|
|
521
|
+
md = pipeline.get_block_variable(
|
|
522
|
+
upstream_block_uuid,
|
|
523
|
+
variable_uuid,
|
|
524
|
+
partition=execution_partition,
|
|
525
|
+
)
|
|
526
|
+
if isinstance(md, dict):
|
|
527
|
+
mds.update(md)
|
|
528
|
+
|
|
529
|
+
kwargs_vars.append(mds)
|
|
530
|
+
|
|
513
531
|
continue
|
|
514
532
|
|
|
515
533
|
# Block output variables for upstream_block_uuid
|
|
@@ -743,6 +761,26 @@ def fetch_input_variables(
|
|
|
743
761
|
__uuid='output_variables'
|
|
744
762
|
)
|
|
745
763
|
|
|
764
|
+
if kwargs_vars:
|
|
765
|
+
kwargs_vars2 = []
|
|
766
|
+
|
|
767
|
+
remote_blocks_output = []
|
|
768
|
+
for kwargs in kwargs_vars:
|
|
769
|
+
for remote_block_dict in kwargs.get('remote_blocks', []):
|
|
770
|
+
# Global data products only need the remote block information, not the output
|
|
771
|
+
if current_block and BlockType.GLOBAL_DATA_PRODUCT == current_block.type:
|
|
772
|
+
output = remote_block_dict
|
|
773
|
+
else:
|
|
774
|
+
output = RemoteBlock.load(**remote_block_dict).get_outputs()
|
|
775
|
+
remote_blocks_output.append(output)
|
|
776
|
+
|
|
777
|
+
for kwargs in kwargs_vars:
|
|
778
|
+
if kwargs.get('remote_blocks'):
|
|
779
|
+
kwargs['remote_blocks'] = remote_blocks_output
|
|
780
|
+
kwargs_vars2.append(kwargs)
|
|
781
|
+
|
|
782
|
+
kwargs_vars = kwargs_vars2
|
|
783
|
+
|
|
746
784
|
return input_vars, kwargs_vars, upstream_block_uuids_final
|
|
747
785
|
|
|
748
786
|
|
|
@@ -75,6 +75,18 @@ class GlobalDataProduct:
|
|
|
75
75
|
|
|
76
76
|
return self._object
|
|
77
77
|
|
|
78
|
+
def get_blocks(self) -> List:
|
|
79
|
+
arr = []
|
|
80
|
+
|
|
81
|
+
if not self.settings or len(self.settings) == 0:
|
|
82
|
+
return arr
|
|
83
|
+
|
|
84
|
+
if GlobalDataProductObjectType.PIPELINE == self.object_type:
|
|
85
|
+
for block_uuid in self.settings.keys():
|
|
86
|
+
arr.append(self.pipeline.get_block(block_uuid))
|
|
87
|
+
|
|
88
|
+
return arr
|
|
89
|
+
|
|
78
90
|
def get_outputs(self, from_notebook: bool = False, global_vars: Dict = None, **kwargs) -> Dict:
|
|
79
91
|
data = {}
|
|
80
92
|
|
|
@@ -7,7 +7,7 @@ import tempfile
|
|
|
7
7
|
import zipfile
|
|
8
8
|
from datetime import datetime, timezone
|
|
9
9
|
from io import BytesIO
|
|
10
|
-
from typing import Any, Callable, Dict, List, Tuple, Union
|
|
10
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
|
11
11
|
|
|
12
12
|
import aiofiles
|
|
13
13
|
import pytz
|
|
@@ -62,6 +62,8 @@ from mage_ai.data_preparation.shared.utils import get_template_vars
|
|
|
62
62
|
from mage_ai.data_preparation.templates.utils import copy_template_directory
|
|
63
63
|
from mage_ai.data_preparation.variable_manager import VariableManager
|
|
64
64
|
from mage_ai.orchestration.constants import Entity
|
|
65
|
+
from mage_ai.orchestration.notification.config import NotificationConfig
|
|
66
|
+
from mage_ai.orchestration.notification.sender import NotificationSender
|
|
65
67
|
from mage_ai.settings.platform import build_repo_path_for_all_projects
|
|
66
68
|
from mage_ai.settings.platform.constants import project_platform_activated
|
|
67
69
|
from mage_ai.settings.repo import get_repo_path
|
|
@@ -97,6 +99,7 @@ class Pipeline:
|
|
|
97
99
|
self.description = description
|
|
98
100
|
self.executor_config = dict()
|
|
99
101
|
self.executor_type = None
|
|
102
|
+
self._rendered_executor_type = None # Render template variables
|
|
100
103
|
self.extensions = {}
|
|
101
104
|
self.name = None
|
|
102
105
|
self.notification_config = dict()
|
|
@@ -339,7 +342,7 @@ class Pipeline:
|
|
|
339
342
|
duplicate_pipeline_dict['name'] = duplicate_pipeline_uuid
|
|
340
343
|
safe_write(
|
|
341
344
|
duplicate_pipeline.config_path,
|
|
342
|
-
yaml.dump(duplicate_pipeline_dict)
|
|
345
|
+
yaml.dump(duplicate_pipeline_dict),
|
|
343
346
|
)
|
|
344
347
|
|
|
345
348
|
tags = duplicate_pipeline_dict.get('tags')
|
|
@@ -514,7 +517,7 @@ class Pipeline:
|
|
|
514
517
|
|
|
515
518
|
if not os.path.exists(config_path):
|
|
516
519
|
raise Exception(f'Pipeline {uuid} does not exist.')
|
|
517
|
-
async with aiofiles.open(config_path, mode='r') as f:
|
|
520
|
+
async with aiofiles.open(config_path, mode='r', encoding='utf-8') as f:
|
|
518
521
|
config = yaml.safe_load(await f.read()) or {}
|
|
519
522
|
|
|
520
523
|
if PipelineType.INTEGRATION == config.get('type'):
|
|
@@ -673,6 +676,7 @@ class Pipeline:
|
|
|
673
676
|
analyze_outputs: bool = False,
|
|
674
677
|
build_block_output_stdout: Callable[..., object] = None,
|
|
675
678
|
global_vars=None,
|
|
679
|
+
retry_config=None,
|
|
676
680
|
run_sensors: bool = True,
|
|
677
681
|
run_tests: bool = True,
|
|
678
682
|
update_status: bool = True,
|
|
@@ -689,6 +693,7 @@ class Pipeline:
|
|
|
689
693
|
StreamingPipelineExecutor(self).execute(
|
|
690
694
|
build_block_output_stdout=build_block_output_stdout,
|
|
691
695
|
global_vars=global_vars,
|
|
696
|
+
retry_config=retry_config,
|
|
692
697
|
)
|
|
693
698
|
else:
|
|
694
699
|
root_blocks = []
|
|
@@ -715,7 +720,7 @@ class Pipeline:
|
|
|
715
720
|
def get_config_from_yaml(self):
|
|
716
721
|
if not os.path.exists(self.config_path):
|
|
717
722
|
raise Exception(f'Pipeline {self.uuid} does not exist in repo_path {self.repo_path}.')
|
|
718
|
-
with open(self.config_path) as fp:
|
|
723
|
+
with open(self.config_path, encoding='utf-8') as fp:
|
|
719
724
|
config = yaml.full_load(fp) or {}
|
|
720
725
|
return config
|
|
721
726
|
|
|
@@ -726,6 +731,16 @@ class Pipeline:
|
|
|
726
731
|
config = json.load(f)
|
|
727
732
|
return config
|
|
728
733
|
|
|
734
|
+
def get_notification_sender(self):
|
|
735
|
+
return NotificationSender(
|
|
736
|
+
NotificationConfig.load(
|
|
737
|
+
config=merge_dict(
|
|
738
|
+
self.repo_config.notification_config,
|
|
739
|
+
self.notification_config,
|
|
740
|
+
),
|
|
741
|
+
),
|
|
742
|
+
)
|
|
743
|
+
|
|
729
744
|
def load_config_from_yaml(self):
|
|
730
745
|
catalog = None
|
|
731
746
|
if os.path.exists(self.catalog_config_path):
|
|
@@ -1294,7 +1309,9 @@ class Pipeline:
|
|
|
1294
1309
|
file_path = (configuration.get('file_source') or {}).get('path')
|
|
1295
1310
|
if file_path:
|
|
1296
1311
|
# Check for block name with period to avoid replacing a directory name
|
|
1297
|
-
new_file_path = file_path.replace(
|
|
1312
|
+
new_file_path = file_path.replace(
|
|
1313
|
+
f'{clean_name(block.name)}.', f'{clean_name(name)}.'
|
|
1314
|
+
)
|
|
1298
1315
|
configuration['file_source']['path'] = new_file_path
|
|
1299
1316
|
block_update_payload['configuration'] = configuration
|
|
1300
1317
|
blocks_to_remove_from_cache.append(block.to_dict())
|
|
@@ -1752,10 +1769,13 @@ class Pipeline:
|
|
|
1752
1769
|
def get_executable_blocks(self):
|
|
1753
1770
|
return [b for b in self.blocks_by_uuid.values() if b.executable]
|
|
1754
1771
|
|
|
1755
|
-
def get_executor_type(self) -> str:
|
|
1756
|
-
if self.
|
|
1757
|
-
|
|
1758
|
-
|
|
1772
|
+
def get_executor_type(self) -> Optional[str]:
|
|
1773
|
+
if self._rendered_executor_type is None:
|
|
1774
|
+
if self.executor_type:
|
|
1775
|
+
return Template(self.executor_type).render(**get_template_vars())
|
|
1776
|
+
else:
|
|
1777
|
+
self._rendered_executor_type = self.executor_type
|
|
1778
|
+
return self._rendered_executor_type
|
|
1759
1779
|
|
|
1760
1780
|
def has_block(self, block_uuid: str, block_type: str = None, extension_uuid: str = None):
|
|
1761
1781
|
if extension_uuid:
|
|
@@ -2132,7 +2152,7 @@ class Pipeline:
|
|
|
2132
2152
|
'Blocks cannot be added or removed when saving content, please try again.',
|
|
2133
2153
|
)
|
|
2134
2154
|
|
|
2135
|
-
content = yaml.dump(pipeline_dict)
|
|
2155
|
+
content = yaml.dump(pipeline_dict, allow_unicode=True)
|
|
2136
2156
|
|
|
2137
2157
|
safe_write(self.config_path, content)
|
|
2138
2158
|
|
|
@@ -2205,7 +2225,7 @@ class Pipeline:
|
|
|
2205
2225
|
'Blocks cannot be added or removed when saving content, please try again.',
|
|
2206
2226
|
)
|
|
2207
2227
|
|
|
2208
|
-
content = yaml.dump(pipeline_dict)
|
|
2228
|
+
content = yaml.dump(pipeline_dict, allow_unicode=True)
|
|
2209
2229
|
|
|
2210
2230
|
test_path = f'{self.config_path}.test'
|
|
2211
2231
|
async with aiofiles.open(test_path, mode='w', encoding='utf-8') as fp:
|
|
@@ -206,6 +206,7 @@ def add_or_update_trigger_for_pipeline_and_persist(
|
|
|
206
206
|
trigger: Trigger,
|
|
207
207
|
pipeline_uuid: str,
|
|
208
208
|
update_only_if_exists: bool = False,
|
|
209
|
+
old_trigger_name: str = None,
|
|
209
210
|
) -> Dict:
|
|
210
211
|
trigger_configs_by_name = get_trigger_configs_by_name(pipeline_uuid)
|
|
211
212
|
|
|
@@ -214,13 +215,14 @@ def add_or_update_trigger_for_pipeline_and_persist(
|
|
|
214
215
|
have, so we need to set "envs" on the updated trigger if it already exists.
|
|
215
216
|
Otherwise, it will get overwritten when updating the trigger in code.
|
|
216
217
|
"""
|
|
217
|
-
|
|
218
|
+
trigger_name = trigger.name if old_trigger_name is None else old_trigger_name
|
|
219
|
+
existing_trigger = trigger_configs_by_name.get(trigger_name)
|
|
218
220
|
if existing_trigger is not None:
|
|
219
221
|
trigger.envs = existing_trigger.get('envs', [])
|
|
220
222
|
elif update_only_if_exists:
|
|
221
223
|
return None
|
|
222
224
|
|
|
223
|
-
trigger_configs_by_name[
|
|
225
|
+
trigger_configs_by_name[trigger_name] = trigger.to_dict()
|
|
224
226
|
yaml_config = dict(triggers=list(trigger_configs_by_name.values()))
|
|
225
227
|
content = yaml.safe_dump(yaml_config)
|
|
226
228
|
trigger_file_path = get_triggers_file_path(pipeline_uuid)
|
|
@@ -7,7 +7,7 @@ from typing import Any, Dict, List
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
import pandas as pd
|
|
9
9
|
import polars as pl
|
|
10
|
-
from pandas.api.types import is_object_dtype
|
|
10
|
+
from pandas.api.types import infer_dtype, is_object_dtype
|
|
11
11
|
from pandas.core.indexes.range import RangeIndex
|
|
12
12
|
|
|
13
13
|
from mage_ai.data_cleaner.shared.utils import is_geo_dataframe, is_spark_dataframe
|
|
@@ -18,6 +18,7 @@ from mage_ai.data_preparation.models.constants import (
|
|
|
18
18
|
VARIABLE_DIR,
|
|
19
19
|
)
|
|
20
20
|
from mage_ai.data_preparation.models.utils import ( # dask_from_pandas,
|
|
21
|
+
AMBIGUOUS_COLUMN_TYPES,
|
|
21
22
|
STRING_SERIALIZABLE_COLUMN_TYPES,
|
|
22
23
|
apply_transform_pandas,
|
|
23
24
|
cast_column_types,
|
|
@@ -282,7 +283,9 @@ class Variable:
|
|
|
282
283
|
else:
|
|
283
284
|
self.__write_json(data)
|
|
284
285
|
|
|
285
|
-
self.
|
|
286
|
+
if self.variable_type != VariableType.SPARK_DATAFRAME:
|
|
287
|
+
# Not write json file in spark data directory to avoid read error
|
|
288
|
+
self.write_metadata()
|
|
286
289
|
|
|
287
290
|
async def write_data_async(self, data: Any) -> None:
|
|
288
291
|
"""
|
|
@@ -315,7 +318,9 @@ class Variable:
|
|
|
315
318
|
else:
|
|
316
319
|
await self.__write_json_async(data)
|
|
317
320
|
|
|
318
|
-
self.
|
|
321
|
+
if self.variable_type != VariableType.SPARK_DATAFRAME:
|
|
322
|
+
# Not write json file in spark data directory to avoid read error
|
|
323
|
+
self.write_metadata()
|
|
319
324
|
|
|
320
325
|
def write_metadata(self) -> None:
|
|
321
326
|
"""
|
|
@@ -578,10 +583,19 @@ class Variable:
|
|
|
578
583
|
else:
|
|
579
584
|
series_non_null = df_col.dropna()
|
|
580
585
|
if len(series_non_null) > 0:
|
|
581
|
-
|
|
586
|
+
sample_element = series_non_null.iloc[0]
|
|
587
|
+
coltype = type(sample_element)
|
|
588
|
+
coltype_inferred = infer_dtype(series_non_null)
|
|
582
589
|
if is_object_dtype(series_non_null.dtype):
|
|
583
590
|
if coltype.__name__ in STRING_SERIALIZABLE_COLUMN_TYPES:
|
|
584
591
|
cast_coltype = str
|
|
592
|
+
# If the column is a "primitive" type, i.e. int/bool/etc and there is
|
|
593
|
+
# a mix of types in the column, cast to string
|
|
594
|
+
elif (
|
|
595
|
+
not hasattr(sample_element, '__dict__')
|
|
596
|
+
and coltype_inferred in AMBIGUOUS_COLUMN_TYPES
|
|
597
|
+
):
|
|
598
|
+
cast_coltype = str
|
|
585
599
|
else:
|
|
586
600
|
cast_coltype = coltype
|
|
587
601
|
try:
|
|
@@ -310,8 +310,9 @@ def get_cluster_type(repo_path=None) -> Optional[ClusterType]:
|
|
|
310
310
|
|
|
311
311
|
def set_project_uuid_from_metadata() -> None:
|
|
312
312
|
global project_uuid
|
|
313
|
-
|
|
314
|
-
|
|
313
|
+
metadata_path = get_metadata_path(root_project=True)
|
|
314
|
+
if os.path.exists(metadata_path):
|
|
315
|
+
with open(metadata_path, 'r', encoding='utf-8') as f:
|
|
315
316
|
config = yml.load(f) or {}
|
|
316
317
|
project_uuid = config.get('project_uuid')
|
|
317
318
|
|
|
@@ -25,7 +25,7 @@ def get_template_vars_no_db(include_python_libraries: Dict = None) -> Dict[str,
|
|
|
25
25
|
try:
|
|
26
26
|
from mage_ai.services.aws.secrets_manager.secrets_manager import get_secret
|
|
27
27
|
kwargs['aws_secret_var'] = get_secret
|
|
28
|
-
except
|
|
28
|
+
except Exception:
|
|
29
29
|
pass
|
|
30
30
|
|
|
31
31
|
try:
|
|
@@ -92,12 +92,18 @@ class LocalStorage(BaseStorage):
|
|
|
92
92
|
os.makedirs(dirname, exist_ok=True)
|
|
93
93
|
|
|
94
94
|
with open(file_path, 'w') as file:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
try:
|
|
96
|
+
simplejson.dump(
|
|
97
|
+
data,
|
|
98
|
+
file,
|
|
99
|
+
default=encode_complex,
|
|
100
|
+
ignore_nan=True,
|
|
101
|
+
)
|
|
102
|
+
except ValueError as err:
|
|
103
|
+
if is_debug():
|
|
104
|
+
raise err
|
|
105
|
+
else:
|
|
106
|
+
print(f'[ERROR] LocalStorage.write_json_file: {err}')
|
|
101
107
|
|
|
102
108
|
async def write_json_file_async(self, file_path: str, data) -> None:
|
|
103
109
|
async with aiofiles.open(file_path, mode='w') as file:
|
|
@@ -23,8 +23,8 @@ def export_data_to_mysql(df: DataFrame, **kwargs) -> None:
|
|
|
23
23
|
with MySQL.with_config(ConfigFileLoader(config_path, config_profile)) as loader:
|
|
24
24
|
loader.export(
|
|
25
25
|
df,
|
|
26
|
-
None,
|
|
27
|
-
table_name,
|
|
26
|
+
schema_name=None,
|
|
27
|
+
table_name=table_name,
|
|
28
28
|
index=False, # Specifies whether to include index in exported table
|
|
29
29
|
if_exists='replace', # Specify resolution policy if table name already exists
|
|
30
30
|
)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from os import path
|
|
2
|
+
|
|
3
|
+
from pandas import DataFrame
|
|
4
|
+
|
|
5
|
+
from mage_ai.settings.repo import get_repo_path
|
|
6
|
+
from mage_ai.io.config import ConfigFileLoader
|
|
7
|
+
from mage_ai.io.oracledb import OracleDB
|
|
8
|
+
|
|
9
|
+
if 'data_exporter' not in globals():
|
|
10
|
+
from mage_ai.data_preparation.decorators import data_exporter
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@data_exporter
|
|
14
|
+
def export_data_to_oracledb(df: DataFrame, **kwargs) -> None:
|
|
15
|
+
"""
|
|
16
|
+
Template to export data to Oracledb.
|
|
17
|
+
"""
|
|
18
|
+
config_path = path.join(get_repo_path(), 'io_config.yaml')
|
|
19
|
+
config_profile = 'default'
|
|
20
|
+
table_name = 'your_table_name'
|
|
21
|
+
|
|
22
|
+
with OracleDB.with_config(ConfigFileLoader(config_path, config_profile)) as exporter:
|
|
23
|
+
exporter.export(
|
|
24
|
+
df,
|
|
25
|
+
table_name=table_name,
|
|
26
|
+
if_exists='replace', # Specify resolution policy if table name already exists
|
|
27
|
+
)
|