datacontract-cli 1.2.3__tar.gz → 1.2.5__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.
- {datacontract_cli-1.2.3/datacontract_cli.egg-info → datacontract_cli-1.2.5}/PKG-INFO +8 -7
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/README.md +2 -1
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/api.py +13 -4
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/cli.py +20 -1
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_ci.py +5 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_edit.py +30 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_test.py +4 -1
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/config/settings.py +14 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/config/variables.py +38 -8
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/data_contract.py +11 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/checks/check_spec.py +6 -1
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/checks/create_checks.py +187 -24
- datacontract_cli-1.2.5/datacontract/engines/checks/custom_quality_check.py +552 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/checks/dimensions.py +2 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/checks/sql_guard.py +4 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/data_contract_test.py +7 -1
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/hana/check_hana_execute.py +2 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/hana/hana_quality_check.py +126 -16
- datacontract_cli-1.2.5/datacontract/engines/ibis/__init__.py +16 -0
- datacontract_cli-1.2.5/datacontract/engines/ibis/connections/athena_patch.py +20 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/connections/connect.py +16 -8
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/connections/duckdb_connection.py +56 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/ibis_check_execute.py +32 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/native_type.py +1 -1
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/mysql_importer.py +2 -3
- datacontract_cli-1.2.5/datacontract/imports/postgres_importer.py +424 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/sql_importer.py +1 -1
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/sqlserver_importer.py +4 -4
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/integration/dbt_sync.py +11 -19
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/lint/resolve.py +109 -44
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/output/test_results_writer.py +2 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5/datacontract_cli.egg-info}/PKG-INFO +8 -7
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract_cli.egg-info/SOURCES.txt +5 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract_cli.egg-info/requires.txt +5 -5
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/pyproject.toml +6 -7
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_api.py +20 -3
- datacontract_cli-1.2.5/tests/test_api_concurrency.py +186 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_config.py +5 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_athena.py +17 -2
- datacontract_cli-1.2.5/tests/test_connect_mysql.py +173 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_postgres.py +10 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_redshift.py +10 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_sqlserver.py +15 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_create_checks_sql_placeholders.py +22 -17
- datacontract_cli-1.2.5/tests/test_custom_quality_checks.py +531 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_dbt_sync.py +6 -6
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_edit.py +36 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_markdown.py +1 -1
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_spark.py +2 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_hana_quality_check.py +39 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_mysql.py +30 -0
- datacontract_cli-1.2.5/tests/test_import_postgres.py +396 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_sql_postgres.py +6 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_lint.py +95 -10
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_quality_sql_dialects.py +4 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_azure_remote.py +4 -3
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_bigquery.py +5 -4
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_checks_filter.py +3 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_databricks.py +3 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_delta.py +4 -3
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_dimension_filter.py +2 -1
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_dry_run.py +5 -4
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_gcs_csv_remote.py +4 -3
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_gcs_json_remote.py +4 -3
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_kafka_remote.py +3 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_local_json_nd.py +2 -1
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_mysql.py +3 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_oracle.py +3 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_oracle_xe.py +3 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_parquet.py +8 -4
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_postgres.py +18 -4
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_quality.py +3 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_quality_local_fallback.py +3 -2
- datacontract_cli-1.2.5/tests/test_test_relationships.py +270 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_results_writer.py +6 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_s3_csv.py +4 -3
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_s3_delta.py +3 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_s3_json.py +3 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_s3_json_complex.py +3 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_s3_json_multiple_models.py +2 -1
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_snowflake.py +3 -2
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_sqlserver.py +3 -2
- datacontract_cli-1.2.5/tests/test_test_trino.py +187 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_untrusted_contract.py +1 -1
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_variables.py +19 -0
- datacontract_cli-1.2.3/datacontract/imports/postgres_importer.py +0 -259
- datacontract_cli-1.2.3/datacontract/output/__init__.py +0 -0
- datacontract_cli-1.2.3/tests/test_connect_mysql.py +0 -78
- datacontract_cli-1.2.3/tests/test_import_postgres.py +0 -187
- datacontract_cli-1.2.3/tests/test_test_trino.py +0 -99
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/LICENSE +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/MANIFEST.in +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/__init__.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/breaking/__init__.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/breaking/detector.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/breaking/rules.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/catalog/catalog.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/changelog/__init__.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/changelog/changelog.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/changelog/normalize.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_api.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_breaking.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_catalog.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_changelog.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_dbt.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_export.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_import.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_init.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_lint.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/command_publish.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/config/__init__.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/config/cli_context.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/editor_assets/VERSION +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/editor_assets/assets/editor.worker-4.7.0.js +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/editor_assets/assets/yaml.worker-4.7.0.js +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/editor_assets/datacontract-editor.css +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/editor_assets/datacontract-editor.es.js +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/editor_assets/index.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/editor_assets/logo_fuchsia_v2.svg +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/editor_assets/monaco-4.7.0.js +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/editor_assets/odcs.svg +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/editor_assets/robots.txt +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/editor_assets/rolldown-runtime-DY7j01NX.js +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/editor_assets/sitemap.xml +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/__init__.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/checks/__init__.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/checks/check_filter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/checks/physical_type_match.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/checks/severity.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/checks/type_normalize.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/datacontract/check_azure_blob_file.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/fastjsonschema/check_jsonschema.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/hana/__init__.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/hana/hana_check_selection.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/hana/hana_connection.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/hana/hana_schema_check.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/hana/hana_type_mapping.py +0 -0
- {datacontract_cli-1.2.3/datacontract/engines/ibis → datacontract_cli-1.2.5/datacontract/engines/ibis/connections}/__init__.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/connections/aws_credentials.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/connections/databricks_patch.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/connections/exasol_patch.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/connections/hive_patch.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/connections/iceberg.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/connections/kafka.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/connections/oracle_patch.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/connections/redshift_credentials.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/connections/redshift_patch.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/dtype_category.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/engines/ibis/snowflake_structured_types.py +0 -0
- {datacontract_cli-1.2.3/datacontract/engines/ibis/connections → datacontract_cli-1.2.5/datacontract/export}/__init__.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/avro_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/avro_idl_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/bigquery_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/custom_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/data_caterer_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/dbml_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/dbt_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/dcs_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/dqx_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/duckdb_type_converter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/excel_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/exporter_factory.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/go_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/great_expectations_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/html_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/iceberg_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/jsonschema_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/markdown_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/mermaid_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/odcs_v3_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/pandas_type_converter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/protobuf_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/pydantic_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/rdf_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/sodacl_check_builder.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/sodacl_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/spark_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/sql_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/sql_type_converter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/sqlalchemy_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/export/xsd_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/athena_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/avro_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/bigquery_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/clickhouse_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/csv_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/dbml_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/dbt_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/dcs_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/excel_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/glue_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/hive_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/iceberg_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/importer_factory.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/json_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/jsonschema_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/object_storage_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/odata_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/odcs_helper.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/odcs_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/openapi_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/oracle_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/parquet_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/powerbi_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/protobuf_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/pydantic_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/redshift_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/snowflake_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/spark_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/spark_type_json.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/trino_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/unity_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/imports/xsd_importer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/init/init_template.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/integration/dbt_test_mapping.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/integration/entropy_data.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/lint/constraints.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/lint/files.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/lint/resources.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/lint/s3.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/lint/schema.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/lint/urls.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/model/breaking.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/model/changelog.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/model/enum_values.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/model/exceptions.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/model/map_type.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/model/natural_keys.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/model/odcs.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/model/run.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/model/server.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/model/vector_type.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/model/workbook.py +0 -0
- {datacontract_cli-1.2.3/datacontract/export → datacontract_cli-1.2.5/datacontract/output}/__init__.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/output/ci_output.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/output/json_test_results.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/output/junit_test_results.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/output/output_format.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/output/text_breaking_results.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/output/text_changelog_results.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/py.typed +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/schemas/datacontract-1.2.1.init.yaml +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/schemas/datacontract-1.2.1.schema.json +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/schemas/odcs-3.0.2.schema.json +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/schemas/odcs-3.1.0.schema.json +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/schemas/odcs-3.2.0.init.yaml +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/schemas/odcs-3.2.0.schema.json +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/datacontract.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/datacontract_odcs.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/excel/odcs-template-v3.0.xlsx +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/excel/odcs-template-v3.1.xlsx +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/excel/odcs-template-v3.2.xlsx +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/index.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/macros/authoritative_definitions.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/macros/context.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/macros/schema.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/macros/server.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/macros/support.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials/datacontract_information.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials/datacontract_terms.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials/definition.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials/example.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials/model_field.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials/quality.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials/server.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/context.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/custom_properties.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/diagram.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/dialog_yaml.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/footer.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/fundamentals.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/header.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/pricing.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/roles.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/schema.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/servers.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/sla.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/support.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/team.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/term_of_use.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/partials_odcs/title.html +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract/templates/style/output.css +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract_cli.egg-info/dependency_links.txt +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract_cli.egg-info/entry_points.txt +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/datacontract_cli.egg-info/top_level.txt +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/setup.cfg +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_api_openapi.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_breaking.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_breaking_odcs_3_2.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_catalog.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_changelog.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_changelog_engine.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_changelog_normalize.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_changelog_output_text.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_check_quality_provenance.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_ci_output.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_cli.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_command_api.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_command_api_options.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_config_file.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_config_require.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_config_threading.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_bigquery.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_clickhouse.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_databricks.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_exasol.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_hive.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_impala.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_oracle.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_s3_credentials.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_snowflake.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_connect_trino.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_create_checks_array_items.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_create_checks_nested.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_create_checks_nested_type.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_create_checks_physical_type.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_create_checks_primary_key.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_create_checks_retention_period.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_create_checks_servicelevel.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_data_contract.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_data_contract_checks.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_data_contract_specification.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_dbt_test_mapping.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_description_linter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_docs_commands.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_docs_config_options.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_docs_ordering.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_download_datacontract_file.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_dtype_category.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_duckdb_json.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_enum_values.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_avro.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_avro_idl.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_bigquery.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_complex_data_contract.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_custom.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_custom_exporter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_custom_model.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_data_caterer.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_dbml.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_dbt_models.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_dbt_sources.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_dbt_staging_sql.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_dcs.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_dqx.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_excel.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_go.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_great_expectations.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_html.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_iceberg.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_jsonschema.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_large_contract.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_mermaid.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_odcs_v3.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_protobuf.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_pydantic.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_rdf.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_sodacl.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_sql.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_sql_clickhouse.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_sql_query.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_sqlalchemy.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_export_xsd.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_hana_connection.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_hana_schema_check.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_hana_type_mapping.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_ibis_check_execute.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_ibis_mssql_pattern.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_ibis_mssql_schema.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_ibis_oracle_schema.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_athena.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_avro.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_bigquery.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_clickhouse.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_csv.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_dbml.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_dbt.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_excel.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_glue.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_hive.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_iceberg.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_json.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_jsonschema.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_object_storage.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_odata.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_odcs_v3.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_openapi.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_oracle.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_parquet.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_powerbi.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_protobuf.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_pydantic_model.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_redshift.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_snowflake.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_spark_type_json.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_sql_clickhouse.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_sql_hive.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_sql_oracle.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_sql_snowflake.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_sql_sqlserver.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_sql_struct.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_sqlserver.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_trino.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_unity_file.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_unmapped_types.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_import_xsd.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_install_extras.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_integration_entropydata.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_lint_files.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_lint_odcs_3_2_constraints.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_lint_schema.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_lint_urls.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_map_type.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_metadata_fields.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_native_type_schema_scope.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_nested_path_checks.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_oracle_patch.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_physical_type_match.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_publish_test_results.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_publish_test_results_payload.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_quality_unrunnable_rules.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_redshift_credentials.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_redshift_patch.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_resolve.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_resolve_definitions.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_resolve_local_definitions.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_roundtrip_jsonschema.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_roundtrip_pydantic_model.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_roundtrip_xsd.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_row_filter_duplicate_count.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_run_check_deprecated_fields.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_run_check_engine.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_server_overrides.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_server_type_mssql.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_server_type_synonyms.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_servers_3_2_0.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_snowflake_structured_types.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_sql_type_converter_physicaltype.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_api.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_api_openapi_import.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_array_items.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_athena_iceberg.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_azure_blob_file.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_clickhouse.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_diagnostics.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_duckdb.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_failed_samples.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_hana.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_hive.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_iceberg.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_iceberg_rest.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_iceberg_s3tables.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_kafka.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_kafka_decoding.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_local_json.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_local_xml.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_metadata_only.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_nested_checks.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_output_json.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_output_junit.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_quality_id_and_tag_filter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_quality_percent_severity.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_redshift.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_row_filter.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_s3_json_multiple_files.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_schema_evolution.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_server_not_found.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_soda_connection_error.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_test_variables.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_type_normalize.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_untrusted_contract_variables.py +0 -0
- {datacontract_cli-1.2.3 → datacontract_cli-1.2.5}/tests/test_vector_type.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datacontract-cli
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.5
|
|
4
4
|
Summary: The datacontract CLI is an open source command-line tool for working with Data Contracts. It uses data contract YAML files to lint the data contract, connect to data sources and execute schema and quality tests, detect breaking changes, and export to different formats. The tool is written in Python. It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a Python library.
|
|
5
5
|
Author-email: Jochen Christ <jochen.christ@entropy-data.com>, Stefan Negele <stefan.negele@innoq.com>, Simon Harrer <simon.harrer@entropy-data.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -40,7 +40,7 @@ Requires-Dist: jsonschema<5.0.0,>=4.23.0
|
|
|
40
40
|
Requires-Dist: pytz>=2024.1
|
|
41
41
|
Requires-Dist: python-multipart<1.0.0,>=0.0.20
|
|
42
42
|
Requires-Dist: rich<16.0,>=13.7
|
|
43
|
-
Requires-Dist: sqlglot<
|
|
43
|
+
Requires-Dist: sqlglot<31.0.0,>=26.6.0
|
|
44
44
|
Requires-Dist: python-dotenv<2.0.0,>=1.0.0
|
|
45
45
|
Requires-Dist: boto3<2.0.0,>=1.34.41
|
|
46
46
|
Requires-Dist: Jinja2<4.0.0,>=3.1.5
|
|
@@ -104,7 +104,7 @@ Requires-Dist: duckdb-extension-azure<1.6.0,>=1.5.0; extra == "azure"
|
|
|
104
104
|
Requires-Dist: azure-identity<1.26,>=1.17.1; extra == "azure"
|
|
105
105
|
Requires-Dist: azure-storage-blob<12.31,>=12.24; extra == "azure"
|
|
106
106
|
Provides-Extra: snowflake
|
|
107
|
-
Requires-Dist: snowflake-connector-python[pandas]<4.
|
|
107
|
+
Requires-Dist: snowflake-connector-python[pandas]<4.9,>=3.6; extra == "snowflake"
|
|
108
108
|
Requires-Dist: ibis-framework[snowflake]<13.0.0,>=10.0.0; extra == "snowflake"
|
|
109
109
|
Provides-Extra: sqlserver
|
|
110
110
|
Requires-Dist: ibis-framework[mssql]<13.0.0,>=10.0.0; extra == "sqlserver"
|
|
@@ -141,7 +141,7 @@ Requires-Dist: pyarrow>=18.1.0; extra == "parquet"
|
|
|
141
141
|
Provides-Extra: rdf
|
|
142
142
|
Requires-Dist: rdflib==7.6.0; extra == "rdf"
|
|
143
143
|
Provides-Extra: api
|
|
144
|
-
Requires-Dist: fastapi<0.
|
|
144
|
+
Requires-Dist: fastapi<0.143.0,>=0.115.0; extra == "api"
|
|
145
145
|
Requires-Dist: uvicorn<0.55.0,>=0.44.0; extra == "api"
|
|
146
146
|
Provides-Extra: protobuf
|
|
147
147
|
Requires-Dist: proto-schema-parser<3.0,>=1.0; extra == "protobuf"
|
|
@@ -161,10 +161,10 @@ Requires-Dist: pre-commit<4.7.0,>=3.7.1; extra == "dev"
|
|
|
161
161
|
Requires-Dist: pytest; extra == "dev"
|
|
162
162
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
163
163
|
Requires-Dist: pytest-xdist; extra == "dev"
|
|
164
|
-
Requires-Dist: pymssql==2.4.
|
|
164
|
+
Requires-Dist: pymssql==2.4.2; extra == "dev"
|
|
165
165
|
Requires-Dist: psycopg2-binary<3.0,>=2.9; extra == "dev"
|
|
166
166
|
Requires-Dist: mysql-connector-python<26.8.0,>=8.0.30; extra == "dev"
|
|
167
|
-
Requires-Dist: ruff==0.16.
|
|
167
|
+
Requires-Dist: ruff==0.16.10; extra == "dev"
|
|
168
168
|
Requires-Dist: testcontainers[kafka,minio,mssql,mysql,postgres]==4.15.0; extra == "dev"
|
|
169
169
|
Requires-Dist: trino==0.339.0; extra == "dev"
|
|
170
170
|
Dynamic: license-file
|
|
@@ -183,6 +183,7 @@ Dynamic: license-file
|
|
|
183
183
|
<a href="https://datacontract.com/slack" rel="nofollow"><img src="https://img.shields.io/badge/slack-join_chat-white.svg?logo=slack&style=social" alt="Slack Status" data-canonical-src="https://img.shields.io/badge/slack-join_chat-white.svg?logo=slack&style=social" style="max-width: 100%;"></a>
|
|
184
184
|
</p>
|
|
185
185
|
|
|
186
|
+
**Turn your schemas into data contracts and test your data against them, on Snowflake, Databricks, BigQuery, Kafka, Postgres & 15 more. Open source, built on the Open Data Contract Standard.**
|
|
186
187
|
The `datacontract` CLI is an open-source command-line tool for working with [data contracts](https://datacontract.com).
|
|
187
188
|
It natively supports the [Open Data Contract Standard](https://bitol-io.github.io/open-data-contract-standard/latest/) to lint data contracts, connect to data sources and execute schema and quality tests, and export to different formats.
|
|
188
189
|
The tool is written in Python.
|
|
@@ -256,7 +257,7 @@ Server: production (type=postgres, host=aws-1-eu-central-2.pooler.supabase.com,
|
|
|
256
257
|
│ passed │ Check that field order_total has physical type INTEGER │ orders.order_total │ │
|
|
257
258
|
│ passed │ Check that field order_total has no missing values │ orders.order_total │ │
|
|
258
259
|
╰────────┴───────────────────────────────────────────────────────────────────┴─────────────────────────┴─────────╯
|
|
259
|
-
🟢 Data contract is valid.
|
|
260
|
+
🟢 Data contract is valid. Ran 30 checks. Took 2.504495 seconds.
|
|
260
261
|
```
|
|
261
262
|
|
|
262
263
|
Voilà, the CLI tested that the YAML itself is valid, all records comply with the schema, and all quality attributes are met.
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
<a href="https://datacontract.com/slack" rel="nofollow"><img src="https://img.shields.io/badge/slack-join_chat-white.svg?logo=slack&style=social" alt="Slack Status" data-canonical-src="https://img.shields.io/badge/slack-join_chat-white.svg?logo=slack&style=social" style="max-width: 100%;"></a>
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
|
+
**Turn your schemas into data contracts and test your data against them, on Snowflake, Databricks, BigQuery, Kafka, Postgres & 15 more. Open source, built on the Open Data Contract Standard.**
|
|
15
16
|
The `datacontract` CLI is an open-source command-line tool for working with [data contracts](https://datacontract.com).
|
|
16
17
|
It natively supports the [Open Data Contract Standard](https://bitol-io.github.io/open-data-contract-standard/latest/) to lint data contracts, connect to data sources and execute schema and quality tests, and export to different formats.
|
|
17
18
|
The tool is written in Python.
|
|
@@ -85,7 +86,7 @@ Server: production (type=postgres, host=aws-1-eu-central-2.pooler.supabase.com,
|
|
|
85
86
|
│ passed │ Check that field order_total has physical type INTEGER │ orders.order_total │ │
|
|
86
87
|
│ passed │ Check that field order_total has no missing values │ orders.order_total │ │
|
|
87
88
|
╰────────┴───────────────────────────────────────────────────────────────────┴─────────────────────────┴─────────╯
|
|
88
|
-
🟢 Data contract is valid.
|
|
89
|
+
🟢 Data contract is valid. Ran 30 checks. Took 2.504495 seconds.
|
|
89
90
|
```
|
|
90
91
|
|
|
91
92
|
Voilà, the CLI tested that the YAML itself is valid, all records comply with the schema, and all quality attributes are met.
|
|
@@ -275,6 +275,8 @@ tenants. Send them over HTTPS only.
|
|
|
275
275
|
See [Configuration](https://docs.datacontract.com/configuration) for the full list of options.
|
|
276
276
|
"""
|
|
277
277
|
|
|
278
|
+
# The endpoints are plain `def`, not `async def`: they block on data sources, and FastAPI runs
|
|
279
|
+
# plain functions in a thread pool, so one slow test does not stall every other request.
|
|
278
280
|
app = FastAPI(
|
|
279
281
|
docs_url="/",
|
|
280
282
|
title="Data Contract CLI API",
|
|
@@ -449,7 +451,8 @@ def config_from_headers(headers) -> "Config | None":
|
|
|
449
451
|
→ ``DATACONTRACT_SNOWFLAKE_PASSWORD``, ``entropy-data-api-key`` →
|
|
450
452
|
``ENTROPY_DATA_API_KEY``. Returns None when no config headers are present,
|
|
451
453
|
so env-var-configured deployments behave exactly as before. Unknown
|
|
452
|
-
``datacontract-*`` option names are rejected with a 400
|
|
454
|
+
``datacontract-*`` option names are rejected with a 400, and so is the
|
|
455
|
+
custom quality checks folder.
|
|
453
456
|
"""
|
|
454
457
|
known = known_env_names()
|
|
455
458
|
values = {}
|
|
@@ -457,6 +460,12 @@ def config_from_headers(headers) -> "Config | None":
|
|
|
457
460
|
lowered = name.lower()
|
|
458
461
|
env = lowered.upper().replace("-", "_")
|
|
459
462
|
if lowered.startswith(_CONFIG_HEADER_PREFIX) or env in known:
|
|
463
|
+
if env == "DATACONTRACT_CUSTOM_QUALITY_CHECKS":
|
|
464
|
+
# A folder on the server's disk is the operator's to choose, never the caller's.
|
|
465
|
+
raise HTTPException(
|
|
466
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
467
|
+
detail="The custom quality checks folder is configured by the API server, not per request.",
|
|
468
|
+
)
|
|
460
469
|
values[env] = value
|
|
461
470
|
if not values:
|
|
462
471
|
return None
|
|
@@ -756,7 +765,7 @@ handled. A contract that cannot be parsed is reported the same way, as a failed
|
|
|
756
765
|
response_model_exclude_none=True,
|
|
757
766
|
response_model_exclude_unset=True,
|
|
758
767
|
)
|
|
759
|
-
|
|
768
|
+
def test(
|
|
760
769
|
request: Request,
|
|
761
770
|
body: Annotated[
|
|
762
771
|
str,
|
|
@@ -863,7 +872,7 @@ violation — not as an error status. A `schema` that is not an `http(s)` URL is
|
|
|
863
872
|
},
|
|
864
873
|
},
|
|
865
874
|
)
|
|
866
|
-
|
|
875
|
+
def lint(
|
|
867
876
|
body: Annotated[
|
|
868
877
|
str,
|
|
869
878
|
Body(
|
|
@@ -961,7 +970,7 @@ parsed is answered with `422`.
|
|
|
961
970
|
},
|
|
962
971
|
},
|
|
963
972
|
)
|
|
964
|
-
|
|
973
|
+
def changelog_endpoint(
|
|
965
974
|
body: ChangelogRequest,
|
|
966
975
|
api_key: Annotated[str | None, Depends(api_key_header)] = None,
|
|
967
976
|
) -> ChangelogResponse:
|
|
@@ -15,7 +15,7 @@ from rich.markup import escape
|
|
|
15
15
|
from typer.core import TyperGroup
|
|
16
16
|
from typing_extensions import Annotated
|
|
17
17
|
|
|
18
|
-
from datacontract.config import Config, set_cli_config
|
|
18
|
+
from datacontract.config import Config, cli_config, set_cli_config
|
|
19
19
|
from datacontract.output.output_format import OutputFormat
|
|
20
20
|
|
|
21
21
|
console = Console()
|
|
@@ -31,6 +31,23 @@ inline_references_option = Annotated[
|
|
|
31
31
|
),
|
|
32
32
|
]
|
|
33
33
|
|
|
34
|
+
custom_quality_checks_option = Annotated[
|
|
35
|
+
Optional[Path],
|
|
36
|
+
typer.Option(
|
|
37
|
+
metavar="DIR",
|
|
38
|
+
help="Folder with the custom quality checks the contract's quality rules use, one YAML file per check. "
|
|
39
|
+
"Defaults to DATACONTRACT_CUSTOM_QUALITY_CHECKS.",
|
|
40
|
+
),
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def config_with_custom_quality_checks(custom_quality_checks: Optional[Path]) -> Config | None:
|
|
45
|
+
"""The --config-file config, with the --custom-quality-checks folder if one was given."""
|
|
46
|
+
config = cli_config()
|
|
47
|
+
if custom_quality_checks is None:
|
|
48
|
+
return config
|
|
49
|
+
return Config.resolve(config).model_copy(update={"custom_quality_checks": str(custom_quality_checks)})
|
|
50
|
+
|
|
34
51
|
|
|
35
52
|
# Order in which top-level commands appear in `datacontract --help` (cf. README.md)
|
|
36
53
|
COMMAND_ORDER = [
|
|
@@ -130,6 +147,8 @@ app = typer.Typer(
|
|
|
130
147
|
cls=OrderedCommandsWithMigrationHints,
|
|
131
148
|
no_args_is_help=True,
|
|
132
149
|
add_completion=False,
|
|
150
|
+
# the locals of a --debug traceback can hold credentials
|
|
151
|
+
pretty_exceptions_show_locals=False,
|
|
133
152
|
help="CLI to manage data contracts. Documentation: https://docs.datacontract.com",
|
|
134
153
|
epilog="Read the full documentation at https://docs.datacontract.com",
|
|
135
154
|
)
|
|
@@ -10,14 +10,15 @@ from datacontract.cli import (
|
|
|
10
10
|
_print_logs,
|
|
11
11
|
_print_publish_failure,
|
|
12
12
|
app,
|
|
13
|
+
config_with_custom_quality_checks,
|
|
13
14
|
console,
|
|
15
|
+
custom_quality_checks_option,
|
|
14
16
|
debug_option,
|
|
15
17
|
enable_debug_logging,
|
|
16
18
|
inline_references_option,
|
|
17
19
|
resolve_output_format,
|
|
18
20
|
validate_publish_url,
|
|
19
21
|
)
|
|
20
|
-
from datacontract.config import cli_config
|
|
21
22
|
from datacontract.data_contract import DataContract
|
|
22
23
|
from datacontract.output.ci_output import write_ci_output, write_ci_summary, write_json_results
|
|
23
24
|
from datacontract.output.output_format import OutputFormat
|
|
@@ -80,6 +81,7 @@ def ci(
|
|
|
80
81
|
bool,
|
|
81
82
|
typer.Option(help="SSL verification when publishing the data contract."),
|
|
82
83
|
] = True,
|
|
84
|
+
custom_quality_checks: custom_quality_checks_option = None,
|
|
83
85
|
inline_references: inline_references_option = True,
|
|
84
86
|
debug: debug_option = None,
|
|
85
87
|
):
|
|
@@ -104,6 +106,7 @@ def ci(
|
|
|
104
106
|
# Plain text output for CI logs; --json sends human output to stderr.
|
|
105
107
|
out = Console(stderr=True, no_color=True) if json_output else Console(no_color=True)
|
|
106
108
|
|
|
109
|
+
config = config_with_custom_quality_checks(custom_quality_checks)
|
|
107
110
|
results = []
|
|
108
111
|
fail_results = {
|
|
109
112
|
"warning": {"warning", "failed", "error"},
|
|
@@ -115,7 +118,7 @@ def ci(
|
|
|
115
118
|
for location in locations:
|
|
116
119
|
out.print(f"Testing {location}")
|
|
117
120
|
run = DataContract(
|
|
118
|
-
config=
|
|
121
|
+
config=config,
|
|
119
122
|
data_contract_file=location,
|
|
120
123
|
schema_location=schema,
|
|
121
124
|
publish_url=publish,
|
|
@@ -74,7 +74,29 @@ def _cli_version() -> str:
|
|
|
74
74
|
return "unknown"
|
|
75
75
|
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
# The editor's AI assistant is configured via these environment variables (e.g., in .env).
|
|
78
|
+
# It is enabled when DATACONTRACT_EDITOR_AI_ENDPOINT is set.
|
|
79
|
+
EDITOR_AI_ENV_VARS = {
|
|
80
|
+
"provider": "DATACONTRACT_EDITOR_AI_PROVIDER",
|
|
81
|
+
"endpoint": "DATACONTRACT_EDITOR_AI_ENDPOINT",
|
|
82
|
+
"apiKey": "DATACONTRACT_EDITOR_AI_API_KEY",
|
|
83
|
+
"model": "DATACONTRACT_EDITOR_AI_MODEL",
|
|
84
|
+
"authHeader": "DATACONTRACT_EDITOR_AI_AUTH_HEADER",
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def editor_ai_config() -> dict | None:
|
|
89
|
+
"""Return the editor's AI assistant config from the environment, or None if no endpoint is set."""
|
|
90
|
+
if not os.getenv(EDITOR_AI_ENV_VARS["endpoint"]):
|
|
91
|
+
return None
|
|
92
|
+
ai = {"enabled": True}
|
|
93
|
+
for key, env_var in EDITOR_AI_ENV_VARS.items():
|
|
94
|
+
if os.getenv(env_var):
|
|
95
|
+
ai[key] = os.getenv(env_var)
|
|
96
|
+
return ai
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _generate_index_html(filename: str, ai_config: dict | None = None) -> str:
|
|
78
100
|
"""
|
|
79
101
|
Generate the editor page: load the YAML from the local file API, write it back on
|
|
80
102
|
save, and point the editor's test runner at this server's own /test endpoint.
|
|
@@ -82,8 +104,10 @@ def _generate_index_html(filename: str) -> str:
|
|
|
82
104
|
The editor runs in EMBEDDED mode, since the file menu (New, Load Example, Open)
|
|
83
105
|
makes no sense when the editor is bound to a single local file. The filename is
|
|
84
106
|
shown in the header via titlePrefix, and Cancel reverts to the file on disk.
|
|
107
|
+
The AI assistant is configured if ai_config is given.
|
|
85
108
|
"""
|
|
86
109
|
filename_js = json.dumps(filename)
|
|
110
|
+
ai_option = f"ai: {json.dumps(ai_config)}," if ai_config else ""
|
|
87
111
|
file_api_path = f"/api/files/{quote(filename)}"
|
|
88
112
|
return f"""<!doctype html>
|
|
89
113
|
<html lang="en">
|
|
@@ -136,6 +160,7 @@ def _generate_index_html(filename: str) -> str:
|
|
|
136
160
|
enabled: true,
|
|
137
161
|
dataContractCliApiServerUrl: window.location.origin,
|
|
138
162
|
}},
|
|
163
|
+
{ai_option}
|
|
139
164
|
onCancel: async () => {{
|
|
140
165
|
try {{
|
|
141
166
|
const response = await fetch('{file_api_path}');
|
|
@@ -213,7 +238,7 @@ def create_app(
|
|
|
213
238
|
|
|
214
239
|
@edit_app.get("/", response_class=HTMLResponse, include_in_schema=False)
|
|
215
240
|
def index():
|
|
216
|
-
return _generate_index_html(filename)
|
|
241
|
+
return _generate_index_html(filename, editor_ai_config())
|
|
217
242
|
|
|
218
243
|
@edit_app.get(EDITOR_ASSETS_PATH + "/{asset_path:path}", include_in_schema=False)
|
|
219
244
|
def editor_asset(asset_path: str):
|
|
@@ -337,6 +362,9 @@ def edit(
|
|
|
337
362
|
the data contract tests locally against the servers defined in the data contract.
|
|
338
363
|
Credentials for the data sources must be provided as environment variables, see
|
|
339
364
|
https://docs.datacontract.com/testing
|
|
365
|
+
The editor's AI assistant is enabled by setting DATACONTRACT_EDITOR_AI_ENDPOINT, together with
|
|
366
|
+
DATACONTRACT_EDITOR_AI_API_KEY, DATACONTRACT_EDITOR_AI_MODEL, DATACONTRACT_EDITOR_AI_PROVIDER
|
|
367
|
+
(openai or anthropic), and DATACONTRACT_EDITOR_AI_AUTH_HEADER (bearer, api-key, or x-api-key).
|
|
340
368
|
"""
|
|
341
369
|
enable_debug_logging(debug)
|
|
342
370
|
|
|
@@ -10,7 +10,9 @@ from datacontract.cli import (
|
|
|
10
10
|
_print_logs,
|
|
11
11
|
_print_publish_failure,
|
|
12
12
|
app,
|
|
13
|
+
config_with_custom_quality_checks,
|
|
13
14
|
console,
|
|
15
|
+
custom_quality_checks_option,
|
|
14
16
|
debug_option,
|
|
15
17
|
enable_debug_logging,
|
|
16
18
|
inline_references_option,
|
|
@@ -200,6 +202,7 @@ def test(
|
|
|
200
202
|
bool,
|
|
201
203
|
typer.Option(help="SSL verification when publishing the data contract."),
|
|
202
204
|
] = True,
|
|
205
|
+
custom_quality_checks: custom_quality_checks_option = None,
|
|
203
206
|
inline_references: inline_references_option = True,
|
|
204
207
|
debug: debug_option = None,
|
|
205
208
|
):
|
|
@@ -231,7 +234,7 @@ def test(
|
|
|
231
234
|
if server == "all":
|
|
232
235
|
server = None
|
|
233
236
|
run = DataContract(
|
|
234
|
-
config=
|
|
237
|
+
config=config_with_custom_quality_checks(custom_quality_checks),
|
|
235
238
|
data_contract_file=location,
|
|
236
239
|
schema_location=schema,
|
|
237
240
|
publish_test_results=publish_test_results,
|
|
@@ -13,6 +13,9 @@ logger = logging.getLogger(__name__)
|
|
|
13
13
|
|
|
14
14
|
_ENV_PREFIX = "DATACONTRACT_"
|
|
15
15
|
|
|
16
|
+
# Used by the drivers that would otherwise wait forever for an unresponsive data source.
|
|
17
|
+
DEFAULT_CONNECT_TIMEOUT = 30
|
|
18
|
+
|
|
16
19
|
# Deprecated option (field name) -> replacement (field name). Single source for
|
|
17
20
|
# the accessor warnings, the Snowflake connect synonyms, and the generated docs.
|
|
18
21
|
DEPRECATED_OPTIONS = {
|
|
@@ -110,7 +113,9 @@ class Config(BaseSettings):
|
|
|
110
113
|
|
|
111
114
|
# general
|
|
112
115
|
api_header_authorization: SecretStr | None = None
|
|
116
|
+
custom_quality_checks: str | None = None
|
|
113
117
|
max_errors: int | None = None
|
|
118
|
+
connect_timeout: int | None = None
|
|
114
119
|
|
|
115
120
|
# athena (credentials come from the s3_* options)
|
|
116
121
|
# overrides for the contract's servers block
|
|
@@ -521,10 +526,19 @@ class Config(BaseSettings):
|
|
|
521
526
|
def get_api_header_authorization(self, required: bool = False) -> str | None:
|
|
522
527
|
return self._str_option("api_header_authorization", required)
|
|
523
528
|
|
|
529
|
+
# --- custom quality checks ---
|
|
530
|
+
def get_custom_quality_checks(self) -> str | None:
|
|
531
|
+
return self._str_option("custom_quality_checks")
|
|
532
|
+
|
|
524
533
|
# --- max ---
|
|
525
534
|
def get_max_errors(self) -> int | None:
|
|
526
535
|
return self._int_option("max_errors")
|
|
527
536
|
|
|
537
|
+
# --- connect timeout ---
|
|
538
|
+
def get_connect_timeout(self) -> int:
|
|
539
|
+
"""Seconds to wait for a data source to accept a connection, for drivers that wait forever by default."""
|
|
540
|
+
return self._int_option("connect_timeout") or DEFAULT_CONNECT_TIMEOUT
|
|
541
|
+
|
|
528
542
|
# --- athena ---
|
|
529
543
|
def get_athena_catalog(self, required: bool = False) -> str | None:
|
|
530
544
|
return self._str_option("athena_catalog", required)
|
|
@@ -231,26 +231,56 @@ _DEFERRED_FIELDS = {
|
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
|
|
234
|
-
|
|
234
|
+
# Compared with the value a query returns, so a whole reference keeps the type it reads as.
|
|
235
|
+
_TYPED_FIELDS = {("DataQuality", "mustBe"), ("DataQuality", "mustNotBe")}
|
|
236
|
+
_PLAIN_NUMBER = re.compile(r"-?(0|[1-9][0-9]*)(\.[0-9]+)?")
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def resolve_runtime_variables(
|
|
240
|
+
value, source: str = "contract", variables: Optional[Mapping[str, str]] = None, typed: bool = False
|
|
241
|
+
):
|
|
235
242
|
"""Copy test inputs with variables resolved, recursively, without altering the contract.
|
|
236
243
|
|
|
237
244
|
Handles property names/types, enum values, logical type options, library
|
|
238
245
|
quality arguments, SLA values, and nested array/map definitions. Dictionary
|
|
239
|
-
keys are structural identifiers and are never interpolated.
|
|
246
|
+
keys are structural identifiers and are never interpolated. With ``typed``, a
|
|
247
|
+
value that is one whole reference becomes a number or boolean if its resolved
|
|
248
|
+
text is a plain one (``1000``, ``-2.5``, ``true``); ``007`` stays a string.
|
|
240
249
|
"""
|
|
241
250
|
if isinstance(value, BaseModel):
|
|
242
251
|
owner = type(value).__name__
|
|
243
252
|
updates = {}
|
|
244
253
|
for field in type(value).model_fields:
|
|
245
|
-
if field in _DEFERRED_FIELDS:
|
|
246
|
-
continue
|
|
247
254
|
original = getattr(value, field)
|
|
248
255
|
field_source = f"{source}.{_field_name(field)}"
|
|
249
|
-
|
|
256
|
+
# A custom quality check's arguments are test inputs, like a library metric's.
|
|
257
|
+
if (
|
|
258
|
+
field == "implementation"
|
|
259
|
+
and getattr(value, "engine", None) == "datacontract-cli"
|
|
260
|
+
and isinstance(original, dict)
|
|
261
|
+
and "arguments" in original
|
|
262
|
+
):
|
|
263
|
+
arguments = resolve_runtime_variables(original["arguments"], f"{field_source}.arguments", variables)
|
|
264
|
+
updates[field] = {**original, "arguments": arguments}
|
|
265
|
+
continue
|
|
266
|
+
if field in _DEFERRED_FIELDS:
|
|
267
|
+
continue
|
|
268
|
+
resolved = resolve_runtime_variables(original, field_source, variables, (owner, field) in _TYPED_FIELDS)
|
|
250
269
|
updates[field] = _checked(original, resolved, owner, field, field_source)
|
|
251
270
|
return value.model_copy(update=updates)
|
|
252
271
|
if isinstance(value, dict):
|
|
253
|
-
return {
|
|
272
|
+
return {
|
|
273
|
+
key: resolve_runtime_variables(item, f"{source}.{key}", variables, typed) for key, item in value.items()
|
|
274
|
+
}
|
|
254
275
|
if isinstance(value, list):
|
|
255
|
-
return [
|
|
256
|
-
|
|
276
|
+
return [
|
|
277
|
+
resolve_runtime_variables(item, f"{source}[{index}]", variables, typed) for index, item in enumerate(value)
|
|
278
|
+
]
|
|
279
|
+
resolved = resolve_variables(value, source=source, variables=variables)
|
|
280
|
+
if not typed or not isinstance(value, str) or not _VARIABLE.fullmatch(value):
|
|
281
|
+
return resolved
|
|
282
|
+
if _PLAIN_NUMBER.fullmatch(resolved):
|
|
283
|
+
return float(resolved) if "." in resolved else int(resolved)
|
|
284
|
+
if resolved in ("true", "false"):
|
|
285
|
+
return resolved == "true"
|
|
286
|
+
return resolved
|
|
@@ -32,6 +32,13 @@ from datacontract.model.run import Check, ResultEnum, Run
|
|
|
32
32
|
logger = logging.getLogger(__name__)
|
|
33
33
|
|
|
34
34
|
|
|
35
|
+
def _warning_checks(warnings: list[DataContractException]) -> list[Check]:
|
|
36
|
+
return [
|
|
37
|
+
Check(type=warning.type, result=warning.result, name=warning.name, reason=warning.reason, engine=warning.engine)
|
|
38
|
+
for warning in warnings
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
|
|
35
42
|
def _unrunnable_rule_checks(data_contract: OpenDataContractStandard) -> list[Check]:
|
|
36
43
|
"""Warnings for quality rules `datacontract test` would not be able to run."""
|
|
37
44
|
checks = []
|
|
@@ -150,7 +157,7 @@ class DataContract:
|
|
|
150
157
|
run = Run.create_run()
|
|
151
158
|
try:
|
|
152
159
|
run.log_info("Linting data contract")
|
|
153
|
-
data_contract, schema_version = resolve.
|
|
160
|
+
data_contract, schema_version, warnings = resolve.resolve_data_contract_with_lint_info(
|
|
154
161
|
self._data_contract_file,
|
|
155
162
|
self._data_contract_str,
|
|
156
163
|
self._data_contract,
|
|
@@ -171,6 +178,7 @@ class DataContract:
|
|
|
171
178
|
engine="datacontract-cli",
|
|
172
179
|
)
|
|
173
180
|
)
|
|
181
|
+
run.checks.extend(_warning_checks(warnings))
|
|
174
182
|
run.checks.extend(_unrunnable_rule_checks(data_contract))
|
|
175
183
|
run.dataContractId = data_contract.id
|
|
176
184
|
run.dataContractVersion = data_contract.version
|
|
@@ -221,7 +229,7 @@ class DataContract:
|
|
|
221
229
|
try:
|
|
222
230
|
run.log_info("Testing data contract")
|
|
223
231
|
run.log_info(self._runtime_info())
|
|
224
|
-
data_contract = resolve.
|
|
232
|
+
data_contract, _, warnings = resolve.resolve_data_contract_with_lint_info(
|
|
225
233
|
self._data_contract_file,
|
|
226
234
|
self._data_contract_str,
|
|
227
235
|
self._data_contract,
|
|
@@ -230,6 +238,7 @@ class DataContract:
|
|
|
230
238
|
config=self._config,
|
|
231
239
|
configured_host_only=self._untrusted_contract,
|
|
232
240
|
)
|
|
241
|
+
run.checks.extend(_warning_checks(warnings))
|
|
233
242
|
|
|
234
243
|
execute_data_contract_test(
|
|
235
244
|
data_contract,
|
|
@@ -27,6 +27,7 @@ class MetricType(str, Enum):
|
|
|
27
27
|
MISSING_COUNT = "missing_count"
|
|
28
28
|
DUPLICATE_COUNT = "duplicate_count"
|
|
29
29
|
INVALID_COUNT = "invalid_count"
|
|
30
|
+
MISSING_REFERENCE_COUNT = "missing_reference_count"
|
|
30
31
|
FIELD_PRESENT = "field_present"
|
|
31
32
|
FIELD_TYPE = "field_type"
|
|
32
33
|
FIELD_PHYSICAL_TYPE = "field_physical_type"
|
|
@@ -158,10 +159,14 @@ class CheckSpec:
|
|
|
158
159
|
expected_schema_property: Optional["SchemaProperty"] = None # FIELD_TYPE: structural comparison
|
|
159
160
|
expected_physical_type: Optional[str] = None # FIELD_PHYSICAL_TYPE: contract physicalType
|
|
160
161
|
|
|
161
|
-
columns: Optional[List[str]] = None # DUPLICATE_COUNT across multiple columns
|
|
162
|
+
columns: Optional[List[str]] = None # DUPLICATE_COUNT across multiple columns; MISSING_REFERENCE_COUNT keys
|
|
163
|
+
|
|
164
|
+
referenced_model: Optional[str] = None # MISSING_REFERENCE_COUNT
|
|
165
|
+
referenced_columns: Optional[List[str]] = None # MISSING_REFERENCE_COUNT, pairwise with `columns`
|
|
162
166
|
|
|
163
167
|
query: Optional[str] = None # CUSTOM_SQL (placeholders already substituted)
|
|
164
168
|
dialect: Optional[str] = None # CUSTOM_SQL input SQL dialect
|
|
169
|
+
diagnostics: Optional[dict] = None # CUSTOM_SQL: reported alongside the measured value
|
|
165
170
|
|
|
166
171
|
seconds: Optional[int] = None # FRESHNESS / RETENTION threshold in seconds
|
|
167
172
|
|