analytics-toolkit 1.3.6.18__tar.gz → 1.3.7.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.
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/PKG-INFO +2 -2
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/README.md +1 -1
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/connection/config.py +88 -36
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/connection/get_sql_connection.py +80 -77
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit.egg-info/PKG-INFO +2 -2
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/pyproject.toml +1 -1
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_connection_config.py +344 -13
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/LICENSE +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/api.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/bootstrap.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/constants.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/cuped.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/formatter.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/metrics.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/outliers.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/parallel.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/planning.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/ratio.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/rows.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/split.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/stats.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/ab_utils/validation.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/cli.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/dates/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/dates/dates.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/dates/functions.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/excel/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/excel/long_format.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/general/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/general/logging.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/general/read_file.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/_backend_adapters/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/_backend_adapters/base.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/_backend_adapters/clickhouse.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/_backend_adapters/dbapi.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/_backend_adapters/gp.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/_backend_adapters/registry.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/_backend_adapters/trino.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/_backend_adapters/utils.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/backend_adapters.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/clickhouse/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/clickhouse/lifecycle.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/clickhouse/options.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/clickhouse/wait.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/connection/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/connection/errors.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/connection/protocols.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/core/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/core/capabilities.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/core/identifiers.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/core/types.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/ddl/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/ddl/api.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/ddl/builders.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/ddl/clickhouse.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/ddl/extract_ddl.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/ddl/identifiers.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/ddl/models.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/ddl/schema.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/io/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/io/execute_read.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/io/execute_sql.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/io/gp_cancel.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/io/models.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/io/read_sql.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/load/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/load/load_df.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/load/load_sql_table.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/load/models.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/load/stage.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/table/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/table/_basic_ops.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/table/api.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/table/ch_create_table_as.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/table/ch_drop_table.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/table/ch_full_table_move.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/table/create_table_from_sql.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/table/maintenance.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/table/models.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/table/partitions.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/table/table_validation.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/table/write_modes.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/flow/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/flow/api.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/flow/attempt.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/flow/estimate.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/flow/finalize.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/flow/stage.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/io/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/io/source.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/runtime/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/runtime/models.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/runtime/retry.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/dml/transfer/schema.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/execution/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/execution/labels.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/execution/operation_runner.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/execution/plan_steps.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/execution/plans.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/execution/query_timing.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/metadata/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/metadata/show_tables.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/metadata/table_info.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/orchestration/__init__.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/orchestration/async_sql.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/orchestration/parallel_sql.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/orchestration/pipeline.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/orchestration/tasks.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit.egg-info/SOURCES.txt +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit.egg-info/dependency_links.txt +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit.egg-info/entry_points.txt +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit.egg-info/requires.txt +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit.egg-info/top_level.txt +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/setup.cfg +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_ab_utils_format.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_ab_utils_metrics.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_ab_utils_parallel.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_ab_utils_split.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_dates.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_excel_long_format.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_general_logging.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_general_read_file.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_architecture.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_async.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_backend_adapters.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_ch_create_table_as.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_ch_drop_table.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_ch_full_table_move.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_create_table_from_sql.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_drop_many_partitions.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_execute_read.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_extract_ddl.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_gp_cancel.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_gp_create_partitions.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_improvements.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_load_table.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_parallel.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_retries.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_show_tables.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_transfer_clickhouse.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_transfer_row_batches.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_transfer_schema.py +0 -0
- {analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/tests/test_sql_transfer_source_batches.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: analytics-toolkit
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.7.3
|
|
4
4
|
Summary: Shared Python utilities for SQL, Excel, and date helpers.
|
|
5
5
|
Author: analytics_toolkit contributors
|
|
6
6
|
License: MIT License
|
|
@@ -75,7 +75,7 @@ Python toolkit for AB-test analysis, SQL workflows, Excel reports, and date help
|
|
|
75
75
|
|
|
76
76
|
[Documentation Overview](https://github.com/Karapsin/analytics_toolkit/blob/main/docs/README.md)
|
|
77
77
|
|
|
78
|
-
**Version:** `1.3.
|
|
78
|
+
**Version:** `1.3.7.3`<br>
|
|
79
79
|
**Depends:** Python (`>=3.8,<3.15`)<br>
|
|
80
80
|
**Imports:** [clickhouse-connect](https://pypi.org/project/clickhouse-connect/) (`>=0.5.14,<1`), [lz4](https://pypi.org/project/lz4/) (`>=4.3.2,<5`), [numpy](https://pypi.org/project/numpy/) (`>=1.24.2,<2`), [openpyxl](https://pypi.org/project/openpyxl/) (`>=3.1.1,<4`), [orjson](https://pypi.org/project/orjson/) (`>=3.8.7,<4`), [pandas](https://pypi.org/project/pandas/) (`>=1.4.4,<3`), [psycopg2-binary](https://pypi.org/project/psycopg2-binary/) (`>=2.9.5,<3`), [python-dateutil](https://pypi.org/project/python-dateutil/) (`>=2.8.2,<3`), [pytz](https://pypi.org/project/pytz/) (`>=2022.7`), [requests](https://pypi.org/project/requests/) (`>=2.28.2,<3`), [scipy](https://pypi.org/project/scipy/) (`>=1.10.1,<2`), [sqlglot](https://pypi.org/project/sqlglot/) (`>=20,<31`), [sqlparse](https://pypi.org/project/sqlparse/) (`>=0.4.3,<1`), [tqdm](https://pypi.org/project/tqdm/) (`>=4.65.0,<5`), [trino](https://pypi.org/project/trino/) (`>=0.320,<1`), [zstandard](https://pypi.org/project/zstandard/) (`>=0.20.0,<1`)<br>
|
|
81
81
|
**Suggests:** [apache-airflow](https://pypi.org/project/apache-airflow/) (`>=2.4,<3`; optional extra `airflow`)<br>
|
|
@@ -6,7 +6,7 @@ Python toolkit for AB-test analysis, SQL workflows, Excel reports, and date help
|
|
|
6
6
|
|
|
7
7
|
[Documentation Overview](https://github.com/Karapsin/analytics_toolkit/blob/main/docs/README.md)
|
|
8
8
|
|
|
9
|
-
**Version:** `1.3.
|
|
9
|
+
**Version:** `1.3.7.3`<br>
|
|
10
10
|
**Depends:** Python (`>=3.8,<3.15`)<br>
|
|
11
11
|
**Imports:** [clickhouse-connect](https://pypi.org/project/clickhouse-connect/) (`>=0.5.14,<1`), [lz4](https://pypi.org/project/lz4/) (`>=4.3.2,<5`), [numpy](https://pypi.org/project/numpy/) (`>=1.24.2,<2`), [openpyxl](https://pypi.org/project/openpyxl/) (`>=3.1.1,<4`), [orjson](https://pypi.org/project/orjson/) (`>=3.8.7,<4`), [pandas](https://pypi.org/project/pandas/) (`>=1.4.4,<3`), [psycopg2-binary](https://pypi.org/project/psycopg2-binary/) (`>=2.9.5,<3`), [python-dateutil](https://pypi.org/project/python-dateutil/) (`>=2.8.2,<3`), [pytz](https://pypi.org/project/pytz/) (`>=2022.7`), [requests](https://pypi.org/project/requests/) (`>=2.28.2,<3`), [scipy](https://pypi.org/project/scipy/) (`>=1.10.1,<2`), [sqlglot](https://pypi.org/project/sqlglot/) (`>=20,<31`), [sqlparse](https://pypi.org/project/sqlparse/) (`>=0.4.3,<1`), [tqdm](https://pypi.org/project/tqdm/) (`>=4.65.0,<5`), [trino](https://pypi.org/project/trino/) (`>=0.320,<1`), [zstandard](https://pypi.org/project/zstandard/) (`>=0.20.0,<1`)<br>
|
|
12
12
|
**Suggests:** [apache-airflow](https://pypi.org/project/apache-airflow/) (`>=2.4,<3`; optional extra `airflow`)<br>
|
{analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit/sql/connection/config.py
RENAMED
|
@@ -56,8 +56,7 @@ class TrinoConfig:
|
|
|
56
56
|
auth_mode: str
|
|
57
57
|
http_scheme: str
|
|
58
58
|
verify_value: str
|
|
59
|
-
|
|
60
|
-
keychain_cert_names: list[str]
|
|
59
|
+
ca_certs: list[str]
|
|
61
60
|
insert_chunk_size: int | None
|
|
62
61
|
request_timeout: int | None
|
|
63
62
|
source: str | None
|
|
@@ -77,6 +76,10 @@ class GpConfig:
|
|
|
77
76
|
keepalives_idle: int
|
|
78
77
|
keepalives_interval: int
|
|
79
78
|
keepalives_count: int
|
|
79
|
+
sslmode: str | None
|
|
80
|
+
ca_certs: list[str]
|
|
81
|
+
ssl_cert: str | None
|
|
82
|
+
ssl_key: str | None
|
|
80
83
|
|
|
81
84
|
|
|
82
85
|
@dataclass(frozen=True)
|
|
@@ -90,8 +93,8 @@ class ChConfig:
|
|
|
90
93
|
database: str | None
|
|
91
94
|
secure: bool
|
|
92
95
|
verify_value: str | None
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
ca_certs: list[str]
|
|
97
|
+
ca_certs_variable: str | None
|
|
95
98
|
connect_timeout: int | None
|
|
96
99
|
send_receive_timeout: int | None
|
|
97
100
|
settings: dict[str, Any] | None
|
|
@@ -174,6 +177,11 @@ def _build_connection_config(
|
|
|
174
177
|
backend = _require_backend(connection_key, raw_config)
|
|
175
178
|
|
|
176
179
|
if backend == "trino":
|
|
180
|
+
_reject_removed_fields(
|
|
181
|
+
raw_config,
|
|
182
|
+
connection_key,
|
|
183
|
+
["use_keychain_certs", "keychain_cert_names", "ca_cert"],
|
|
184
|
+
)
|
|
177
185
|
return TrinoConfig(
|
|
178
186
|
connection_key=connection_key,
|
|
179
187
|
backend=backend,
|
|
@@ -203,16 +211,10 @@ def _build_connection_config(
|
|
|
203
211
|
)
|
|
204
212
|
or "true"
|
|
205
213
|
),
|
|
206
|
-
|
|
214
|
+
ca_certs=_optional_string_or_string_list(
|
|
207
215
|
raw_config,
|
|
208
216
|
connection_key,
|
|
209
|
-
"
|
|
210
|
-
False,
|
|
211
|
-
),
|
|
212
|
-
keychain_cert_names=_optional_string_list(
|
|
213
|
-
raw_config,
|
|
214
|
-
connection_key,
|
|
215
|
-
"keychain_cert_names",
|
|
217
|
+
"ca_certs",
|
|
216
218
|
),
|
|
217
219
|
insert_chunk_size=_optional_positive_int(
|
|
218
220
|
raw_config,
|
|
@@ -227,6 +229,15 @@ def _build_connection_config(
|
|
|
227
229
|
source=_optional_string(raw_config, connection_key, "source"),
|
|
228
230
|
)
|
|
229
231
|
if backend == "gp":
|
|
232
|
+
_reject_removed_fields(raw_config, connection_key, ["ca_cert"])
|
|
233
|
+
ca_certs = _optional_string_or_string_list(
|
|
234
|
+
raw_config,
|
|
235
|
+
connection_key,
|
|
236
|
+
"ca_certs",
|
|
237
|
+
)
|
|
238
|
+
sslmode = _optional_string(raw_config, connection_key, "sslmode")
|
|
239
|
+
if ca_certs and sslmode is None:
|
|
240
|
+
sslmode = "verify-full"
|
|
230
241
|
return GpConfig(
|
|
231
242
|
connection_key=connection_key,
|
|
232
243
|
backend=backend,
|
|
@@ -265,24 +276,29 @@ def _build_connection_config(
|
|
|
265
276
|
"keepalives_count",
|
|
266
277
|
DEFAULT_GP_KEEPALIVES_COUNT,
|
|
267
278
|
),
|
|
279
|
+
sslmode=sslmode,
|
|
280
|
+
ca_certs=ca_certs,
|
|
281
|
+
ssl_cert=_optional_string(raw_config, connection_key, "ssl_cert"),
|
|
282
|
+
ssl_key=_optional_string(raw_config, connection_key, "ssl_key"),
|
|
268
283
|
)
|
|
269
284
|
if backend == "ch":
|
|
270
|
-
|
|
271
|
-
if ca_cert is None:
|
|
272
|
-
ca_cert = _optional_string(raw_config, connection_key, "ca_certs")
|
|
273
|
-
ca_cert_variable = _optional_string(
|
|
285
|
+
_reject_removed_fields(
|
|
274
286
|
raw_config,
|
|
275
287
|
connection_key,
|
|
276
|
-
"ca_cert_variable",
|
|
288
|
+
["ca_cert", "ca_cert_variable"],
|
|
277
289
|
)
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
290
|
+
ca_certs = _optional_string_or_string_list(
|
|
291
|
+
raw_config,
|
|
292
|
+
connection_key,
|
|
293
|
+
"ca_certs",
|
|
294
|
+
)
|
|
295
|
+
ca_certs_variable = _optional_string(
|
|
296
|
+
raw_config,
|
|
297
|
+
connection_key,
|
|
298
|
+
"ca_certs_variable",
|
|
299
|
+
)
|
|
300
|
+
if ca_certs:
|
|
301
|
+
ca_certs_variable = None
|
|
286
302
|
return ChConfig(
|
|
287
303
|
connection_key=connection_key,
|
|
288
304
|
backend=backend,
|
|
@@ -297,8 +313,8 @@ def _build_connection_config(
|
|
|
297
313
|
connection_key,
|
|
298
314
|
"verify",
|
|
299
315
|
),
|
|
300
|
-
|
|
301
|
-
|
|
316
|
+
ca_certs=ca_certs,
|
|
317
|
+
ca_certs_variable=ca_certs_variable,
|
|
302
318
|
connect_timeout=_optional_positive_int(
|
|
303
319
|
raw_config,
|
|
304
320
|
connection_key,
|
|
@@ -338,19 +354,35 @@ def generate_dummy_connections(airflow: bool = False) -> Path:
|
|
|
338
354
|
connections_path = Path.cwd() / CONNECTIONS_FILE_NAME
|
|
339
355
|
if connections_path.exists():
|
|
340
356
|
raise ValueError(f"SQL connections file already exists: {connections_path}")
|
|
357
|
+
certs_dir = Path.cwd() / ".certs"
|
|
341
358
|
|
|
342
359
|
content = (
|
|
343
360
|
_build_dummy_airflow_connections()
|
|
344
361
|
if airflow
|
|
345
362
|
else _build_dummy_direct_connections()
|
|
346
363
|
)
|
|
364
|
+
certs_dir.mkdir(exist_ok=True)
|
|
347
365
|
connections_path.write_text(
|
|
348
366
|
json.dumps(content, indent=2) + "\n",
|
|
349
367
|
encoding="utf-8",
|
|
350
368
|
)
|
|
369
|
+
_print_dummy_connections_cert_instructions(certs_dir)
|
|
351
370
|
return connections_path
|
|
352
371
|
|
|
353
372
|
|
|
373
|
+
def _print_dummy_connections_cert_instructions(certs_dir: Path) -> None:
|
|
374
|
+
print(f"Created {certs_dir} for local certificate files.")
|
|
375
|
+
print(
|
|
376
|
+
"Greenplum: put CA PEMs in .certs/ and set ca_certs; "
|
|
377
|
+
"optional ssl_cert, ssl_key, sslmode."
|
|
378
|
+
)
|
|
379
|
+
print("Trino: put HTTPS CA PEMs in .certs/ and set ca_certs.")
|
|
380
|
+
print(
|
|
381
|
+
"ClickHouse: put HTTPS CA PEMs in .certs/ and set ca_certs; "
|
|
382
|
+
"Airflow can use ca_certs_variable."
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
|
|
354
386
|
def _build_dummy_direct_connections() -> dict[str, dict[str, Any]]:
|
|
355
387
|
return {
|
|
356
388
|
"gp": {
|
|
@@ -360,6 +392,7 @@ def _build_dummy_direct_connections() -> dict[str, dict[str, Any]]:
|
|
|
360
392
|
"user": "user",
|
|
361
393
|
"password": "password",
|
|
362
394
|
"database": "db",
|
|
395
|
+
"ca_certs": "gp-ca.pem",
|
|
363
396
|
},
|
|
364
397
|
"trino": {
|
|
365
398
|
"type": "trino",
|
|
@@ -369,6 +402,8 @@ def _build_dummy_direct_connections() -> dict[str, dict[str, Any]]:
|
|
|
369
402
|
"password": "password",
|
|
370
403
|
"catalog": "iceberg",
|
|
371
404
|
"schema": "sandbox",
|
|
405
|
+
"http_scheme": "https",
|
|
406
|
+
"ca_certs": "trino-ca.pem",
|
|
372
407
|
},
|
|
373
408
|
"ch": {
|
|
374
409
|
"type": "ch",
|
|
@@ -377,6 +412,8 @@ def _build_dummy_direct_connections() -> dict[str, dict[str, Any]]:
|
|
|
377
412
|
"user": "user",
|
|
378
413
|
"password": "password",
|
|
379
414
|
"database": "default",
|
|
415
|
+
"secure": True,
|
|
416
|
+
"ca_certs": "clickhouse-ca.pem",
|
|
380
417
|
},
|
|
381
418
|
}
|
|
382
419
|
|
|
@@ -385,9 +422,9 @@ def _build_dummy_airflow_connections() -> dict[str, Any]:
|
|
|
385
422
|
return {
|
|
386
423
|
"source": "airflow",
|
|
387
424
|
"connections": {
|
|
388
|
-
"gp": {"type": "gp"},
|
|
389
|
-
"trino": {"type": "trino"},
|
|
390
|
-
"ch": {"type": "ch"},
|
|
425
|
+
"gp": {"type": "gp", "ca_certs": "gp-ca.pem"},
|
|
426
|
+
"trino": {"type": "trino", "ca_certs": "trino-ca.pem"},
|
|
427
|
+
"ch": {"type": "ch", "ca_certs": "clickhouse-ca.pem"},
|
|
391
428
|
},
|
|
392
429
|
}
|
|
393
430
|
|
|
@@ -763,6 +800,10 @@ def _get_airflow_raw_connection_config_and_extras(
|
|
|
763
800
|
"keepalives_idle",
|
|
764
801
|
"keepalives_interval",
|
|
765
802
|
"keepalives_count",
|
|
803
|
+
"sslmode",
|
|
804
|
+
"ca_certs",
|
|
805
|
+
"ssl_cert",
|
|
806
|
+
"ssl_key",
|
|
766
807
|
],
|
|
767
808
|
)
|
|
768
809
|
elif resolved_backend == "trino":
|
|
@@ -775,8 +816,7 @@ def _get_airflow_raw_connection_config_and_extras(
|
|
|
775
816
|
"auth_mode",
|
|
776
817
|
"http_scheme",
|
|
777
818
|
"verify",
|
|
778
|
-
"
|
|
779
|
-
"keychain_cert_names",
|
|
819
|
+
"ca_certs",
|
|
780
820
|
"insert_chunk_size",
|
|
781
821
|
"request_timeout",
|
|
782
822
|
"source",
|
|
@@ -794,9 +834,7 @@ def _get_airflow_raw_connection_config_and_extras(
|
|
|
794
834
|
[
|
|
795
835
|
"secure",
|
|
796
836
|
"verify",
|
|
797
|
-
"ca_cert",
|
|
798
837
|
"ca_certs",
|
|
799
|
-
"ca_cert_variable",
|
|
800
838
|
"ca_certs_variable",
|
|
801
839
|
"connect_timeout",
|
|
802
840
|
"send_receive_timeout",
|
|
@@ -1208,7 +1246,21 @@ def _optional_mapping(
|
|
|
1208
1246
|
return dict(value)
|
|
1209
1247
|
|
|
1210
1248
|
|
|
1211
|
-
def
|
|
1249
|
+
def _reject_removed_fields(
|
|
1250
|
+
config: dict[str, Any],
|
|
1251
|
+
connection_key: str,
|
|
1252
|
+
field_names: Sequence[str],
|
|
1253
|
+
) -> None:
|
|
1254
|
+
for field_name in field_names:
|
|
1255
|
+
if field_name in config:
|
|
1256
|
+
raise SqlConfigError(
|
|
1257
|
+
f"SQL connection '{connection_key}' field '{field_name}' "
|
|
1258
|
+
"is not supported. "
|
|
1259
|
+
"Use 'ca_certs' for CA certificate files."
|
|
1260
|
+
)
|
|
1261
|
+
|
|
1262
|
+
|
|
1263
|
+
def _optional_string_or_string_list(
|
|
1212
1264
|
config: dict[str, Any],
|
|
1213
1265
|
connection_key: str,
|
|
1214
1266
|
field_name: str,
|
|
@@ -1217,7 +1269,7 @@ def _optional_string_list(
|
|
|
1217
1269
|
if value is None:
|
|
1218
1270
|
return []
|
|
1219
1271
|
if isinstance(value, str):
|
|
1220
|
-
names = [
|
|
1272
|
+
names = [value.strip()]
|
|
1221
1273
|
elif isinstance(value, list):
|
|
1222
1274
|
names = []
|
|
1223
1275
|
for item in value:
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import os
|
|
4
|
-
import subprocess
|
|
5
3
|
from dataclasses import replace
|
|
6
4
|
from functools import wraps
|
|
7
5
|
from pathlib import Path
|
|
@@ -91,9 +89,8 @@ def _get_trino_connection(config: TrinoConfig) -> Any:
|
|
|
91
89
|
"The 'trino' package is required for Trino connections."
|
|
92
90
|
) from exc
|
|
93
91
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
verify_value = str(_build_trino_keychain_bundle(config))
|
|
92
|
+
ca_certs = _resolve_ca_certs(config.connection_key, config.ca_certs)
|
|
93
|
+
verify_value = ca_certs or config.verify_value
|
|
97
94
|
|
|
98
95
|
if config.auth_mode == "oauth2":
|
|
99
96
|
auth = trino.auth.OAuth2Authentication()
|
|
@@ -150,6 +147,25 @@ def _get_gp_connection(config: GpConfig) -> Any:
|
|
|
150
147
|
"keepalives_count": config.keepalives_count,
|
|
151
148
|
}
|
|
152
149
|
)
|
|
150
|
+
if config.sslmode is not None:
|
|
151
|
+
connect_kwargs["sslmode"] = config.sslmode
|
|
152
|
+
ca_certs = _resolve_ca_certs(config.connection_key, config.ca_certs)
|
|
153
|
+
if ca_certs is not None:
|
|
154
|
+
connect_kwargs["sslrootcert"] = ca_certs
|
|
155
|
+
if config.ssl_cert is not None:
|
|
156
|
+
ssl_cert = _resolve_single_cert_path(
|
|
157
|
+
config.connection_key,
|
|
158
|
+
config.ssl_cert,
|
|
159
|
+
field_name="ssl_cert",
|
|
160
|
+
)
|
|
161
|
+
connect_kwargs["sslcert"] = str(ssl_cert)
|
|
162
|
+
if config.ssl_key is not None:
|
|
163
|
+
ssl_key = _resolve_single_cert_path(
|
|
164
|
+
config.connection_key,
|
|
165
|
+
config.ssl_key,
|
|
166
|
+
field_name="ssl_key",
|
|
167
|
+
)
|
|
168
|
+
connect_kwargs["sslkey"] = str(ssl_key)
|
|
153
169
|
|
|
154
170
|
return psycopg2.connect(**connect_kwargs)
|
|
155
171
|
|
|
@@ -176,9 +192,9 @@ def _get_ch_connection(config: ChConfig) -> Any:
|
|
|
176
192
|
client_kwargs["database"] = config.database
|
|
177
193
|
if config.verify_value is not None:
|
|
178
194
|
client_kwargs["verify"] = _parse_verify_value(config.verify_value)
|
|
179
|
-
|
|
180
|
-
if
|
|
181
|
-
client_kwargs["ca_cert"] =
|
|
195
|
+
ca_certs = _resolve_ch_ca_certs(config)
|
|
196
|
+
if ca_certs is not None:
|
|
197
|
+
client_kwargs["ca_cert"] = ca_certs
|
|
182
198
|
if config.connect_timeout is not None:
|
|
183
199
|
client_kwargs["connect_timeout"] = config.connect_timeout
|
|
184
200
|
if config.send_receive_timeout is not None:
|
|
@@ -197,35 +213,35 @@ def _get_ch_connection(config: ChConfig) -> Any:
|
|
|
197
213
|
return clickhouse_connect.get_client(**client_kwargs)
|
|
198
214
|
|
|
199
215
|
|
|
200
|
-
def
|
|
201
|
-
if config.
|
|
202
|
-
return config.
|
|
203
|
-
if config.
|
|
216
|
+
def _resolve_ch_ca_certs(config: ChConfig) -> str | None:
|
|
217
|
+
if config.ca_certs:
|
|
218
|
+
return _resolve_ca_certs(config.connection_key, config.ca_certs)
|
|
219
|
+
if config.ca_certs_variable is None:
|
|
204
220
|
return None
|
|
205
221
|
|
|
206
222
|
try:
|
|
207
223
|
from airflow.models.variable import Variable
|
|
208
224
|
except ImportError as exc:
|
|
209
225
|
raise SqlConfigError(
|
|
210
|
-
f"SQL connection '{config.connection_key}' uses
|
|
226
|
+
f"SQL connection '{config.connection_key}' uses ca_certs_variable "
|
|
211
227
|
"but Airflow Variable support is unavailable."
|
|
212
228
|
) from exc
|
|
213
229
|
|
|
214
230
|
try:
|
|
215
|
-
|
|
231
|
+
ca_certs = Variable.get(config.ca_certs_variable)
|
|
216
232
|
except Exception as exc:
|
|
217
233
|
raise SqlConfigError(
|
|
218
|
-
f"Could not resolve Airflow Variable '{config.
|
|
234
|
+
f"Could not resolve Airflow Variable '{config.ca_certs_variable}' "
|
|
219
235
|
f"for SQL connection '{config.connection_key}'. "
|
|
220
236
|
f"{type(exc).__name__}: {exc}"
|
|
221
237
|
) from exc
|
|
222
238
|
|
|
223
|
-
if not isinstance(
|
|
239
|
+
if not isinstance(ca_certs, str) or not ca_certs.strip():
|
|
224
240
|
raise SqlConfigError(
|
|
225
|
-
f"Airflow Variable '{config.
|
|
241
|
+
f"Airflow Variable '{config.ca_certs_variable}' for SQL connection "
|
|
226
242
|
f"'{config.connection_key}' must be a non-empty string."
|
|
227
243
|
)
|
|
228
|
-
return
|
|
244
|
+
return _resolve_ca_certs(config.connection_key, [ca_certs.strip()])
|
|
229
245
|
|
|
230
246
|
|
|
231
247
|
def _parse_verify_value(value: str) -> bool | str:
|
|
@@ -238,69 +254,56 @@ def _parse_verify_value(value: str) -> bool | str:
|
|
|
238
254
|
return normalized
|
|
239
255
|
|
|
240
256
|
|
|
241
|
-
def
|
|
242
|
-
if not
|
|
243
|
-
|
|
244
|
-
f"SQL connection '{config.connection_key}' enables keychain certs "
|
|
245
|
-
"but does not define keychain_cert_names."
|
|
246
|
-
)
|
|
257
|
+
def _resolve_ca_certs(connection_key: str, ca_certs: list[str]) -> str | None:
|
|
258
|
+
if not ca_certs:
|
|
259
|
+
return None
|
|
247
260
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
keychains = [
|
|
252
|
-
str(Path.home() / "Library/Keychains/login.keychain-db"),
|
|
253
|
-
"/Library/Keychains/System.keychain",
|
|
261
|
+
resolved_paths = [
|
|
262
|
+
_resolve_single_cert_path(connection_key, cert_path, field_name="ca_certs")
|
|
263
|
+
for cert_path in ca_certs
|
|
254
264
|
]
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
265
|
+
if len(resolved_paths) == 1:
|
|
266
|
+
return str(resolved_paths[0])
|
|
267
|
+
|
|
268
|
+
connections_dir = get_connections_file_path().parent
|
|
269
|
+
bundle_dir = connections_dir / ".certs" / ".generated"
|
|
270
|
+
bundle_dir.mkdir(parents=True, exist_ok=True)
|
|
271
|
+
bundle_path = bundle_dir / f"{_safe_file_key(connection_key)}-ca-bundle.pem"
|
|
272
|
+
bundle_contents = "\n".join(
|
|
273
|
+
path.read_text(encoding="utf-8").strip()
|
|
274
|
+
for path in resolved_paths
|
|
275
|
+
) + "\n"
|
|
276
|
+
if (
|
|
277
|
+
not bundle_path.exists()
|
|
278
|
+
or bundle_path.read_text(encoding="utf-8") != bundle_contents
|
|
279
|
+
):
|
|
266
280
|
bundle_path.write_text(bundle_contents, encoding="utf-8")
|
|
267
|
-
return bundle_path
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
def
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
281
|
+
return str(bundle_path)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def _resolve_single_cert_path(
|
|
285
|
+
connection_key: str,
|
|
286
|
+
cert_path: str,
|
|
287
|
+
*,
|
|
288
|
+
field_name: str,
|
|
289
|
+
) -> Path:
|
|
290
|
+
raw_path = cert_path.strip()
|
|
291
|
+
path = Path(raw_path)
|
|
292
|
+
if path.is_absolute():
|
|
293
|
+
resolved = path
|
|
294
|
+
else:
|
|
295
|
+
connections_dir = get_connections_file_path().parent
|
|
296
|
+
if "/" in raw_path or "\\" in raw_path:
|
|
297
|
+
resolved = connections_dir / path
|
|
298
|
+
else:
|
|
299
|
+
resolved = connections_dir / ".certs" / path
|
|
300
|
+
resolved = resolved.resolve()
|
|
301
|
+
if not resolved.is_file():
|
|
302
|
+
raise SqlConfigError(
|
|
303
|
+
f"SQL connection '{connection_key}' field '{field_name}' references "
|
|
304
|
+
f"missing certificate file: {resolved}"
|
|
288
305
|
)
|
|
289
|
-
|
|
290
|
-
return result.stdout
|
|
291
|
-
|
|
292
|
-
return ""
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
def _state_dir() -> Path:
|
|
296
|
-
state_override = os.getenv("MAGNIT_UTILS_HOME")
|
|
297
|
-
if state_override:
|
|
298
|
-
return Path(state_override).expanduser()
|
|
299
|
-
|
|
300
|
-
try:
|
|
301
|
-
return get_connections_file_path().parent
|
|
302
|
-
except SqlConfigError:
|
|
303
|
-
return Path.cwd().resolve()
|
|
306
|
+
return resolved
|
|
304
307
|
|
|
305
308
|
|
|
306
309
|
def _safe_file_key(connection_key: str) -> str:
|
{analytics_toolkit-1.3.6.18 → analytics_toolkit-1.3.7.3}/analytics_toolkit.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: analytics-toolkit
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.7.3
|
|
4
4
|
Summary: Shared Python utilities for SQL, Excel, and date helpers.
|
|
5
5
|
Author: analytics_toolkit contributors
|
|
6
6
|
License: MIT License
|
|
@@ -75,7 +75,7 @@ Python toolkit for AB-test analysis, SQL workflows, Excel reports, and date help
|
|
|
75
75
|
|
|
76
76
|
[Documentation Overview](https://github.com/Karapsin/analytics_toolkit/blob/main/docs/README.md)
|
|
77
77
|
|
|
78
|
-
**Version:** `1.3.
|
|
78
|
+
**Version:** `1.3.7.3`<br>
|
|
79
79
|
**Depends:** Python (`>=3.8,<3.15`)<br>
|
|
80
80
|
**Imports:** [clickhouse-connect](https://pypi.org/project/clickhouse-connect/) (`>=0.5.14,<1`), [lz4](https://pypi.org/project/lz4/) (`>=4.3.2,<5`), [numpy](https://pypi.org/project/numpy/) (`>=1.24.2,<2`), [openpyxl](https://pypi.org/project/openpyxl/) (`>=3.1.1,<4`), [orjson](https://pypi.org/project/orjson/) (`>=3.8.7,<4`), [pandas](https://pypi.org/project/pandas/) (`>=1.4.4,<3`), [psycopg2-binary](https://pypi.org/project/psycopg2-binary/) (`>=2.9.5,<3`), [python-dateutil](https://pypi.org/project/python-dateutil/) (`>=2.8.2,<3`), [pytz](https://pypi.org/project/pytz/) (`>=2022.7`), [requests](https://pypi.org/project/requests/) (`>=2.28.2,<3`), [scipy](https://pypi.org/project/scipy/) (`>=1.10.1,<2`), [sqlglot](https://pypi.org/project/sqlglot/) (`>=20,<31`), [sqlparse](https://pypi.org/project/sqlparse/) (`>=0.4.3,<1`), [tqdm](https://pypi.org/project/tqdm/) (`>=4.65.0,<5`), [trino](https://pypi.org/project/trino/) (`>=0.320,<1`), [zstandard](https://pypi.org/project/zstandard/) (`>=0.20.0,<1`)<br>
|
|
81
81
|
**Suggests:** [apache-airflow](https://pypi.org/project/apache-airflow/) (`>=2.4,<3`; optional extra `airflow`)<br>
|