mage-ai 0.9.67__py3-none-any.whl → 0.9.69__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/monitors/BaseMonitor.py +1 -2
- mage_ai/api/policies/PipelinePolicy.py +2 -0
- mage_ai/api/resources/BlockLayoutItemResource.py +2 -2
- mage_ai/api/resources/BlockResource.py +4 -3
- mage_ai/api/resources/CacheItemResource.py +1 -1
- mage_ai/api/resources/GitBranchResource.py +3 -5
- mage_ai/api/resources/PageBlockLayoutResource.py +2 -2
- mage_ai/api/resources/PipelineResource.py +13 -0
- mage_ai/api/resources/PipelineRunResource.py +10 -1
- mage_ai/api/resources/SeedResource.py +2 -1
- mage_ai/api/resources/SessionResource.py +13 -1
- 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/tag.py +3 -0
- mage_ai/cluster_manager/manage.py +4 -1
- mage_ai/data_preparation/executors/k8s_block_executor.py +8 -1
- mage_ai/data_preparation/executors/k8s_pipeline_executor.py +12 -1
- mage_ai/data_preparation/executors/streaming_pipeline_executor.py +77 -7
- mage_ai/data_preparation/logging/gcs_logger_manager.py +7 -4
- mage_ai/data_preparation/models/block/__init__.py +28 -71
- mage_ai/data_preparation/models/block/block_factory.py +77 -0
- mage_ai/data_preparation/models/block/data_integration/mixins.py +16 -5
- mage_ai/data_preparation/models/block/dbt/block.py +5 -7
- mage_ai/data_preparation/models/block/dynamic/child.py +3 -0
- 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 +9 -3
- mage_ai/data_preparation/models/block/integration/__init__.py +13 -9
- mage_ai/data_preparation/models/block/platform/mixins.py +1 -1
- mage_ai/data_preparation/models/block/sql/__init__.py +1 -1
- mage_ai/data_preparation/models/pipeline.py +102 -19
- 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/gcs_storage.py +1 -1
- mage_ai/data_preparation/templates/constants.py +7 -0
- 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/export_utils.py +3 -0
- mage_ai/io/mysql.py +38 -6
- mage_ai/io/oracledb.py +138 -3
- mage_ai/io/snowflake.py +152 -29
- mage_ai/io/sql.py +4 -0
- mage_ai/orchestration/db/__init__.py +2 -2
- mage_ai/orchestration/db/models/oauth.py +4 -4
- mage_ai/orchestration/db/models/schedules.py +10 -3
- mage_ai/orchestration/job_manager.py +6 -0
- mage_ai/orchestration/notification/sender.py +8 -0
- mage_ai/orchestration/pipeline_scheduler_original.py +26 -7
- 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/server/constants.py +1 -1
- mage_ai/server/frontend_dist/404.html +2 -2
- mage_ai/server/{frontend_dist_base_path_template/_next/static/khKiaJtwrslgMmp4YSa1f → frontend_dist/_next/static/_krrrgup_C-dPOpX36S8I}/_buildManifest.js +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1557-df144fbd8b2208c3.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-fa0792ddb88f4646.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/4241-ccd0126f5750cc35.js → frontend_dist/_next/static/chunks/4241-4499461184ba0d23.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/5627-237a3de578538022.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_base_path_template/_next/static/chunks/7966-5c1786fb7e7a48f5.js → frontend_dist/_next/static/chunks/7966-f07b2913f7326b50.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-d9c89527266296f7.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/users/[user]-8bbfa0c19b5e4cb3.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-852d403c7bda21b3.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-597b74828bf105db.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/{pipeline-runs-a66b4c7641ae03eb.js → pipeline-runs-3edc6270c5b0e962.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-a8b61d8d239fd16f.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-e1dd1ed71d26c10d.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.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]/syncs-90abafc7ed61c582.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-1bdfda8edc9cf4a8.js +1 -0
- 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-503049734a8b082f.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-5b26eeda8aed8a7b.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-79a4cf66a623e667.js → frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-8b793b3b696a2cd3.js} +1 -1
- mage_ai/server/frontend_dist/_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-7d38b2f7c3e918a1.js → frontend_dist/_next/static/chunks/pages/sign-in-09414a8b66fb6f06.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-9cba3211434a8966.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 +3 -3
- 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 +5 -5
- 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 +2 -2
- mage_ai/server/{frontend_dist/_next/static/vPsMu6Fi2zrHaf2fRXKRO → frontend_dist_base_path_template/_next/static/KLL5mirre9d7_ZeEpaw3s}/_buildManifest.js +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1557-df144fbd8b2208c3.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-fa0792ddb88f4646.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/4241-ccd0126f5750cc35.js → frontend_dist_base_path_template/_next/static/chunks/4241-4499461184ba0d23.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5627-237a3de578538022.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/_next/static/chunks/7966-5c1786fb7e7a48f5.js → frontend_dist_base_path_template/_next/static/chunks/7966-f07b2913f7326b50.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-d9c89527266296f7.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/users/[user]-8bbfa0c19b5e4cb3.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-852d403c7bda21b3.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-597b74828bf105db.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{pipeline-runs-a66b4c7641ae03eb.js → pipeline-runs-3edc6270c5b0e962.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-a8b61d8d239fd16f.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-e1dd1ed71d26c10d.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1417ad1c821d720a.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]/syncs-90abafc7ed61c582.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-1bdfda8edc9cf4a8.js +1 -0
- 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-503049734a8b082f.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-5b26eeda8aed8a7b.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-79a4cf66a623e667.js → frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-8b793b3b696a2cd3.js} +1 -1
- 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/_next/static/chunks/pages/sign-in-7d38b2f7c3e918a1.js → frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-09414a8b66fb6f06.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-9cba3211434a8966.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 +3 -3
- 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 +5 -5
- 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 +7 -0
- mage_ai/server/server.py +12 -5
- mage_ai/server/websocket_server.py +1 -0
- mage_ai/services/k8s/job_manager.py +8 -0
- mage_ai/services/slack/slack.py +10 -1
- mage_ai/services/spark/spark.py +9 -2
- mage_ai/settings/backends.py +8 -8
- mage_ai/settings/keys/auth.py +2 -0
- mage_ai/settings/models/configuration_option.py +10 -9
- mage_ai/settings/server.py +1 -1
- mage_ai/shared/files.py +19 -1
- mage_ai/shared/path_fixer.py +3 -0
- mage_ai/streaming/sources/base.py +5 -0
- mage_ai/streaming/sources/influxdb.py +2 -0
- mage_ai/streaming/sources/kafka.py +2 -1
- mage_ai/streaming/sources/mongodb.py +4 -0
- mage_ai/tests/api/endpoints/mixins.py +10 -9
- mage_ai/tests/api/endpoints/test_seeds.py +24 -0
- mage_ai/tests/api/operations/test_sessions.py +53 -2
- mage_ai/tests/authentication/providers/test_okta.py +43 -0
- mage_ai/tests/data_preparation/models/block/dbt/test_block.py +2 -2
- mage_ai/tests/data_preparation/models/block/dbt/test_block_sql.py +1 -1
- mage_ai/tests/data_preparation/models/block/dbt/test_block_yaml.py +1 -1
- mage_ai/tests/data_preparation/models/test_block.py +2 -1
- 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/test_pipeline_scheduler.py +2 -0
- mage_ai/tests/server/test_server.py +8 -4
- mage_ai/tests/settings/models/test_configuration_option.py +2 -2
- {mage_ai-0.9.67.dist-info → mage_ai-0.9.69.dist-info}/METADATA +6 -6
- {mage_ai-0.9.67.dist-info → mage_ai-0.9.69.dist-info}/RECORD +263 -259
- mage_ai/server/frontend_dist/_next/static/chunks/1557-01f0843dc6ac4971.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/181-e61915415a976861.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-13563a1ff815f922.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/pages/_app-1c1ffd928f5a00f7.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/index-b7b8695a7f9efde2.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/[user]-d3a5fd3119fdb1e4.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-42789d698d28a92f.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/overview-d05040edba41b2ac.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-aaf393c86fc1bda3.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-36377e679da2cd91.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1b688d61f8efe07a.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/settings-ed3331d22d5cff7d.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-d94e48bad89ba1e0.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-f508c2f261297724.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines-f99e99aa8f45529c.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/platform/preferences-6826000cdffc36b8.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-dde29a463495cebb.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-ab98a7b3a678669e.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/181-e61915415a976861.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-13563a1ff815f922.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/pages/_app-1c1ffd928f5a00f7.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/index-b7b8695a7f9efde2.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-d3a5fd3119fdb1e4.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-42789d698d28a92f.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/overview-d05040edba41b2ac.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-aaf393c86fc1bda3.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-36377e679da2cd91.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/[run]-1b688d61f8efe07a.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/settings-ed3331d22d5cff7d.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-d94e48bad89ba1e0.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-f508c2f261297724.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines-f99e99aa8f45529c.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/platform/preferences-6826000cdffc36b8.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-dde29a463495cebb.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-ab98a7b3a678669e.js +0 -1
- /mage_ai/server/frontend_dist/_next/static/{vPsMu6Fi2zrHaf2fRXKRO → _krrrgup_C-dPOpX36S8I}/_ssgManifest.js +0 -0
- /mage_ai/server/frontend_dist_base_path_template/_next/static/{khKiaJtwrslgMmp4YSa1f → KLL5mirre9d7_ZeEpaw3s}/_ssgManifest.js +0 -0
- {mage_ai-0.9.67.dist-info → mage_ai-0.9.69.dist-info}/LICENSE +0 -0
- {mage_ai-0.9.67.dist-info → mage_ai-0.9.69.dist-info}/WHEEL +0 -0
- {mage_ai-0.9.67.dist-info → mage_ai-0.9.69.dist-info}/entry_points.txt +0 -0
- {mage_ai-0.9.67.dist-info → mage_ai-0.9.69.dist-info}/top_level.txt +0 -0
|
@@ -15,8 +15,10 @@ import yaml
|
|
|
15
15
|
from jinja2 import Template
|
|
16
16
|
|
|
17
17
|
from mage_ai.authentication.permissions.constants import EntityName
|
|
18
|
+
from mage_ai.cache.block import BlockCache
|
|
18
19
|
from mage_ai.cache.pipeline import PipelineCache
|
|
19
20
|
from mage_ai.data_preparation.models.block import Block, run_blocks, run_blocks_sync
|
|
21
|
+
from mage_ai.data_preparation.models.block.block_factory import BlockFactory
|
|
20
22
|
from mage_ai.data_preparation.models.block.data_integration.utils import (
|
|
21
23
|
convert_outputs_to_data,
|
|
22
24
|
)
|
|
@@ -60,6 +62,8 @@ from mage_ai.data_preparation.shared.utils import get_template_vars
|
|
|
60
62
|
from mage_ai.data_preparation.templates.utils import copy_template_directory
|
|
61
63
|
from mage_ai.data_preparation.variable_manager import VariableManager
|
|
62
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
|
|
63
67
|
from mage_ai.settings.platform import build_repo_path_for_all_projects
|
|
64
68
|
from mage_ai.settings.platform.constants import project_platform_activated
|
|
65
69
|
from mage_ai.settings.repo import get_repo_path
|
|
@@ -82,6 +86,8 @@ class Pipeline:
|
|
|
82
86
|
repo_config=None,
|
|
83
87
|
catalog=None,
|
|
84
88
|
use_repo_path: bool = False,
|
|
89
|
+
description: str = None,
|
|
90
|
+
tags: List[str] = None,
|
|
85
91
|
):
|
|
86
92
|
self.block_configs = []
|
|
87
93
|
self.blocks_by_uuid = {}
|
|
@@ -90,7 +96,7 @@ class Pipeline:
|
|
|
90
96
|
self.concurrency_config = dict()
|
|
91
97
|
self.created_at = None
|
|
92
98
|
self.data_integration = None
|
|
93
|
-
self.description =
|
|
99
|
+
self.description = description
|
|
94
100
|
self.executor_config = dict()
|
|
95
101
|
self.executor_type = None
|
|
96
102
|
self.extensions = {}
|
|
@@ -101,7 +107,7 @@ class Pipeline:
|
|
|
101
107
|
self.run_pipeline_in_one_process = False
|
|
102
108
|
self.schedules = []
|
|
103
109
|
self.settings = {}
|
|
104
|
-
self.tags = []
|
|
110
|
+
self.tags = tags or []
|
|
105
111
|
self.type = PipelineType.PYTHON
|
|
106
112
|
self.use_repo_path = use_repo_path
|
|
107
113
|
self.uuid = uuid
|
|
@@ -215,7 +221,14 @@ class Pipeline:
|
|
|
215
221
|
self.widget_configs
|
|
216
222
|
|
|
217
223
|
@classmethod
|
|
218
|
-
def create(
|
|
224
|
+
def create(
|
|
225
|
+
self,
|
|
226
|
+
name: str,
|
|
227
|
+
description: str = None,
|
|
228
|
+
pipeline_type: PipelineType = PipelineType.PYTHON,
|
|
229
|
+
repo_path: str = None,
|
|
230
|
+
tags: List[str] = None,
|
|
231
|
+
):
|
|
219
232
|
"""
|
|
220
233
|
1. Create a new folder for pipeline
|
|
221
234
|
2. Create a new yaml file to store pipeline config
|
|
@@ -231,14 +244,20 @@ class Pipeline:
|
|
|
231
244
|
with open(os.path.join(pipeline_path, PIPELINE_CONFIG_FILE), 'w') as fp:
|
|
232
245
|
yaml.dump(dict(
|
|
233
246
|
created_at=str(datetime.now(tz=pytz.UTC)),
|
|
247
|
+
description=description,
|
|
234
248
|
name=name,
|
|
249
|
+
tags=tags or [],
|
|
235
250
|
uuid=uuid,
|
|
236
251
|
type=format_enum(pipeline_type or PipelineType.PYTHON),
|
|
237
252
|
), fp)
|
|
253
|
+
|
|
238
254
|
pipeline = Pipeline(
|
|
239
255
|
uuid,
|
|
256
|
+
description=description,
|
|
240
257
|
repo_path=repo_path,
|
|
258
|
+
tags=tags or [],
|
|
241
259
|
)
|
|
260
|
+
|
|
242
261
|
return pipeline
|
|
243
262
|
|
|
244
263
|
@classmethod
|
|
@@ -322,7 +341,7 @@ class Pipeline:
|
|
|
322
341
|
duplicate_pipeline_dict['name'] = duplicate_pipeline_uuid
|
|
323
342
|
safe_write(
|
|
324
343
|
duplicate_pipeline.config_path,
|
|
325
|
-
yaml.dump(duplicate_pipeline_dict)
|
|
344
|
+
yaml.dump(duplicate_pipeline_dict),
|
|
326
345
|
)
|
|
327
346
|
|
|
328
347
|
tags = duplicate_pipeline_dict.get('tags')
|
|
@@ -368,6 +387,54 @@ class Pipeline:
|
|
|
368
387
|
IntegrationPipeline,
|
|
369
388
|
)
|
|
370
389
|
|
|
390
|
+
config_path, repo_path = self._get_config_path(
|
|
391
|
+
uuid,
|
|
392
|
+
repo_path=repo_path,
|
|
393
|
+
all_projects=all_projects,
|
|
394
|
+
use_repo_path=use_repo_path,
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
if check_if_exists and not os.path.exists(config_path):
|
|
398
|
+
return None
|
|
399
|
+
|
|
400
|
+
pipeline = self(uuid, repo_path=repo_path, use_repo_path=use_repo_path)
|
|
401
|
+
if PipelineType.INTEGRATION == pipeline.type:
|
|
402
|
+
pipeline = IntegrationPipeline(uuid, repo_path=repo_path)
|
|
403
|
+
|
|
404
|
+
return pipeline
|
|
405
|
+
|
|
406
|
+
@classmethod
|
|
407
|
+
def get_config(
|
|
408
|
+
self,
|
|
409
|
+
uuid,
|
|
410
|
+
repo_path: str = None,
|
|
411
|
+
all_projects: bool = False,
|
|
412
|
+
use_repo_path: bool = False,
|
|
413
|
+
):
|
|
414
|
+
config_path, _ = self._get_config_path(
|
|
415
|
+
uuid,
|
|
416
|
+
repo_path=repo_path,
|
|
417
|
+
all_projects=all_projects,
|
|
418
|
+
use_repo_path=use_repo_path,
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
metadata_path = os.path.join(config_path, PIPELINE_CONFIG_FILE)
|
|
422
|
+
|
|
423
|
+
if not os.path.exists(metadata_path):
|
|
424
|
+
return None
|
|
425
|
+
|
|
426
|
+
with open(metadata_path) as fp:
|
|
427
|
+
config = yaml.full_load(fp) or {}
|
|
428
|
+
return config
|
|
429
|
+
|
|
430
|
+
@classmethod
|
|
431
|
+
def _get_config_path(
|
|
432
|
+
self,
|
|
433
|
+
uuid,
|
|
434
|
+
repo_path: str = None,
|
|
435
|
+
all_projects: bool = False,
|
|
436
|
+
use_repo_path: bool = False,
|
|
437
|
+
) -> Tuple[str, str]:
|
|
371
438
|
if all_projects and not use_repo_path and project_platform_activated():
|
|
372
439
|
from mage_ai.settings.platform.utils import get_pipeline_config_path
|
|
373
440
|
|
|
@@ -379,15 +446,7 @@ class Pipeline:
|
|
|
379
446
|
PIPELINES_FOLDER,
|
|
380
447
|
uuid,
|
|
381
448
|
)
|
|
382
|
-
|
|
383
|
-
if check_if_exists and not os.path.exists(config_path):
|
|
384
|
-
return None
|
|
385
|
-
|
|
386
|
-
pipeline = self(uuid, repo_path=repo_path, use_repo_path=use_repo_path)
|
|
387
|
-
if PipelineType.INTEGRATION == pipeline.type:
|
|
388
|
-
pipeline = IntegrationPipeline(uuid, repo_path=repo_path)
|
|
389
|
-
|
|
390
|
-
return pipeline
|
|
449
|
+
return config_path, repo_path
|
|
391
450
|
|
|
392
451
|
@classmethod
|
|
393
452
|
async def load_metadata(
|
|
@@ -457,7 +516,7 @@ class Pipeline:
|
|
|
457
516
|
|
|
458
517
|
if not os.path.exists(config_path):
|
|
459
518
|
raise Exception(f'Pipeline {uuid} does not exist.')
|
|
460
|
-
async with aiofiles.open(config_path, mode='r') as f:
|
|
519
|
+
async with aiofiles.open(config_path, mode='r', encoding='utf-8') as f:
|
|
461
520
|
config = yaml.safe_load(await f.read()) or {}
|
|
462
521
|
|
|
463
522
|
if PipelineType.INTEGRATION == config.get('type'):
|
|
@@ -616,6 +675,7 @@ class Pipeline:
|
|
|
616
675
|
analyze_outputs: bool = False,
|
|
617
676
|
build_block_output_stdout: Callable[..., object] = None,
|
|
618
677
|
global_vars=None,
|
|
678
|
+
retry_config=None,
|
|
619
679
|
run_sensors: bool = True,
|
|
620
680
|
run_tests: bool = True,
|
|
621
681
|
update_status: bool = True,
|
|
@@ -632,6 +692,7 @@ class Pipeline:
|
|
|
632
692
|
StreamingPipelineExecutor(self).execute(
|
|
633
693
|
build_block_output_stdout=build_block_output_stdout,
|
|
634
694
|
global_vars=global_vars,
|
|
695
|
+
retry_config=retry_config,
|
|
635
696
|
)
|
|
636
697
|
else:
|
|
637
698
|
root_blocks = []
|
|
@@ -658,7 +719,7 @@ class Pipeline:
|
|
|
658
719
|
def get_config_from_yaml(self):
|
|
659
720
|
if not os.path.exists(self.config_path):
|
|
660
721
|
raise Exception(f'Pipeline {self.uuid} does not exist in repo_path {self.repo_path}.')
|
|
661
|
-
with open(self.config_path) as fp:
|
|
722
|
+
with open(self.config_path, encoding='utf-8') as fp:
|
|
662
723
|
config = yaml.full_load(fp) or {}
|
|
663
724
|
return config
|
|
664
725
|
|
|
@@ -669,6 +730,16 @@ class Pipeline:
|
|
|
669
730
|
config = json.load(f)
|
|
670
731
|
return config
|
|
671
732
|
|
|
733
|
+
def get_notification_sender(self):
|
|
734
|
+
return NotificationSender(
|
|
735
|
+
NotificationConfig.load(
|
|
736
|
+
config=merge_dict(
|
|
737
|
+
self.repo_config.notification_config,
|
|
738
|
+
self.notification_config,
|
|
739
|
+
),
|
|
740
|
+
),
|
|
741
|
+
)
|
|
742
|
+
|
|
672
743
|
def load_config_from_yaml(self):
|
|
673
744
|
catalog = None
|
|
674
745
|
if os.path.exists(self.catalog_config_path):
|
|
@@ -717,7 +788,8 @@ class Pipeline:
|
|
|
717
788
|
)
|
|
718
789
|
|
|
719
790
|
language = c.get('language')
|
|
720
|
-
|
|
791
|
+
|
|
792
|
+
return BlockFactory.block_class_from_type(block_type, language=language, pipeline=self)(
|
|
721
793
|
c.get('name'),
|
|
722
794
|
c.get('uuid'),
|
|
723
795
|
block_type,
|
|
@@ -931,6 +1003,8 @@ class Pipeline:
|
|
|
931
1003
|
include_outputs=include_outputs,
|
|
932
1004
|
sample_count=sample_count,
|
|
933
1005
|
)
|
|
1006
|
+
if include_block_pipelines:
|
|
1007
|
+
shared_kwargs['block_cache'] = BlockCache()
|
|
934
1008
|
blocks_data = await asyncio.gather(
|
|
935
1009
|
*[b.to_dict_async(**merge_dict(shared_kwargs, dict(
|
|
936
1010
|
include_block_catalog=include_block_catalog,
|
|
@@ -991,6 +1065,7 @@ class Pipeline:
|
|
|
991
1065
|
old_uuid = None
|
|
992
1066
|
blocks_to_remove_from_cache = []
|
|
993
1067
|
block_uuids_to_add_to_cache = []
|
|
1068
|
+
tags_to_remove_from_cache = []
|
|
994
1069
|
should_update_block_cache = False
|
|
995
1070
|
should_update_tag_cache = False
|
|
996
1071
|
|
|
@@ -1043,6 +1118,10 @@ class Pipeline:
|
|
|
1043
1118
|
old_tags = self.tags or []
|
|
1044
1119
|
|
|
1045
1120
|
if sorted(new_tags) != sorted(old_tags):
|
|
1121
|
+
tags_diff = set(old_tags).symmetric_difference(set(new_tags))
|
|
1122
|
+
for tag in tags_diff:
|
|
1123
|
+
if tag in old_tags:
|
|
1124
|
+
tags_to_remove_from_cache.append(tag)
|
|
1046
1125
|
self.tags = new_tags
|
|
1047
1126
|
should_save = True
|
|
1048
1127
|
should_update_tag_cache = True
|
|
@@ -1229,7 +1308,9 @@ class Pipeline:
|
|
|
1229
1308
|
file_path = (configuration.get('file_source') or {}).get('path')
|
|
1230
1309
|
if file_path:
|
|
1231
1310
|
# Check for block name with period to avoid replacing a directory name
|
|
1232
|
-
new_file_path = file_path.replace(
|
|
1311
|
+
new_file_path = file_path.replace(
|
|
1312
|
+
f'{clean_name(block.name)}.', f'{clean_name(name)}.'
|
|
1313
|
+
)
|
|
1233
1314
|
configuration['file_source']['path'] = new_file_path
|
|
1234
1315
|
block_update_payload['configuration'] = configuration
|
|
1235
1316
|
blocks_to_remove_from_cache.append(block.to_dict())
|
|
@@ -1296,6 +1377,8 @@ class Pipeline:
|
|
|
1296
1377
|
|
|
1297
1378
|
cache = await TagCache.initialize_cache()
|
|
1298
1379
|
|
|
1380
|
+
for tag_uuid in tags_to_remove_from_cache:
|
|
1381
|
+
cache.remove_pipeline(tag_uuid, self.uuid, self.repo_path)
|
|
1299
1382
|
for tag_uuid in self.tags:
|
|
1300
1383
|
if old_uuid:
|
|
1301
1384
|
cache.remove_pipeline(tag_uuid, old_uuid, self.repo_path)
|
|
@@ -2065,7 +2148,7 @@ class Pipeline:
|
|
|
2065
2148
|
'Blocks cannot be added or removed when saving content, please try again.',
|
|
2066
2149
|
)
|
|
2067
2150
|
|
|
2068
|
-
content = yaml.dump(pipeline_dict)
|
|
2151
|
+
content = yaml.dump(pipeline_dict, allow_unicode=True)
|
|
2069
2152
|
|
|
2070
2153
|
safe_write(self.config_path, content)
|
|
2071
2154
|
|
|
@@ -2138,7 +2221,7 @@ class Pipeline:
|
|
|
2138
2221
|
'Blocks cannot be added or removed when saving content, please try again.',
|
|
2139
2222
|
)
|
|
2140
2223
|
|
|
2141
|
-
content = yaml.dump(pipeline_dict)
|
|
2224
|
+
content = yaml.dump(pipeline_dict, allow_unicode=True)
|
|
2142
2225
|
|
|
2143
2226
|
test_path = f'{self.config_path}.test'
|
|
2144
2227
|
async with aiofiles.open(test_path, mode='w', encoding='utf-8') as fp:
|
|
@@ -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:
|
|
@@ -148,7 +148,7 @@ class GCSStorage(BaseStorage):
|
|
|
148
148
|
df.write_parquet(buffer)
|
|
149
149
|
buffer.seek(0)
|
|
150
150
|
blob = self.bucket.blob(gcs_url_path(file_path))
|
|
151
|
-
blob.upload_from_string(buffer)
|
|
151
|
+
blob.upload_from_string(buffer.getvalue())
|
|
152
152
|
|
|
153
153
|
@contextmanager
|
|
154
154
|
def open_to_write(self, file_path: str) -> None:
|
|
@@ -608,6 +608,13 @@ TEMPLATES_ONLY_FOR_V2 = [
|
|
|
608
608
|
name='MySQL',
|
|
609
609
|
path='data_exporters/mysql.py',
|
|
610
610
|
),
|
|
611
|
+
dict(
|
|
612
|
+
block_type=BlockType.DATA_EXPORTER,
|
|
613
|
+
groups=[GROUP_DATABASES],
|
|
614
|
+
language=BlockLanguage.PYTHON,
|
|
615
|
+
name='OracleDB',
|
|
616
|
+
path='data_exporters/oracledb.py',
|
|
617
|
+
),
|
|
611
618
|
dict(
|
|
612
619
|
block_type=BlockType.DATA_EXPORTER,
|
|
613
620
|
groups=[GROUP_DATABASES],
|
|
@@ -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
|
+
)
|