castor-extractor 0.16.5__tar.gz → 0.16.9__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.16.5 → castor_extractor-0.16.9}/CHANGELOG.md +17 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/PKG-INFO +6 -3
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/__init__.py +2 -1
- castor_extractor-0.16.9/castor_extractor/utils/collection.py +46 -0
- castor_extractor-0.16.9/castor_extractor/utils/collection_test.py +60 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/time.py +9 -1
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/time_test.py +8 -1
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/domo/client/client.py +28 -43
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/domo/client/client_test.py +1 -23
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/domo/client/endpoints.py +13 -6
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/domo/client/pagination.py +4 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/api/client.py +21 -17
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/api/sdk.py +10 -58
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/api/utils.py +1 -1
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/extract.py +2 -1
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/multithreading.py +1 -1
- castor_extractor-0.16.9/castor_extractor/visualization/tableau_revamp/__init__.py +3 -0
- castor_extractor-0.16.9/castor_extractor/visualization/tableau_revamp/assets.py +18 -0
- castor_extractor-0.16.9/castor_extractor/visualization/tableau_revamp/client/__init__.py +2 -0
- castor_extractor-0.16.9/castor_extractor/visualization/tableau_revamp/client/client.py +297 -0
- castor_extractor-0.16.9/castor_extractor/visualization/tableau_revamp/client/credentials.py +104 -0
- castor_extractor-0.16.9/castor_extractor/visualization/tableau_revamp/client/errors.py +3 -0
- castor_extractor-0.16.9/castor_extractor/visualization/tableau_revamp/client/gql_queries.py +134 -0
- castor_extractor-0.16.9/castor_extractor/visualization/tableau_revamp/client/tsc_fields.py +34 -0
- castor_extractor-0.16.9/castor_extractor/visualization/tableau_revamp/constants.py +5 -0
- castor_extractor-0.16.9/castor_extractor/visualization/tableau_revamp/extract.py +53 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/databricks/client.py +12 -5
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/databricks/client_test.py +22 -3
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/databricks/format.py +5 -1
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/pyproject.toml +8 -3
- castor_extractor-0.16.5/castor_extractor/utils/collection.py +0 -14
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/Dockerfile +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/LICENCE +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/README.md +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_bigquery.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_databricks.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_domo.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_looker.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_metabase_api.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_metabase_db.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_mode.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_mysql.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_postgres.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_powerbi.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_qlik.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_redshift.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_salesforce.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_salesforce_reporting.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_sigma.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_snowflake.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_sqlserver.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/extract_tableau.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/file_check.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/commands/upload.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/file_checker/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/file_checker/column.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/file_checker/column_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/file_checker/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/file_checker/enums.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/file_checker/file.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/file_checker/file_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/file_checker/file_test_users.csv +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/file_checker/file_test_users_valid.csv +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/file_checker/templates/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/file_checker/templates/generic_warehouse.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/logger.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/types.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/uploader/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/uploader/constant.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/uploader/env.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/uploader/env_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/uploader/upload.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/uploader/upload_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/uploader/utils.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/client/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/client/abstract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/client/api.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/client/api_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/client/postgres.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/client/query.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/client/uri.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/client/uri_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/dbt/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/dbt/assets.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/dbt/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/dbt/client_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/dbt/credentials.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/deprecate.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/env.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/files.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/files_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/formatter.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/formatter_test.csv +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/formatter_test.json +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/formatter_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/json_stream_write.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/load.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/object.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/object_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/pager/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/pager/pager.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/pager/pager_on_id.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/pager/pager_on_id_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/pager/pager_on_token.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/pager/pager_on_token_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/pager/pager_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/retry.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/retry_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/safe.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/safe_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/salesforce/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/salesforce/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/salesforce/client_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/salesforce/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/salesforce/credentials.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/salesforce/credentials_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/store.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/string.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/string_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/type.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/validation.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/validation_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/utils/write.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/domo/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/domo/assets.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/domo/client/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/domo/client/credentials.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/domo/client/pagination_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/domo/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/domo/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/api/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/api/client_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/api/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/api/sdk_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/assets.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/constant.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/env.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/fields.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/fields_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/parameters.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/assets.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/api/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/api/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/api/client_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/api/credentials.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/db/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/db/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/db/credentials.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/db/queries/.sqlfluff +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/db/queries/base_url.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/db/queries/card.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/db/queries/collection.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/db/queries/dashboard.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/db/queries/dashboard_cards.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/db/queries/database.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/db/queries/table.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/db/queries/user.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/decryption.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/decryption_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/client/shared.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/errors.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/metabase/types.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/mode/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/mode/assets.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/mode/client/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/mode/client/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/mode/client/client_test.json +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/mode/client/client_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/mode/client/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/mode/client/credentials.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/mode/errors.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/mode/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/powerbi/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/powerbi/assets.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/powerbi/client/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/powerbi/client/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/powerbi/client/credentials.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/powerbi/client/credentials_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/powerbi/client/rest.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/powerbi/client/rest_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/powerbi/client/utils.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/powerbi/client/utils_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/powerbi/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/assets.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/engine/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/engine/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/engine/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/engine/error.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/engine/error_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/engine/json_rpc.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/engine/json_rpc_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/engine/websocket.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/master.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/rest.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/client/rest_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/qlik/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/salesforce_reporting/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/salesforce_reporting/assets.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/salesforce_reporting/client/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/salesforce_reporting/client/rest.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/salesforce_reporting/client/soql.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/salesforce_reporting/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/sigma/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/sigma/assets.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/sigma/client/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/sigma/client/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/sigma/client/client_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/sigma/client/credentials.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/sigma/client/endpoints.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/sigma/client/pagination.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/sigma/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/sigma/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/assets.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/client/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/client/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/client/client_utils.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/client/credentials.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/client/project.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/client/safe_mode.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/errors.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/gql_fields.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/assets/graphql/metadata/metadata_1_get.json +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/assets/graphql/metadata/metadata_2_get.json +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/auth.xml +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/project_get.xml +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/user_get.xml +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/view_get_usage.xml +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/assets/rest_api/workbook_get.xml +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/graphql/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/graphql/paginated_object_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/rest_api/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/rest_api/auth_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/rest_api/credentials_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/rest_api/projects_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/rest_api/usages_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/rest_api/users_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/rest_api/workbooks_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/utils/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tests/unit/utils/env_key.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/tsc_fields.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/types.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/tableau/usage.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/abstract/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/abstract/asset.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/abstract/asset_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/abstract/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/abstract/query.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/abstract/time_filter.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/abstract/time_filter_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/client_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/credentials.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/queries/.sqlfluff +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/queries/column.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/queries/cte/sharded.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/queries/database.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/queries/query.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/queries/schema.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/queries/table.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/queries/table_with_tags.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/queries/user.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/queries/view_ddl.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/query.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/bigquery/types.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/databricks/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/databricks/credentials.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/databricks/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/databricks/format_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/databricks/types.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/client_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/queries/.sqlfluff +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/queries/column.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/queries/database.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/queries/query.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/queries/schema.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/queries/table.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/queries/user.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/queries/view_ddl.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/mysql/query.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/postgres/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/postgres/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/postgres/queries/.sqlfluff +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/postgres/queries/column.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/postgres/queries/database.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/postgres/queries/group.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/postgres/queries/schema.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/postgres/queries/table.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/postgres/queries/user.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/postgres/query.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/client_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/queries/.sqlfluff +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/queries/column.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/queries/database.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/queries/group.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/queries/query.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/queries/schema.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/queries/table.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/queries/table_freshness.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/queries/user.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/queries/view_ddl.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/redshift/query.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/salesforce/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/salesforce/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/salesforce/constants.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/salesforce/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/salesforce/format.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/salesforce/format_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/salesforce/soql.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/client_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/credentials.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/credentials_test.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/queries/.sqlfluff +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/queries/column.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/queries/column_lineage.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/queries/database.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/queries/grant_to_role.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/queries/grant_to_user.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/queries/query.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/queries/role.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/queries/schema.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/queries/table.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/queries/user.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/queries/view_ddl.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/snowflake/query.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/sqlserver/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/sqlserver/client.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/sqlserver/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/sqlserver/queries/.sqlfluff +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/sqlserver/queries/column.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/sqlserver/queries/database.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/sqlserver/queries/schema.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/sqlserver/queries/table.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/sqlserver/queries/user.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/sqlserver/query.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/synapse/__init__.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/synapse/extract.py +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/synapse/queries/.sqlfluff +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/synapse/queries/column.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/synapse/queries/database.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/synapse/queries/query.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/synapse/queries/schema.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/synapse/queries/table.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/synapse/queries/user.sql +0 -0
- {castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/warehouse/synapse/queries/view_ddl.sql +0 -0
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.9 - 2024-05-28
|
|
4
|
+
|
|
5
|
+
* Tableau: extract only fields that are necessary
|
|
6
|
+
|
|
7
|
+
## 0.16.8 - 2024-05-21
|
|
8
|
+
|
|
9
|
+
* Add compatibility with python 3.12
|
|
10
|
+
* Looker: Bump looker-sdk and refactor client
|
|
11
|
+
|
|
12
|
+
## 0.16.7 - 2024-05-16
|
|
13
|
+
|
|
14
|
+
* Databricks: allow no emails on user
|
|
15
|
+
|
|
16
|
+
## 0.16.6 - 2024-05-14
|
|
17
|
+
|
|
18
|
+
* Introducing the revamped connector for Tableau
|
|
19
|
+
|
|
3
20
|
## 0.16.5 - 2024-04-25
|
|
4
21
|
|
|
5
22
|
* Salesforce: remove DeploymentStatus from EntityDefinition query
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: castor-extractor
|
|
3
|
-
Version: 0.16.
|
|
3
|
+
Version: 0.16.9
|
|
4
4
|
Summary: Extract your metadata assets.
|
|
5
5
|
Home-page: https://www.castordoc.com/
|
|
6
6
|
License: EULA
|
|
7
7
|
Author: Castor
|
|
8
8
|
Author-email: support@castordoc.com
|
|
9
|
-
Requires-Python: >=3.8,<3.
|
|
9
|
+
Requires-Python: >=3.8,<3.13
|
|
10
10
|
Classifier: License :: Other/Proprietary License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.9
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.10
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
18
|
Provides-Extra: all
|
|
18
19
|
Provides-Extra: bigquery
|
|
19
20
|
Provides-Extra: dbt
|
|
@@ -34,8 +35,10 @@ Requires-Dist: google-cloud-core (>=2.1.0,<3.0.0)
|
|
|
34
35
|
Requires-Dist: google-cloud-storage (>=2,<3)
|
|
35
36
|
Requires-Dist: google-resumable-media (>=2.0.3,<3.0.0)
|
|
36
37
|
Requires-Dist: googleapis-common-protos (>=1.53.0,<2.0.0)
|
|
37
|
-
Requires-Dist: looker-sdk (>=
|
|
38
|
+
Requires-Dist: looker-sdk (>=23.0.0) ; extra == "looker" or extra == "all"
|
|
38
39
|
Requires-Dist: msal (>=1.20.0,<2.0.0) ; extra == "powerbi" or extra == "all"
|
|
40
|
+
Requires-Dist: numpy (<1.25) ; python_version >= "3.8" and python_version < "3.9"
|
|
41
|
+
Requires-Dist: numpy (>=1.26,<2) ; python_version >= "3.12" and python_version < "3.13"
|
|
39
42
|
Requires-Dist: psycopg2-binary (>=2.0.0,<3.0.0) ; extra == "metabase" or extra == "postgres" or extra == "redshift" or extra == "all"
|
|
40
43
|
Requires-Dist: pycryptodome (>=3.0.0,<4.0.0) ; extra == "metabase" or extra == "all"
|
|
41
44
|
Requires-Dist: pydantic (>=2.6,<3.0)
|
|
@@ -5,7 +5,7 @@ from .client import (
|
|
|
5
5
|
SqlalchemyClient,
|
|
6
6
|
uri_encode,
|
|
7
7
|
)
|
|
8
|
-
from .collection import group_by
|
|
8
|
+
from .collection import group_by, mapping_from_rows
|
|
9
9
|
from .constants import OUTPUT_DIR
|
|
10
10
|
from .deprecate import deprecate_python
|
|
11
11
|
from .env import from_env
|
|
@@ -32,6 +32,7 @@ from .time import (
|
|
|
32
32
|
current_timestamp,
|
|
33
33
|
date_after,
|
|
34
34
|
past_date,
|
|
35
|
+
timestamp_ms,
|
|
35
36
|
)
|
|
36
37
|
from .type import Callback, Getter, JsonType, SerializedAsset
|
|
37
38
|
from .validation import validate_baseurl
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from typing import Any, DefaultDict, Dict, List, Sequence
|
|
2
|
+
|
|
3
|
+
from .object import getproperty
|
|
4
|
+
from .type import Getter
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def group_by(identifier: Getter, elements: Sequence) -> Dict[Any, List]:
|
|
8
|
+
"""Groups the elements by the given key"""
|
|
9
|
+
groups: Dict[Any, List] = DefaultDict(list)
|
|
10
|
+
for element in elements:
|
|
11
|
+
key = getproperty(element, identifier)
|
|
12
|
+
groups[key].append(element)
|
|
13
|
+
|
|
14
|
+
return groups
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def mapping_from_rows(rows: List[Dict], key: Any, value: Any) -> Dict:
|
|
18
|
+
"""
|
|
19
|
+
Create a dictionary mapping from a list of dictionaries using specified keys for mapping.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
rows (list[dict]): A list of dictionaries from which to create the mapping.
|
|
23
|
+
key (Any): The key to use for the keys of the resulting dictionary.
|
|
24
|
+
value (Any): The key to use for the values of the resulting dictionary.
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
dict: A dictionary where each key-value pair corresponds to the specified key and value
|
|
28
|
+
from each dictionary in the input list. Only dictionaries with both specified key
|
|
29
|
+
and value present are included in the result.
|
|
30
|
+
|
|
31
|
+
Example:
|
|
32
|
+
rows = [{'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}]
|
|
33
|
+
mapping = mapping_from_rows(rows, 'id', 'name')
|
|
34
|
+
# mapping will be {1: 'Alice', 2: 'Bob'}
|
|
35
|
+
"""
|
|
36
|
+
mapping = {}
|
|
37
|
+
|
|
38
|
+
for row in rows:
|
|
39
|
+
mapping_key = row.get(key)
|
|
40
|
+
mapping_value = row.get(value)
|
|
41
|
+
|
|
42
|
+
if not mapping_key or not mapping_value:
|
|
43
|
+
continue
|
|
44
|
+
mapping[mapping_key] = mapping_value
|
|
45
|
+
|
|
46
|
+
return mapping
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from .collection import mapping_from_rows
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test__mapping_from_rows__basic_mapping():
|
|
7
|
+
rows = [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]
|
|
8
|
+
result = mapping_from_rows(rows, "id", "name")
|
|
9
|
+
expected = {1: "Alice", 2: "Bob"}
|
|
10
|
+
assert result == expected
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test__mapping_from_rows__missing_key():
|
|
14
|
+
rows = [{"id": 1, "name": "Alice"}, {"name": "Bob"}]
|
|
15
|
+
result = mapping_from_rows(rows, "id", "name")
|
|
16
|
+
expected = {1: "Alice"}
|
|
17
|
+
assert result == expected
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test__mapping_from_rows__missing_value():
|
|
21
|
+
rows = [{"id": 1, "name": "Alice"}, {"id": 2}]
|
|
22
|
+
result = mapping_from_rows(rows, "id", "name")
|
|
23
|
+
expected = {1: "Alice"}
|
|
24
|
+
assert result == expected
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test__mapping_from_rows__empty_list():
|
|
28
|
+
rows = []
|
|
29
|
+
result = mapping_from_rows(rows, "id", "name")
|
|
30
|
+
expected = {}
|
|
31
|
+
assert result == expected
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test__mapping_from_rows__non_existent_key_value():
|
|
35
|
+
rows = [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]
|
|
36
|
+
result = mapping_from_rows(rows, "nonexistent_key", "nonexistent_value")
|
|
37
|
+
expected = {}
|
|
38
|
+
assert result == expected
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test__mapping_from_rows__none_key_value():
|
|
42
|
+
rows = [
|
|
43
|
+
{"id": 1, "name": "Alice"},
|
|
44
|
+
{"id": None, "name": "Bob"},
|
|
45
|
+
{"id": 2, "name": None},
|
|
46
|
+
]
|
|
47
|
+
result = mapping_from_rows(rows, "id", "name")
|
|
48
|
+
expected = {1: "Alice"}
|
|
49
|
+
assert result == expected
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test__mapping_from_rows__multiple_valid_rows():
|
|
53
|
+
rows = [
|
|
54
|
+
{"id": 1, "name": "Alice"},
|
|
55
|
+
{"id": 2, "name": "Bob"},
|
|
56
|
+
{"id": 3, "name": "Charlie"},
|
|
57
|
+
]
|
|
58
|
+
result = mapping_from_rows(rows, "id", "name")
|
|
59
|
+
expected = {1: "Alice", 2: "Bob", 3: "Charlie"}
|
|
60
|
+
assert result == expected
|
|
@@ -15,7 +15,7 @@ def current_timestamp() -> int:
|
|
|
15
15
|
"""
|
|
16
16
|
Returns the current timestamp from epoch (rounded to the nearest second)
|
|
17
17
|
"""
|
|
18
|
-
return int(
|
|
18
|
+
return int(current_datetime().timestamp())
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def _set_uct_timezone(ts: datetime) -> datetime:
|
|
@@ -24,6 +24,14 @@ def _set_uct_timezone(ts: datetime) -> datetime:
|
|
|
24
24
|
return ts
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
def timestamp_ms(ts: datetime) -> int:
|
|
28
|
+
"""
|
|
29
|
+
Return ts timestamp in millisecond (rounded)
|
|
30
|
+
"""
|
|
31
|
+
ts_utc = _set_uct_timezone(ts)
|
|
32
|
+
return int(ts_utc.timestamp() * 1000)
|
|
33
|
+
|
|
34
|
+
|
|
27
35
|
def now(tz: bool = False) -> datetime:
|
|
28
36
|
"""
|
|
29
37
|
provide current time
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from datetime import date, datetime
|
|
2
2
|
|
|
3
|
-
from .time import at_midnight, date_after
|
|
3
|
+
from .time import at_midnight, date_after, timestamp_ms
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def test_at_midnight():
|
|
@@ -10,3 +10,10 @@ def test_at_midnight():
|
|
|
10
10
|
def test_date_after():
|
|
11
11
|
day = date(1999, 12, 31)
|
|
12
12
|
assert date_after(day, 3) == date(2000, 1, 3)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_timestamp_ms():
|
|
16
|
+
dt = datetime(1991, 4, 3, 0, 0)
|
|
17
|
+
result = timestamp_ms(dt)
|
|
18
|
+
expected = 670636800000
|
|
19
|
+
assert result == expected
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from datetime import
|
|
2
|
+
from datetime import datetime, timedelta
|
|
3
3
|
from http import HTTPStatus
|
|
4
4
|
from typing import Iterator, List, Optional, Set, Tuple
|
|
5
5
|
|
|
6
6
|
import requests
|
|
7
7
|
|
|
8
|
+
from ....utils import at_midnight, current_date, past_date, retry, timestamp_ms
|
|
8
9
|
from ..assets import DomoAsset
|
|
9
10
|
from .credentials import DomoCredentials
|
|
10
11
|
from .endpoints import Endpoint, EndpointFactory
|
|
@@ -13,8 +14,7 @@ from .pagination import Pagination
|
|
|
13
14
|
RawData = Iterator[dict]
|
|
14
15
|
|
|
15
16
|
DOMO_PUBLIC_URL = "https://api.domo.com"
|
|
16
|
-
|
|
17
|
-
DEFAULT_TIMEOUT = 500
|
|
17
|
+
DEFAULT_TIMEOUT = 120
|
|
18
18
|
TOKEN_EXPIRATION_SECONDS = timedelta(seconds=3000) # auth token lasts 1 hour
|
|
19
19
|
|
|
20
20
|
IGNORED_ERROR_CODES = (
|
|
@@ -23,12 +23,14 @@ IGNORED_ERROR_CODES = (
|
|
|
23
23
|
)
|
|
24
24
|
ERROR_TPL = "Request failed with status code {status_code} and reason {reason}"
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
_RETRY_EXCEPTIONS = [
|
|
27
|
+
requests.exceptions.ConnectTimeout,
|
|
28
|
+
requests.exceptions.ReadTimeout,
|
|
29
|
+
]
|
|
30
|
+
_RETRY_COUNT = 2
|
|
31
|
+
_RETRY_BASE_MS = 10 * 60 * 1000 # 10 minutes
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
"""convert date into datetime at midnight: 00:00:00"""
|
|
31
|
-
return datetime.combine(date_, datetime.min.time())
|
|
33
|
+
logger = logging.getLogger(__name__)
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
def _handle_response(response: requests.Response) -> requests.Response:
|
|
@@ -36,21 +38,6 @@ def _handle_response(response: requests.Response) -> requests.Response:
|
|
|
36
38
|
return response
|
|
37
39
|
|
|
38
40
|
|
|
39
|
-
def _is_expired(last_result: dict) -> bool:
|
|
40
|
-
"""
|
|
41
|
-
Checks if the date given is expired
|
|
42
|
-
i.e. date < yesterday (00:00 AM)
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
last_timestamp = datetime.strptime(last_result["time"], FORMAT)
|
|
46
|
-
logger.info(f"Last audit input has timestamp: {last_timestamp}")
|
|
47
|
-
yesterday = date.today() - timedelta(days=1)
|
|
48
|
-
threshold = _at_midnight(yesterday)
|
|
49
|
-
if last_timestamp < threshold:
|
|
50
|
-
return True
|
|
51
|
-
return False
|
|
52
|
-
|
|
53
|
-
|
|
54
41
|
def _ignore_or_raise(
|
|
55
42
|
error: requests.RequestException,
|
|
56
43
|
ignore_error_codes: Optional[Tuple[int, ...]],
|
|
@@ -82,6 +69,7 @@ class DomoClient:
|
|
|
82
69
|
def __init__(self, credentials: DomoCredentials):
|
|
83
70
|
self._authentication = credentials.authentication
|
|
84
71
|
self._bearer_headers: Optional[dict] = None
|
|
72
|
+
self._session = requests.session()
|
|
85
73
|
self._token_creation_time: datetime = datetime.min
|
|
86
74
|
self._endpoint_factory = EndpointFactory(credentials.base_url)
|
|
87
75
|
self._private_headers = credentials.private_headers
|
|
@@ -102,7 +90,7 @@ class DomoClient:
|
|
|
102
90
|
basic_authentication = self._authentication
|
|
103
91
|
endpoint = self._endpoint_factory.authentication
|
|
104
92
|
|
|
105
|
-
response =
|
|
93
|
+
response = self._session.get(
|
|
106
94
|
endpoint.url(),
|
|
107
95
|
auth=basic_authentication,
|
|
108
96
|
timeout=self._timeout,
|
|
@@ -115,6 +103,11 @@ class DomoClient:
|
|
|
115
103
|
|
|
116
104
|
return self._bearer_headers
|
|
117
105
|
|
|
106
|
+
@retry(
|
|
107
|
+
exceptions=_RETRY_EXCEPTIONS,
|
|
108
|
+
max_retries=_RETRY_COUNT,
|
|
109
|
+
base_ms=_RETRY_BASE_MS,
|
|
110
|
+
)
|
|
118
111
|
def _get(
|
|
119
112
|
self,
|
|
120
113
|
endpoint: Endpoint,
|
|
@@ -124,12 +117,14 @@ class DomoClient:
|
|
|
124
117
|
params = params if params else {}
|
|
125
118
|
is_private = endpoint.is_private
|
|
126
119
|
headers = self._private_headers if is_private else self._bearer_auth()
|
|
127
|
-
|
|
120
|
+
|
|
121
|
+
response = self._session.get(
|
|
128
122
|
url=endpoint.url(asset_id),
|
|
129
123
|
headers=headers,
|
|
130
124
|
params=params,
|
|
131
125
|
timeout=self._timeout,
|
|
132
126
|
)
|
|
127
|
+
|
|
133
128
|
if response.status_code != HTTPStatus.OK:
|
|
134
129
|
logger.warning(
|
|
135
130
|
ERROR_TPL.format(
|
|
@@ -165,28 +160,14 @@ class DomoClient:
|
|
|
165
160
|
"""Used when the response is paginated and need iterations"""
|
|
166
161
|
pagination = Pagination()
|
|
167
162
|
all_results: List[dict] = []
|
|
163
|
+
|
|
168
164
|
while pagination.needs_increment:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
params={
|
|
172
|
-
"offset": pagination.offset,
|
|
173
|
-
"limit": pagination.per_page,
|
|
174
|
-
},
|
|
175
|
-
)
|
|
165
|
+
params = {**pagination.params, **endpoint.params}
|
|
166
|
+
results = self._get_many(endpoint=endpoint, params=params)
|
|
176
167
|
all_results.extend(results)
|
|
177
168
|
number_of_items = len(results)
|
|
178
169
|
pagination.increment_offset(number_of_items)
|
|
179
170
|
|
|
180
|
-
if endpoint == self._endpoint_factory.audit:
|
|
181
|
-
last_result = results[-1]
|
|
182
|
-
# We decided to fetch audits until the audit is prior to a particular date
|
|
183
|
-
# defined in _is_expired function. To be more precise, we could have instead use
|
|
184
|
-
# params start and end of the audit endpoint (timestamp in milliseconds).
|
|
185
|
-
# https://developer.domo.com/portal/a4e18ca6a0c0b-retrieve-activity-log-entries
|
|
186
|
-
# But we need then to manage properly the timezone conversion of the results
|
|
187
|
-
# which adds more complexity than benefits
|
|
188
|
-
if _is_expired(last_result):
|
|
189
|
-
pagination.should_stop = True
|
|
190
171
|
return all_results
|
|
191
172
|
|
|
192
173
|
def _datasources(self, page_id: str) -> RawData:
|
|
@@ -300,7 +281,11 @@ class DomoClient:
|
|
|
300
281
|
)
|
|
301
282
|
|
|
302
283
|
def _audit(self) -> RawData:
|
|
303
|
-
|
|
284
|
+
yesterday = timestamp_ms(at_midnight(past_date(1)))
|
|
285
|
+
today = timestamp_ms(at_midnight(current_date()))
|
|
286
|
+
yield from self._get_paginated(
|
|
287
|
+
self._endpoint_factory.audit(yesterday, today)
|
|
288
|
+
)
|
|
304
289
|
|
|
305
290
|
def _dataflows(self) -> RawData:
|
|
306
291
|
dataflows = self._get_many(self._endpoint_factory.dataflows)
|
|
@@ -1,33 +1,11 @@
|
|
|
1
|
-
from datetime import date, datetime, timedelta
|
|
2
1
|
from unittest.mock import patch
|
|
3
2
|
|
|
4
3
|
import pytest
|
|
5
4
|
import requests
|
|
6
5
|
|
|
7
|
-
from .client import
|
|
8
|
-
FORMAT,
|
|
9
|
-
DomoClient,
|
|
10
|
-
DomoCredentials,
|
|
11
|
-
_at_midnight,
|
|
12
|
-
_is_expired,
|
|
13
|
-
)
|
|
6
|
+
from .client import DomoClient, DomoCredentials
|
|
14
7
|
from .endpoints import EndpointFactory
|
|
15
8
|
|
|
16
|
-
NEVER_EXPIRING_DATE = datetime.max
|
|
17
|
-
TODAY_DATE = _at_midnight(date.today())
|
|
18
|
-
EXPIRED_DATE = _at_midnight(date.today() - timedelta(days=2))
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def test__is_expired():
|
|
22
|
-
test_datetimes = (
|
|
23
|
-
({"time": NEVER_EXPIRING_DATE.strftime(FORMAT)}, False),
|
|
24
|
-
({"time": TODAY_DATE.strftime(FORMAT)}, False),
|
|
25
|
-
({"time": EXPIRED_DATE.strftime(FORMAT)}, True),
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
for test_datetime, is_expired in test_datetimes:
|
|
29
|
-
assert _is_expired(test_datetime) == is_expired
|
|
30
|
-
|
|
31
9
|
|
|
32
10
|
class FakeResponse:
|
|
33
11
|
"""
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
2
|
from typing import Optional
|
|
3
3
|
|
|
4
4
|
_DOMO_PUBLIC_URL = "https://api.domo.com"
|
|
@@ -13,6 +13,7 @@ class Endpoint:
|
|
|
13
13
|
|
|
14
14
|
base_url: str
|
|
15
15
|
is_private: bool = False
|
|
16
|
+
params: dict = field(default_factory=dict)
|
|
16
17
|
|
|
17
18
|
def url(self, asset_id: Optional[str] = None):
|
|
18
19
|
return f"{self.base_url}/{asset_id}" if asset_id else self.base_url
|
|
@@ -40,10 +41,6 @@ class EndpointFactory:
|
|
|
40
41
|
def users(self) -> Endpoint:
|
|
41
42
|
return Endpoint(f"{_DOMO_PUBLIC_URL}/v1/users")
|
|
42
43
|
|
|
43
|
-
@property
|
|
44
|
-
def audit(self) -> Endpoint:
|
|
45
|
-
return Endpoint(f"{_DOMO_PUBLIC_URL}/v1/audit")
|
|
46
|
-
|
|
47
44
|
@property
|
|
48
45
|
def dataflows(self) -> Endpoint:
|
|
49
46
|
return Endpoint(
|
|
@@ -51,6 +48,16 @@ class EndpointFactory:
|
|
|
51
48
|
is_private=True,
|
|
52
49
|
)
|
|
53
50
|
|
|
51
|
+
def audit(self, start: int, end: int) -> Endpoint:
|
|
52
|
+
"""
|
|
53
|
+
start and end are timestamps since epoch in milliseconds
|
|
54
|
+
See [documentation](https://developer.domo.com/portal/a4e18ca6a0c0b-retrieve-activity-log-entries)
|
|
55
|
+
"""
|
|
56
|
+
return Endpoint(
|
|
57
|
+
base_url=f"{_DOMO_PUBLIC_URL}/v1/audit",
|
|
58
|
+
params={"start": start, "end": end},
|
|
59
|
+
)
|
|
60
|
+
|
|
54
61
|
def lineage(self, dataflow_id: str) -> Endpoint:
|
|
55
62
|
return Endpoint(
|
|
56
63
|
base_url=f"{self.base_url}/api/data/v1/lineage/DATAFLOW/{dataflow_id}",
|
|
@@ -65,6 +72,6 @@ class EndpointFactory:
|
|
|
65
72
|
|
|
66
73
|
def page_content(self, page_id: str) -> Endpoint:
|
|
67
74
|
return Endpoint(
|
|
68
|
-
f"{self.base_url}/api/content/v3/stacks/{page_id}/cards?parts=datasources",
|
|
75
|
+
base_url=f"{self.base_url}/api/content/v3/stacks/{page_id}/cards?parts=datasources",
|
|
69
76
|
is_private=True,
|
|
70
77
|
)
|
|
@@ -23,6 +23,10 @@ class Pagination:
|
|
|
23
23
|
|
|
24
24
|
return True
|
|
25
25
|
|
|
26
|
+
@property
|
|
27
|
+
def params(self) -> dict:
|
|
28
|
+
return {"offset": self.offset, "limit": self.per_page}
|
|
29
|
+
|
|
26
30
|
def increment_offset(self, number_results: int) -> None:
|
|
27
31
|
self.offset += number_results
|
|
28
32
|
self.number_results = number_results
|
|
@@ -4,7 +4,22 @@ from datetime import date, timedelta
|
|
|
4
4
|
from typing import Callable, Iterator, List, Optional, Sequence, Tuple
|
|
5
5
|
|
|
6
6
|
from dateutil.utils import today
|
|
7
|
-
from looker_sdk
|
|
7
|
+
from looker_sdk import init40
|
|
8
|
+
from looker_sdk.sdk.api40.models import (
|
|
9
|
+
ContentView,
|
|
10
|
+
Dashboard,
|
|
11
|
+
DBConnection,
|
|
12
|
+
Folder,
|
|
13
|
+
GroupHierarchy,
|
|
14
|
+
GroupSearch,
|
|
15
|
+
Look,
|
|
16
|
+
LookmlModel,
|
|
17
|
+
LookmlModelExplore,
|
|
18
|
+
Project,
|
|
19
|
+
User,
|
|
20
|
+
UserAttribute,
|
|
21
|
+
)
|
|
22
|
+
from looker_sdk.sdk.constants import sdk_version
|
|
8
23
|
|
|
9
24
|
from ....utils import Pager, PagerLogger, SafeMode, past_date, safe_mode
|
|
10
25
|
from ..env import page_size
|
|
@@ -24,21 +39,7 @@ from .constants import (
|
|
|
24
39
|
USER_FIELDS,
|
|
25
40
|
USERS_ATTRIBUTES_FIELDS,
|
|
26
41
|
)
|
|
27
|
-
from .sdk import
|
|
28
|
-
Credentials,
|
|
29
|
-
Dashboard,
|
|
30
|
-
DBConnection,
|
|
31
|
-
Folder,
|
|
32
|
-
GroupHierarchy,
|
|
33
|
-
GroupSearch,
|
|
34
|
-
Look,
|
|
35
|
-
LookmlModel,
|
|
36
|
-
LookmlModelExplore,
|
|
37
|
-
Project,
|
|
38
|
-
User,
|
|
39
|
-
has_admin_permissions,
|
|
40
|
-
init40,
|
|
41
|
-
)
|
|
42
|
+
from .sdk import CastorApiSettings, Credentials, has_admin_permissions
|
|
42
43
|
|
|
43
44
|
logger = logging.getLogger(__name__)
|
|
44
45
|
|
|
@@ -81,7 +82,10 @@ class ApiClient:
|
|
|
81
82
|
on_api_call: OnApiCall = lambda: None,
|
|
82
83
|
safe_mode: Optional[SafeMode] = None,
|
|
83
84
|
):
|
|
84
|
-
|
|
85
|
+
settings = CastorApiSettings(
|
|
86
|
+
credentials=credentials, sdk_version=sdk_version
|
|
87
|
+
)
|
|
88
|
+
sdk = init40(config_settings=settings)
|
|
85
89
|
if not has_admin_permissions(sdk):
|
|
86
90
|
raise PermissionError("User does not have admin access.")
|
|
87
91
|
else:
|
{castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/api/sdk.py
RENAMED
|
@@ -4,35 +4,9 @@ This file is a proxy to Looker SDK functions using Castor ApiSettings.
|
|
|
4
4
|
|
|
5
5
|
from typing import Optional
|
|
6
6
|
|
|
7
|
-
from looker_sdk.
|
|
8
|
-
from looker_sdk.rtl import
|
|
9
|
-
auth_session,
|
|
10
|
-
requests_transport,
|
|
11
|
-
serialize,
|
|
12
|
-
transport,
|
|
13
|
-
)
|
|
14
|
-
from looker_sdk.rtl.api_settings import PApiSettings, SettingsConfig
|
|
15
|
-
from looker_sdk.sdk import constants
|
|
7
|
+
from looker_sdk.rtl import transport
|
|
8
|
+
from looker_sdk.rtl.api_settings import ApiSettings, SettingsConfig
|
|
16
9
|
from looker_sdk.sdk.api40 import methods as methods40
|
|
17
|
-
from looker_sdk.sdk.api40.models import (
|
|
18
|
-
Dashboard,
|
|
19
|
-
DashboardElement,
|
|
20
|
-
DBConnection,
|
|
21
|
-
Folder,
|
|
22
|
-
GroupHierarchy,
|
|
23
|
-
GroupSearch,
|
|
24
|
-
Look,
|
|
25
|
-
LookmlModel,
|
|
26
|
-
LookmlModelExplore,
|
|
27
|
-
LookmlModelExploreField,
|
|
28
|
-
LookmlModelExploreFieldset,
|
|
29
|
-
LookmlModelExploreJoins,
|
|
30
|
-
LookmlModelNavExplore,
|
|
31
|
-
Project,
|
|
32
|
-
Query,
|
|
33
|
-
User,
|
|
34
|
-
)
|
|
35
|
-
from typing_extensions import Protocol
|
|
36
10
|
|
|
37
11
|
from ..env import timeout_second
|
|
38
12
|
|
|
@@ -76,46 +50,24 @@ def has_admin_permissions(sdk_: methods40.Looker40SDK) -> bool:
|
|
|
76
50
|
)
|
|
77
51
|
|
|
78
52
|
|
|
79
|
-
|
|
80
|
-
"""Default dependency configuration"""
|
|
81
|
-
settings = ApiSettings(config=config, sdk_version=constants.sdk_version)
|
|
82
|
-
settings.is_configured()
|
|
83
|
-
transport = requests_transport.RequestsTransport.configure(settings)
|
|
84
|
-
return methods40.Looker40SDK(
|
|
85
|
-
auth=auth_session.AuthSession(
|
|
86
|
-
settings,
|
|
87
|
-
transport,
|
|
88
|
-
serialize.deserialize40,
|
|
89
|
-
"4.0",
|
|
90
|
-
),
|
|
91
|
-
deserialize=serialize.deserialize40,
|
|
92
|
-
serialize=serialize.serialize40,
|
|
93
|
-
transport=transport,
|
|
94
|
-
api_version="4.0",
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
class CastorApiSettings(PApiSettings):
|
|
99
|
-
"""This is an intermediate class that is meant to be extended (for typing purpose)"""
|
|
100
|
-
|
|
101
|
-
def read_config(self) -> SettingsConfig:
|
|
102
|
-
raise NotImplementedError()
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
class ApiSettings(CastorApiSettings):
|
|
53
|
+
class CastorApiSettings(ApiSettings):
|
|
106
54
|
"""SDK settings with initialisation using a credential object instead of a path to a .ini file"""
|
|
107
55
|
|
|
108
|
-
def __init__(
|
|
56
|
+
def __init__(
|
|
57
|
+
self, credentials: Credentials, sdk_version: Optional[str] = ""
|
|
58
|
+
):
|
|
109
59
|
"""Configure using a config dict"""
|
|
110
|
-
self.config =
|
|
60
|
+
self.config = credentials.to_settings_config()
|
|
111
61
|
self.verify_ssl = True
|
|
112
62
|
self.base_url = self.config.get("base_url", "")
|
|
113
|
-
self.timeout =
|
|
63
|
+
self.timeout = credentials.timeout
|
|
114
64
|
self.headers = {"Content-Type": "application/json"}
|
|
115
65
|
self.agent_tag = f"{transport.AGENT_PREFIX}"
|
|
116
66
|
if sdk_version:
|
|
117
67
|
self.agent_tag += f" {sdk_version}"
|
|
118
68
|
|
|
69
|
+
super().__init__()
|
|
70
|
+
|
|
119
71
|
def read_config(self) -> SettingsConfig:
|
|
120
72
|
"""Returns a serialization of the credentials"""
|
|
121
73
|
return self.config
|
{castor_extractor-0.16.5 → castor_extractor-0.16.9}/castor_extractor/visualization/looker/extract.py
RENAMED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from typing import Iterable, Optional, Set, Tuple, Union
|
|
3
3
|
|
|
4
|
+
from looker_sdk.sdk.api40.models import LookmlModel
|
|
5
|
+
|
|
4
6
|
from ...logger import add_logging_file_handler, set_stream_handler_to_stdout
|
|
5
7
|
from ...utils import (
|
|
6
8
|
SafeMode,
|
|
@@ -12,7 +14,6 @@ from ...utils import (
|
|
|
12
14
|
write_summary,
|
|
13
15
|
)
|
|
14
16
|
from .api import ApiClient, Credentials, lookml_explore_names
|
|
15
|
-
from .api.sdk import LookmlModel
|
|
16
17
|
from .assets import LookerAsset
|
|
17
18
|
from .multithreading import MultithreadingFetcher
|
|
18
19
|
from .parameters import get_parameters
|
|
@@ -4,11 +4,11 @@ from concurrent.futures import ThreadPoolExecutor
|
|
|
4
4
|
from functools import partial
|
|
5
5
|
from typing import Iterable, List, Set
|
|
6
6
|
|
|
7
|
+
from looker_sdk.error import SDKError
|
|
7
8
|
from tqdm import tqdm # type: ignore
|
|
8
9
|
|
|
9
10
|
from ...utils import RetryStrategy, deep_serialize, retry
|
|
10
11
|
from . import ApiClient
|
|
11
|
-
from .api.sdk import SDKError
|
|
12
12
|
from .assets import LookerAsset
|
|
13
13
|
|
|
14
14
|
logger = logging.getLogger(__name__)
|