castor-extractor 0.17.2__tar.gz → 0.17.3__tar.gz
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 castor-extractor might be problematic. Click here for more details.
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/CHANGELOG.md +4 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/PKG-INFO +6 -1
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/databricks/__init__.py +1 -1
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/databricks/client.py +94 -4
- castor_extractor-0.17.3/castor_extractor/warehouse/databricks/credentials.py +27 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/databricks/extract.py +2 -2
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/databricks/format.py +34 -8
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/databricks/format_test.py +44 -19
- castor_extractor-0.17.3/castor_extractor/warehouse/databricks/utils.py +27 -0
- castor_extractor-0.17.3/castor_extractor/warehouse/databricks/utils_test.py +25 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/pyproject.toml +11 -2
- castor_extractor-0.17.2/castor_extractor/warehouse/databricks/credentials.py +0 -28
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/Dockerfile +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/LICENCE +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/README.md +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_bigquery.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_databricks.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_domo.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_looker.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_metabase_api.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_metabase_db.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_mode.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_mysql.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_postgres.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_powerbi.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_qlik.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_redshift.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_salesforce.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_salesforce_reporting.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_sigma.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_snowflake.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_sqlserver.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_tableau.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/file_check.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/upload.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/file_checker/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/file_checker/column.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/file_checker/column_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/file_checker/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/file_checker/enums.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/file_checker/file.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/file_checker/file_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/file_checker/file_test_users.csv +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/file_checker/file_test_users_valid.csv +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/file_checker/templates/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/file_checker/templates/generic_warehouse.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/logger.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/types.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/uploader/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/uploader/constant.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/uploader/env.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/uploader/env_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/uploader/upload.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/uploader/upload_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/uploader/utils.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/client/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/client/abstract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/client/api.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/client/api_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/client/postgres.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/client/query.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/client/uri.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/client/uri_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/collection.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/collection_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/dbt/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/dbt/assets.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/dbt/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/dbt/client_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/dbt/credentials.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/deprecate.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/env.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/files.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/files_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/formatter.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/formatter_test.csv +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/formatter_test.json +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/formatter_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/json_stream_write.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/load.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/object.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/object_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/pager/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/pager/pager.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/pager/pager_on_id.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/pager/pager_on_id_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/pager/pager_on_token.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/pager/pager_on_token_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/pager/pager_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/retry.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/retry_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/safe.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/safe_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/salesforce/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/salesforce/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/salesforce/client_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/salesforce/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/salesforce/credentials.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/salesforce/credentials_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/store.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/string.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/string_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/time.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/time_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/type.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/validation.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/validation_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/utils/write.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/domo/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/domo/assets.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/domo/client/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/domo/client/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/domo/client/client_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/domo/client/credentials.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/domo/client/endpoints.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/domo/client/pagination.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/domo/client/pagination_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/domo/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/domo/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/api/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/api/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/api/client_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/api/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/api/sdk.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/api/sdk_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/api/utils.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/assets.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/constant.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/env.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/fields.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/fields_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/multithreading.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/looker/parameters.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/assets.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/api/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/api/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/api/client_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/api/credentials.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/db/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/db/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/db/credentials.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/db/queries/.sqlfluff +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/db/queries/base_url.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/db/queries/card.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/db/queries/collection.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/db/queries/dashboard.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/db/queries/dashboard_cards.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/db/queries/database.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/db/queries/table.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/db/queries/user.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/decryption.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/decryption_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/client/shared.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/errors.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/metabase/types.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/mode/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/mode/assets.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/mode/client/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/mode/client/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/mode/client/client_test.json +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/mode/client/client_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/mode/client/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/mode/client/credentials.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/mode/errors.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/mode/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/powerbi/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/powerbi/assets.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/powerbi/client/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/powerbi/client/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/powerbi/client/credentials.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/powerbi/client/credentials_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/powerbi/client/rest.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/powerbi/client/rest_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/powerbi/client/utils.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/powerbi/client/utils_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/powerbi/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/assets.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/engine/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/engine/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/engine/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/engine/error.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/engine/error_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/engine/json_rpc.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/engine/json_rpc_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/engine/websocket.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/master.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/rest.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/client/rest_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/qlik/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/salesforce_reporting/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/salesforce_reporting/assets.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/salesforce_reporting/client/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/salesforce_reporting/client/rest.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/salesforce_reporting/client/soql.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/salesforce_reporting/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/sigma/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/sigma/assets.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/sigma/client/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/sigma/client/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/sigma/client/client_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/sigma/client/credentials.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/sigma/client/endpoints.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/sigma/client/pagination.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/sigma/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/sigma/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/assets.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/client/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/client/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/client/client_utils.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/client/credentials.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/client/project.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/client/safe_mode.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/errors.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/gql_fields.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/assets/graphql/metadata/metadata_1_get.json +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/assets/graphql/metadata/metadata_2_get.json +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/auth.xml +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/project_get.xml +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/user_get.xml +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/view_get_usage.xml +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/workbook_get.xml +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/graphql/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/graphql/paginated_object_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/rest_api/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/rest_api/auth_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/rest_api/credentials_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/rest_api/projects_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/rest_api/usages_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/rest_api/users_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/rest_api/workbooks_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/utils/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tests/unit/utils/env_key.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/tsc_fields.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/types.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau/usage.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau_revamp/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau_revamp/assets.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau_revamp/client/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau_revamp/client/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau_revamp/client/credentials.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau_revamp/client/errors.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau_revamp/client/gql_queries.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau_revamp/client/tsc_fields.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau_revamp/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/visualization/tableau_revamp/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/abstract/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/abstract/asset.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/abstract/asset_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/abstract/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/abstract/query.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/abstract/time_filter.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/abstract/time_filter_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/client_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/credentials.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/queries/.sqlfluff +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/queries/column.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/queries/cte/sharded.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/queries/database.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/queries/query.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/queries/schema.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/queries/table.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/queries/table_with_tags.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/queries/user.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/queries/view_ddl.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/query.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/bigquery/types.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/databricks/client_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/databricks/test_constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/databricks/types.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/client_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/queries/.sqlfluff +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/queries/column.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/queries/database.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/queries/query.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/queries/schema.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/queries/table.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/queries/user.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/queries/view_ddl.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/mysql/query.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/postgres/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/postgres/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/postgres/queries/.sqlfluff +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/postgres/queries/column.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/postgres/queries/database.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/postgres/queries/group.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/postgres/queries/schema.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/postgres/queries/table.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/postgres/queries/user.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/postgres/query.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/client_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/queries/.sqlfluff +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/queries/column.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/queries/database.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/queries/group.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/queries/query.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/queries/schema.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/queries/table.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/queries/table_freshness.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/queries/user.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/queries/view_ddl.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/redshift/query.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/salesforce/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/salesforce/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/salesforce/constants.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/salesforce/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/salesforce/format.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/salesforce/format_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/salesforce/soql.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/client_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/credentials.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/credentials_test.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/.sqlfluff +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/column.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/column_lineage.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/database.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/function.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/grant_to_role.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/grant_to_user.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/query.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/role.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/schema.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/table.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/user.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/queries/view_ddl.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/snowflake/query.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/sqlserver/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/sqlserver/client.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/sqlserver/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/sqlserver/queries/.sqlfluff +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/sqlserver/queries/column.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/sqlserver/queries/database.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/sqlserver/queries/schema.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/sqlserver/queries/table.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/sqlserver/queries/user.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/sqlserver/query.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/synapse/__init__.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/synapse/extract.py +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/synapse/queries/.sqlfluff +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/synapse/queries/column.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/synapse/queries/database.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/synapse/queries/query.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/synapse/queries/schema.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/synapse/queries/table.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/synapse/queries/user.sql +0 -0
- {castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/synapse/queries/view_ddl.sql +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: castor-extractor
|
|
3
|
-
Version: 0.17.
|
|
3
|
+
Version: 0.17.3
|
|
4
4
|
Summary: Extract your metadata assets.
|
|
5
5
|
Home-page: https://www.castordoc.com/
|
|
6
6
|
License: EULA
|
|
@@ -17,6 +17,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
18
|
Provides-Extra: all
|
|
19
19
|
Provides-Extra: bigquery
|
|
20
|
+
Provides-Extra: databricks
|
|
20
21
|
Provides-Extra: dbt
|
|
21
22
|
Provides-Extra: looker
|
|
22
23
|
Provides-Extra: metabase
|
|
@@ -29,6 +30,7 @@ Provides-Extra: snowflake
|
|
|
29
30
|
Provides-Extra: sqlserver
|
|
30
31
|
Provides-Extra: tableau
|
|
31
32
|
Requires-Dist: cryptography (>=41.0.5) ; extra == "snowflake"
|
|
33
|
+
Requires-Dist: databricks-sql-connector (>=3.2.0,<4.0.0) ; extra == "databricks" or extra == "all"
|
|
32
34
|
Requires-Dist: google-api-core (>=2.1.1,<3.0.0)
|
|
33
35
|
Requires-Dist: google-auth (>=2,<3)
|
|
34
36
|
Requires-Dist: google-cloud-core (>=2.1.0,<3.0.0)
|
|
@@ -39,6 +41,9 @@ Requires-Dist: looker-sdk (>=23.0.0) ; extra == "looker" or extra == "all"
|
|
|
39
41
|
Requires-Dist: msal (>=1.20.0,<2.0.0) ; extra == "powerbi" or extra == "all"
|
|
40
42
|
Requires-Dist: numpy (<1.25) ; python_version >= "3.8" and python_version < "3.9"
|
|
41
43
|
Requires-Dist: numpy (>=1.26,<2) ; python_version >= "3.12" and python_version < "3.13"
|
|
44
|
+
Requires-Dist: pandas (>=2,<2.2.0) ; python_version >= "3.9" and python_full_version <= "3.11.0"
|
|
45
|
+
Requires-Dist: pandas (>=2.0,<2.1) ; python_version >= "3.8" and python_version < "3.9"
|
|
46
|
+
Requires-Dist: pandas (>=2.1,<2.2.0) ; python_version >= "3.12" and python_version < "3.13"
|
|
42
47
|
Requires-Dist: psycopg2-binary (>=2.0.0,<3.0.0) ; extra == "metabase" or extra == "postgres" or extra == "redshift" or extra == "all"
|
|
43
48
|
Requires-Dist: pycryptodome (>=3.0.0,<4.0.0) ; extra == "metabase" or extra == "all"
|
|
44
49
|
Requires-Dist: pydantic (>=2.6,<3.0)
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/databricks/client.py
RENAMED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from collections import defaultdict
|
|
2
3
|
from concurrent.futures import ThreadPoolExecutor
|
|
3
4
|
from datetime import date
|
|
5
|
+
from enum import Enum
|
|
4
6
|
from functools import partial
|
|
5
7
|
from typing import Any, Dict, List, Optional, Set, Tuple, cast
|
|
6
8
|
|
|
7
9
|
import requests
|
|
10
|
+
from databricks import sql # type: ignore
|
|
8
11
|
from requests import Response
|
|
9
12
|
|
|
10
13
|
from ...utils import (
|
|
@@ -19,8 +22,9 @@ from ...utils.client.api import APIClient
|
|
|
19
22
|
from ...utils.pager import PagerOnToken
|
|
20
23
|
from ..abstract.time_filter import TimeFilter
|
|
21
24
|
from .credentials import DatabricksCredentials
|
|
22
|
-
from .format import DatabricksFormatter
|
|
25
|
+
from .format import DatabricksFormatter, TagMapping
|
|
23
26
|
from .types import Link, Ostr, OTimestampedLink, TablesColumns, TimestampedLink
|
|
27
|
+
from .utils import build_path, tag_label
|
|
24
28
|
|
|
25
29
|
logger = logging.getLogger(__name__)
|
|
26
30
|
|
|
@@ -33,9 +37,18 @@ _RETRY_EXCEPTIONS = [
|
|
|
33
37
|
]
|
|
34
38
|
_WORKSPACE_ID_HEADER = "X-Databricks-Org-Id"
|
|
35
39
|
|
|
40
|
+
_INFORMATION_SCHEMA_SQL = "SELECT * FROM system.information_schema"
|
|
41
|
+
|
|
36
42
|
safe_params = SafeMode((BaseException,), _MAX_NUMBER_OF_LINEAGE_ERRORS)
|
|
37
43
|
|
|
38
44
|
|
|
45
|
+
class TagEntity(Enum):
|
|
46
|
+
"""Entities that can be tagged in Databricks"""
|
|
47
|
+
|
|
48
|
+
COLUMN = "COLUMN"
|
|
49
|
+
TABLE = "TABLE"
|
|
50
|
+
|
|
51
|
+
|
|
39
52
|
def _day_to_epoch_ms(day: date) -> int:
|
|
40
53
|
return int(at_midnight(day).timestamp() * 1000)
|
|
41
54
|
|
|
@@ -76,12 +89,38 @@ class DatabricksClient(APIClient):
|
|
|
76
89
|
credentials: DatabricksCredentials,
|
|
77
90
|
db_allowed: Optional[Set[str]] = None,
|
|
78
91
|
db_blocked: Optional[Set[str]] = None,
|
|
92
|
+
has_table_tags: bool = False,
|
|
93
|
+
has_column_tags: bool = False,
|
|
79
94
|
):
|
|
80
95
|
super().__init__(host=credentials.host, token=credentials.token)
|
|
96
|
+
self._http_path = credentials.http_path
|
|
81
97
|
self._db_allowed = db_allowed
|
|
82
98
|
self._db_blocked = db_blocked
|
|
99
|
+
self._has_table_tags = has_table_tags
|
|
100
|
+
self._has_column_tags = has_column_tags
|
|
83
101
|
self.formatter = DatabricksFormatter()
|
|
84
102
|
|
|
103
|
+
def execute_sql(
|
|
104
|
+
self,
|
|
105
|
+
query: str,
|
|
106
|
+
params: Optional[dict] = None,
|
|
107
|
+
):
|
|
108
|
+
"""
|
|
109
|
+
Execute a SQL query on Databricks system tables and return the results.
|
|
110
|
+
https://docs.databricks.com/en/dev-tools/python-sql-connector.html
|
|
111
|
+
|
|
112
|
+
/!\ credentials.http_path is required in order to run SQL queries
|
|
113
|
+
"""
|
|
114
|
+
assert self._http_path, "HTTP_PATH is required to run SQL queries"
|
|
115
|
+
with sql.connect(
|
|
116
|
+
server_hostname=self._host,
|
|
117
|
+
http_path=self._http_path,
|
|
118
|
+
access_token=self._token,
|
|
119
|
+
) as connection:
|
|
120
|
+
with connection.cursor() as cursor:
|
|
121
|
+
cursor.execute(query, params)
|
|
122
|
+
return cursor.fetchall()
|
|
123
|
+
|
|
85
124
|
@staticmethod
|
|
86
125
|
def name() -> str:
|
|
87
126
|
return "Databricks"
|
|
@@ -130,7 +169,12 @@ class DatabricksClient(APIClient):
|
|
|
130
169
|
"""
|
|
131
170
|
return response.json(), response.headers[_WORKSPACE_ID_HEADER]
|
|
132
171
|
|
|
133
|
-
def _tables_columns_of_schema(
|
|
172
|
+
def _tables_columns_of_schema(
|
|
173
|
+
self,
|
|
174
|
+
schema: dict,
|
|
175
|
+
table_tags: TagMapping,
|
|
176
|
+
column_tags: TagMapping,
|
|
177
|
+
) -> TablesColumns:
|
|
134
178
|
path = "api/2.1/unity-catalog/tables"
|
|
135
179
|
payload = {
|
|
136
180
|
"catalog_name": schema["database_id"],
|
|
@@ -143,7 +187,12 @@ class DatabricksClient(APIClient):
|
|
|
143
187
|
)
|
|
144
188
|
host = self.build_url(self._host, path="")
|
|
145
189
|
return self.formatter.format_table_column(
|
|
146
|
-
content.get("tables", []),
|
|
190
|
+
raw_tables=content.get("tables", []),
|
|
191
|
+
schema=schema,
|
|
192
|
+
host=host,
|
|
193
|
+
workspace_id=workspace_id,
|
|
194
|
+
table_tags=table_tags,
|
|
195
|
+
column_tags=column_tags,
|
|
147
196
|
)
|
|
148
197
|
|
|
149
198
|
@staticmethod
|
|
@@ -156,6 +205,40 @@ class DatabricksClient(APIClient):
|
|
|
156
205
|
return table
|
|
157
206
|
return {**table, "owner_external_id": owner_external_id}
|
|
158
207
|
|
|
208
|
+
def _needs_extraction(self, entity: TagEntity) -> bool:
|
|
209
|
+
if entity == TagEntity.TABLE:
|
|
210
|
+
return self._has_table_tags
|
|
211
|
+
if entity == TagEntity.COLUMN:
|
|
212
|
+
return self._has_column_tags
|
|
213
|
+
raise AssertionError(f"Entity not supported: {entity}")
|
|
214
|
+
|
|
215
|
+
def _get_tags_mapping(self, entity: TagEntity) -> TagMapping:
|
|
216
|
+
"""
|
|
217
|
+
Fetch tags of the given entity and build a mapping:
|
|
218
|
+
{ path: list[tags] }
|
|
219
|
+
|
|
220
|
+
https://docs.databricks.com/en/sql/language-manual/information-schema/table_tags.html
|
|
221
|
+
https://docs.databricks.com/en/sql/language-manual/information-schema/column_tags.html
|
|
222
|
+
"""
|
|
223
|
+
if not self._needs_extraction(entity):
|
|
224
|
+
# extracting tags require additional credentials (http_path)
|
|
225
|
+
return dict()
|
|
226
|
+
|
|
227
|
+
table = f"{entity.value.lower()}_tags"
|
|
228
|
+
query = f"{_INFORMATION_SCHEMA_SQL}.{table}"
|
|
229
|
+
result = self.execute_sql(query)
|
|
230
|
+
mapping = defaultdict(list)
|
|
231
|
+
for row in result:
|
|
232
|
+
dict_row = row.asDict()
|
|
233
|
+
keys = ["catalog_name", "schema_name", "table_name"]
|
|
234
|
+
if entity == TagEntity.COLUMN:
|
|
235
|
+
keys.append("column_name")
|
|
236
|
+
path = build_path(dict_row, keys)
|
|
237
|
+
label = tag_label(dict_row)
|
|
238
|
+
mapping[path].append(label)
|
|
239
|
+
|
|
240
|
+
return mapping
|
|
241
|
+
|
|
159
242
|
@staticmethod
|
|
160
243
|
def _get_user_mapping(users: List[dict]) -> dict:
|
|
161
244
|
return {
|
|
@@ -172,8 +255,15 @@ class DatabricksClient(APIClient):
|
|
|
172
255
|
tables: List[dict] = []
|
|
173
256
|
columns: List[dict] = []
|
|
174
257
|
user_mapping = self._get_user_mapping(users)
|
|
258
|
+
table_tags = self._get_tags_mapping(TagEntity.TABLE)
|
|
259
|
+
column_tags = self._get_tags_mapping(TagEntity.COLUMN)
|
|
175
260
|
for schema in schemas:
|
|
176
|
-
|
|
261
|
+
|
|
262
|
+
t_to_add, c_to_add = self._tables_columns_of_schema(
|
|
263
|
+
schema=schema,
|
|
264
|
+
table_tags=table_tags,
|
|
265
|
+
column_tags=column_tags,
|
|
266
|
+
)
|
|
177
267
|
t_with_owner = [
|
|
178
268
|
self._match_table_with_user(table, user_mapping)
|
|
179
269
|
for table in t_to_add
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from dataclasses import field
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from pydantic.dataclasses import dataclass
|
|
5
|
+
from pydantic_settings import SettingsConfigDict
|
|
6
|
+
|
|
7
|
+
DATABRICKS_ENV_PREFIX = "CASTOR_DATABRICKS_"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class DatabricksCredentials:
|
|
12
|
+
"""
|
|
13
|
+
Credentials needed by Databricks client
|
|
14
|
+
Requires:
|
|
15
|
+
- host
|
|
16
|
+
- token
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
host: str
|
|
20
|
+
token: str = field(metadata={"sensitive": True})
|
|
21
|
+
http_path: Optional[str] = field(default=None)
|
|
22
|
+
|
|
23
|
+
model_config = SettingsConfigDict(
|
|
24
|
+
env_prefix=DATABRICKS_ENV_PREFIX,
|
|
25
|
+
extra="ignore",
|
|
26
|
+
populate_by_name=True,
|
|
27
|
+
)
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/databricks/extract.py
RENAMED
|
@@ -15,7 +15,7 @@ from ..abstract import (
|
|
|
15
15
|
common_args,
|
|
16
16
|
)
|
|
17
17
|
from .client import DatabricksClient
|
|
18
|
-
from .credentials import
|
|
18
|
+
from .credentials import DatabricksCredentials
|
|
19
19
|
|
|
20
20
|
DATABRICKS_ASSETS: SupportedAssets = {
|
|
21
21
|
WarehouseAssetGroup.ADDITIONAL_LINEAGE: ADDITIONAL_LINEAGE_ASSETS,
|
|
@@ -170,7 +170,7 @@ def extract_all(**kwargs) -> None:
|
|
|
170
170
|
output_directory, skip_existing = common_args(kwargs)
|
|
171
171
|
|
|
172
172
|
client = DatabricksClient(
|
|
173
|
-
credentials=
|
|
173
|
+
credentials=DatabricksCredentials(**kwargs),
|
|
174
174
|
db_allowed=kwargs.get("db_allowed"),
|
|
175
175
|
db_blocked=kwargs.get("db_blocked"),
|
|
176
176
|
)
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/warehouse/databricks/format.py
RENAMED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from datetime import datetime
|
|
3
|
-
from typing import List, Optional
|
|
3
|
+
from typing import Dict, List, Optional
|
|
4
4
|
|
|
5
5
|
from .types import TablesColumns
|
|
6
|
+
from .utils import build_path
|
|
6
7
|
|
|
7
8
|
logger = logging.getLogger(__name__)
|
|
8
9
|
|
|
@@ -11,6 +12,8 @@ EXCLUDED_SCHEMAS = {"information_schema", "default"}
|
|
|
11
12
|
|
|
12
13
|
TABLE_URL_TPL = "{host}explore/data/{catalog_name}/{schema_name}/{table_name}?o={workspace_id}"
|
|
13
14
|
|
|
15
|
+
TagMapping = Dict[str, List[str]]
|
|
16
|
+
|
|
14
17
|
|
|
15
18
|
def _to_datetime_or_none(time_ms: Optional[int]) -> Optional[datetime]:
|
|
16
19
|
"""return time in ms as datetime or None"""
|
|
@@ -24,6 +27,7 @@ def _table_payload(
|
|
|
24
27
|
table: dict,
|
|
25
28
|
host: str,
|
|
26
29
|
workspace_id: str,
|
|
30
|
+
tags: TagMapping,
|
|
27
31
|
) -> dict:
|
|
28
32
|
"""
|
|
29
33
|
Prepares the table payload. This also includes a source link which is built
|
|
@@ -36,26 +40,43 @@ def _table_payload(
|
|
|
36
40
|
table_name=table["name"],
|
|
37
41
|
workspace_id=workspace_id,
|
|
38
42
|
)
|
|
43
|
+
|
|
44
|
+
keys = ["catalog_name", "schema_name", "name"]
|
|
45
|
+
path = build_path(table, keys)
|
|
46
|
+
|
|
39
47
|
return {
|
|
40
48
|
"description": table.get("comment"),
|
|
41
49
|
"id": table["table_id"],
|
|
42
50
|
"owner_email": table.get("owner"),
|
|
43
51
|
"schema_id": f"{schema['id']}",
|
|
44
52
|
"table_name": table["name"],
|
|
45
|
-
"tags": [],
|
|
53
|
+
"tags": tags.get(path, []),
|
|
46
54
|
"type": table.get("table_type"),
|
|
47
55
|
"url": url,
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
|
|
51
|
-
def
|
|
59
|
+
def _column_path(table: dict, column: dict) -> str:
|
|
60
|
+
keys = ["catalog_name", "schema_name", "name"]
|
|
61
|
+
table_path = build_path(table, keys)
|
|
62
|
+
column_name = column["name"]
|
|
63
|
+
return f"{table_path}.{column_name}"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _column_payload(
|
|
67
|
+
table: dict,
|
|
68
|
+
column: dict,
|
|
69
|
+
tags: TagMapping,
|
|
70
|
+
) -> dict:
|
|
71
|
+
path = _column_path(table, column)
|
|
52
72
|
return {
|
|
53
73
|
"column_name": column["name"],
|
|
54
74
|
"data_type": column["type_name"],
|
|
55
75
|
"description": column.get("comment"),
|
|
56
|
-
"id": f"`{table['
|
|
76
|
+
"id": f"`{table['table_id']}`.`{column['name']}`",
|
|
57
77
|
"ordinal_position": column["position"],
|
|
58
|
-
"table_id": table["
|
|
78
|
+
"table_id": table["table_id"],
|
|
79
|
+
"tags": tags.get(path, []),
|
|
59
80
|
}
|
|
60
81
|
|
|
61
82
|
|
|
@@ -97,19 +118,24 @@ class DatabricksFormatter:
|
|
|
97
118
|
|
|
98
119
|
@staticmethod
|
|
99
120
|
def format_table_column(
|
|
100
|
-
raw_tables: List[dict],
|
|
121
|
+
raw_tables: List[dict],
|
|
122
|
+
schema: dict,
|
|
123
|
+
host: str,
|
|
124
|
+
workspace_id: str,
|
|
125
|
+
table_tags: TagMapping,
|
|
126
|
+
column_tags: TagMapping,
|
|
101
127
|
) -> TablesColumns:
|
|
102
128
|
tables = []
|
|
103
129
|
columns = []
|
|
104
130
|
if not raw_tables:
|
|
105
131
|
return [], []
|
|
106
132
|
for table in raw_tables:
|
|
107
|
-
t = _table_payload(schema, table, host, workspace_id)
|
|
133
|
+
t = _table_payload(schema, table, host, workspace_id, table_tags)
|
|
108
134
|
tables.append(t)
|
|
109
135
|
if not table.get("columns"):
|
|
110
136
|
continue
|
|
111
137
|
for column in table["columns"]:
|
|
112
|
-
c = _column_payload(
|
|
138
|
+
c = _column_payload(table, column, column_tags)
|
|
113
139
|
columns.append(c)
|
|
114
140
|
|
|
115
141
|
return tables, columns
|
|
@@ -2,6 +2,7 @@ from datetime import datetime
|
|
|
2
2
|
|
|
3
3
|
from .format import (
|
|
4
4
|
DatabricksFormatter,
|
|
5
|
+
_column_path,
|
|
5
6
|
_column_payload,
|
|
6
7
|
_table_payload,
|
|
7
8
|
_to_datetime_or_none,
|
|
@@ -42,7 +43,12 @@ def test__table_payload():
|
|
|
42
43
|
host = "https://some.cloud.databricks.net/"
|
|
43
44
|
workspace_id = "123456"
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
tags = {
|
|
47
|
+
"foo.bar.baz": ["riri", "fifi"],
|
|
48
|
+
"dummy.path": ["loulou"],
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
payload = _table_payload(schema, table, host, workspace_id, tags)
|
|
46
52
|
|
|
47
53
|
expected = {
|
|
48
54
|
"description": None,
|
|
@@ -50,7 +56,7 @@ def test__table_payload():
|
|
|
50
56
|
"owner_email": "pot@ato.com",
|
|
51
57
|
"schema_id": "id123",
|
|
52
58
|
"table_name": "baz",
|
|
53
|
-
"tags": [],
|
|
59
|
+
"tags": ["riri", "fifi"],
|
|
54
60
|
"type": "MANAGED",
|
|
55
61
|
"url": "https://some.cloud.databricks.net/explore/data/foo/bar/baz?o=123456",
|
|
56
62
|
}
|
|
@@ -59,40 +65,59 @@ def test__table_payload():
|
|
|
59
65
|
|
|
60
66
|
def test__column_payload():
|
|
61
67
|
table = {
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
+
"catalog_name": "foo",
|
|
69
|
+
"name": "baz",
|
|
70
|
+
"owner": "pot@ato.com",
|
|
71
|
+
"schema_name": "bar",
|
|
72
|
+
"table_id": "732pot5e-8ato-4c27-b701-9fa51febc192",
|
|
73
|
+
"table_type": "MANAGED",
|
|
68
74
|
}
|
|
69
75
|
column = {
|
|
76
|
+
"comment": "some description",
|
|
70
77
|
"name": "Uid",
|
|
71
|
-
"
|
|
72
|
-
"type_name": "STRING",
|
|
78
|
+
"nullable": True,
|
|
73
79
|
"position": 0,
|
|
80
|
+
"type_json": '{"name":"Uid","type":"string","nullable":true,"metadata":{}}',
|
|
81
|
+
"type_name": "STRING",
|
|
74
82
|
"type_precision": 0,
|
|
75
83
|
"type_scale": 0,
|
|
76
|
-
"
|
|
77
|
-
"nullable": True,
|
|
78
|
-
"comment": "some description",
|
|
84
|
+
"type_text": "string",
|
|
79
85
|
}
|
|
80
|
-
|
|
86
|
+
tags = {
|
|
87
|
+
"foo.bar.baz.Uid": ["riri", "fifi"],
|
|
88
|
+
"dummy.path": ["loulou"],
|
|
89
|
+
}
|
|
90
|
+
payload = _column_payload(table, column, tags)
|
|
81
91
|
|
|
82
92
|
expected = {
|
|
83
|
-
"id": "`18175cd5-9b9b-4d78-9d28-caaa12c21ce0`.`Uid`",
|
|
84
93
|
"column_name": "Uid",
|
|
85
|
-
"table_id": "18175cd5-9b9b-4d78-9d28-caaa12c21ce0",
|
|
86
|
-
"description": "some description",
|
|
87
94
|
"data_type": "STRING",
|
|
95
|
+
"description": "some description",
|
|
96
|
+
"id": "`732pot5e-8ato-4c27-b701-9fa51febc192`.`Uid`",
|
|
88
97
|
"ordinal_position": 0,
|
|
98
|
+
"table_id": "732pot5e-8ato-4c27-b701-9fa51febc192",
|
|
99
|
+
"tags": ["riri", "fifi"],
|
|
89
100
|
}
|
|
90
101
|
assert payload == expected
|
|
91
102
|
|
|
92
103
|
# case where there are spaces in the name
|
|
93
104
|
column["name"] = "column name with spaces"
|
|
94
|
-
payload = _column_payload(table, column)
|
|
105
|
+
payload = _column_payload(table, column, tags)
|
|
95
106
|
expected_id = (
|
|
96
|
-
"`
|
|
107
|
+
"`732pot5e-8ato-4c27-b701-9fa51febc192`.`column name with spaces`"
|
|
97
108
|
)
|
|
98
109
|
assert payload["id"] == expected_id
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def test__column_path():
|
|
113
|
+
table = {
|
|
114
|
+
"catalog_name": "Jo",
|
|
115
|
+
"schema_name": "William",
|
|
116
|
+
"name": "Jack",
|
|
117
|
+
}
|
|
118
|
+
column = {
|
|
119
|
+
"name": "Averell",
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
expected = "Jo.William.Jack.Averell"
|
|
123
|
+
assert _column_path(table=table, column=column) == expected
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from typing import Dict, List
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def build_path(
|
|
5
|
+
row: Dict,
|
|
6
|
+
keys: List[str],
|
|
7
|
+
) -> str:
|
|
8
|
+
"""
|
|
9
|
+
format an asset's path:
|
|
10
|
+
- picks the given keys from dict
|
|
11
|
+
- join keys with a dot "."
|
|
12
|
+
"""
|
|
13
|
+
key_values = [row[key] for key in keys]
|
|
14
|
+
return ".".join(key_values)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def tag_label(row: Dict) -> str:
|
|
18
|
+
"""
|
|
19
|
+
format the tag's label:
|
|
20
|
+
- {key:value} when the value is not empty
|
|
21
|
+
- {key} otherwise
|
|
22
|
+
"""
|
|
23
|
+
tag_name = row["tag_name"]
|
|
24
|
+
tag_value = row["tag_value"]
|
|
25
|
+
if not tag_value:
|
|
26
|
+
return tag_name
|
|
27
|
+
return f"{tag_name}:{tag_value}"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from .utils import build_path, tag_label
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_build_path():
|
|
5
|
+
row = {
|
|
6
|
+
"bigflo": "oli",
|
|
7
|
+
"laurel": "hardy",
|
|
8
|
+
"dupond": "dupont",
|
|
9
|
+
}
|
|
10
|
+
keys = ["laurel", "dupond"]
|
|
11
|
+
assert build_path(row, keys) == "hardy.dupont"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_tag_label():
|
|
15
|
+
row = {
|
|
16
|
+
"tag_name": "marketplace",
|
|
17
|
+
"tag_value": "",
|
|
18
|
+
}
|
|
19
|
+
assert tag_label(row) == "marketplace"
|
|
20
|
+
|
|
21
|
+
row = {
|
|
22
|
+
"tag_name": "fi",
|
|
23
|
+
"tag_value": "fou",
|
|
24
|
+
}
|
|
25
|
+
assert tag_label(row) == "fi:fou"
|
|
@@ -3,7 +3,7 @@ requires = ["setuptools>=61.2"]
|
|
|
3
3
|
|
|
4
4
|
[tool.poetry]
|
|
5
5
|
name = "castor-extractor"
|
|
6
|
-
version = "0.17.
|
|
6
|
+
version = "0.17.3"
|
|
7
7
|
description = "Extract your metadata assets."
|
|
8
8
|
authors = ["Castor <support@castordoc.com>"]
|
|
9
9
|
license = "EULA"
|
|
@@ -40,6 +40,11 @@ numpy = [ # Subdependency of pyarrow. As numpy remove 3.8 in 1.25 and add 3.12 i
|
|
|
40
40
|
{ version = "<1.25", python = "~3.8" },
|
|
41
41
|
{ version = ">=1.26,<2", python = "~3.12" },
|
|
42
42
|
]
|
|
43
|
+
pandas = [ # Subdependency of databricks-sql-connector. As pandas remove 3.8 in 2.1 and add 3.12 wheel in 2.1 . And build pandas from source is complex.
|
|
44
|
+
{ version = "~2.0", python = "~3.8" },
|
|
45
|
+
{ version = ">=2,<2.2.0", python = ">=3.9,<=3.11" }, # Same as databricks-sql-connector requirement
|
|
46
|
+
{ version = ">=2.1,<2.2.0", python = "~3.12" },
|
|
47
|
+
]
|
|
43
48
|
psycopg2-binary = { version = ">=2.0.0, < 3.0.0", optional = true }
|
|
44
49
|
pycryptodome = { version = ">=3.0.0, <4.0.0", optional = true }
|
|
45
50
|
python-dateutil = ">=2.0.0, <=3.0.0"
|
|
@@ -60,10 +65,12 @@ pydantic = "^2.6"
|
|
|
60
65
|
pydantic-settings = "^2.2"
|
|
61
66
|
pymssql = { version = "^2.2.11", optional = true }
|
|
62
67
|
pymysql = { extras = ["rsa"], version = "^1.1.0", optional = true }
|
|
68
|
+
databricks-sql-connector = {version = "^3.2.0", optional = true}
|
|
63
69
|
|
|
64
70
|
|
|
65
71
|
[tool.poetry.extras]
|
|
66
72
|
bigquery = ["sqlalchemy-bigquery"]
|
|
73
|
+
databricks = ["databricks-sql-connector"]
|
|
67
74
|
dbt = []
|
|
68
75
|
looker = ["looker-sdk"]
|
|
69
76
|
metabase = ["psycopg2-binary", "pycryptodome"]
|
|
@@ -80,6 +87,7 @@ snowflake = [
|
|
|
80
87
|
sqlserver = ["pymssql"]
|
|
81
88
|
tableau = ["tableauserverclient"]
|
|
82
89
|
all = [
|
|
90
|
+
"databricks-sql-connector",
|
|
83
91
|
"looker-sdk",
|
|
84
92
|
"msal",
|
|
85
93
|
"psycopg2-binary",
|
|
@@ -237,5 +245,6 @@ DEP002 = [
|
|
|
237
245
|
"snowflake-sqlalchemy",
|
|
238
246
|
"sqlalchemy-bigquery",
|
|
239
247
|
"sqlalchemy-redshift",
|
|
240
|
-
"numpy" # See comment on numpy in dependencies
|
|
248
|
+
"numpy", # See comment on numpy in dependencies
|
|
249
|
+
"pandas" # See comment on pandas in dependencies
|
|
241
250
|
]
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
from dataclasses import field
|
|
2
|
-
|
|
3
|
-
from pydantic.dataclasses import dataclass
|
|
4
|
-
|
|
5
|
-
from ...utils import from_env
|
|
6
|
-
|
|
7
|
-
_HOST = "CASTOR_DATABRICKS_HOST"
|
|
8
|
-
_TOKEN = "CASTOR_DATABRICKS_TOKEN" # noqa: S105
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@dataclass
|
|
12
|
-
class DatabricksCredentials:
|
|
13
|
-
"""
|
|
14
|
-
Credentials needed by Databricks client
|
|
15
|
-
Requires:
|
|
16
|
-
- host
|
|
17
|
-
- token
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
host: str
|
|
21
|
-
token: str = field(metadata={"sensitive": True})
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def to_credentials(params: dict) -> DatabricksCredentials:
|
|
25
|
-
"""extract Databricks credentials"""
|
|
26
|
-
host = params.get("host") or from_env(_HOST)
|
|
27
|
-
token = params.get("token") or from_env(_TOKEN)
|
|
28
|
-
return DatabricksCredentials(host=host, token=token)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_bigquery.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_databricks.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_domo.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_looker.py
RENAMED
|
File without changes
|
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_metabase_db.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_mode.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_mysql.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_postgres.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_powerbi.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_qlik.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_redshift.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_salesforce.py
RENAMED
|
File without changes
|
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_sigma.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_snowflake.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_sqlserver.py
RENAMED
|
File without changes
|
{castor_extractor-0.17.2 → castor_extractor-0.17.3}/castor_extractor/commands/extract_tableau.py
RENAMED
|
File without changes
|
|
File without changes
|