datacontract-cli 1.2.5__tar.gz → 1.2.7__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.5/datacontract_cli.egg-info → datacontract_cli-1.2.7}/PKG-INFO +9 -8
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/README.md +3 -2
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/api.py +38 -14
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/breaking/detector.py +39 -37
- datacontract_cli-1.2.7/datacontract/breaking/rules.py +486 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_api.py +11 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_breaking.py +9 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_import.py +4 -3
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/config/settings.py +4 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/config/variables.py +7 -8
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/data_contract.py +29 -7
- datacontract_cli-1.2.7/datacontract/editor_assets/VERSION +1 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/editor_assets/datacontract-editor.css +1 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/editor_assets/datacontract-editor.es.js +10544 -9806
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/checks/check_spec.py +1 -2
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/checks/create_checks.py +77 -103
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/checks/dimensions.py +0 -2
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/checks/type_normalize.py +24 -58
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/data_contract_test.py +84 -19
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/hana/hana_quality_check.py +6 -3
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/hana/hana_schema_check.py +4 -7
- datacontract_cli-1.2.7/datacontract/engines/http_api.py +96 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/ibis_check_execute.py +197 -135
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/jsonschema_exporter.py +2 -2
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/protobuf_exporter.py +3 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/sodacl_check_builder.py +1 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/clickhouse_importer.py +2 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/glue_importer.py +2 -2
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/hive_importer.py +2 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/jsonschema_importer.py +1 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/odata_importer.py +3 -13
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/odcs_helper.py +19 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/openapi_importer.py +86 -33
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/unity_importer.py +3 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/lint/constraints.py +11 -2
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/model/breaking.py +20 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/model/enum_values.py +7 -3
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/output/test_results_writer.py +4 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/output/text_breaking_results.py +3 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7/datacontract_cli.egg-info}/PKG-INFO +9 -8
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract_cli.egg-info/SOURCES.txt +1 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract_cli.egg-info/requires.txt +5 -5
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/pyproject.toml +6 -6
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_api.py +74 -1
- datacontract_cli-1.2.7/tests/test_breaking.py +523 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_breaking_odcs_3_2.py +28 -23
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_config.py +1 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_create_checks_nested.py +12 -3
- datacontract_cli-1.2.7/tests/test_create_checks_nested_type.py +680 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_enum_values.py +54 -2
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_jsonschema.py +21 -2
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_protobuf.py +22 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_hana_quality_check.py +12 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_ibis_check_execute.py +7 -7
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_athena.py +1 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_clickhouse.py +8 -3
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_hive.py +5 -3
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_odata.py +9 -6
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_openapi.py +78 -3
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_lint_odcs_3_2_constraints.py +31 -10
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_map_type.py +2 -2
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_quality_unrunnable_rules.py +1 -1
- datacontract_cli-1.2.7/tests/test_test_api.py +243 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_api_openapi_import.py +1 -44
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_dimension_filter.py +0 -2
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_iceberg.py +1 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_iceberg_rest.py +1 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_local_json.py +36 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_nested_checks.py +1 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_parquet.py +1 -1
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_results_writer.py +6 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_trino.py +59 -0
- datacontract_cli-1.2.5/datacontract/breaking/rules.py +0 -280
- datacontract_cli-1.2.5/datacontract/editor_assets/VERSION +0 -1
- datacontract_cli-1.2.5/tests/test_breaking.py +0 -490
- datacontract_cli-1.2.5/tests/test_create_checks_nested_type.py +0 -475
- datacontract_cli-1.2.5/tests/test_test_api.py +0 -83
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/LICENSE +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/MANIFEST.in +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/__init__.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/breaking/__init__.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/catalog/catalog.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/changelog/__init__.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/changelog/changelog.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/changelog/normalize.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/cli.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_catalog.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_changelog.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_ci.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_dbt.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_edit.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_export.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_init.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_lint.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_publish.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/command_test.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/config/__init__.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/config/cli_context.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/editor_assets/assets/editor.worker-4.7.0.js +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/editor_assets/assets/yaml.worker-4.7.0.js +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/editor_assets/index.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/editor_assets/logo_fuchsia_v2.svg +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/editor_assets/monaco-4.7.0.js +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/editor_assets/odcs.svg +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/editor_assets/robots.txt +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/editor_assets/rolldown-runtime-DY7j01NX.js +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/editor_assets/sitemap.xml +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/__init__.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/checks/__init__.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/checks/check_filter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/checks/custom_quality_check.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/checks/physical_type_match.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/checks/severity.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/checks/sql_guard.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/datacontract/check_azure_blob_file.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/fastjsonschema/check_jsonschema.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/hana/__init__.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/hana/check_hana_execute.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/hana/hana_check_selection.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/hana/hana_connection.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/hana/hana_type_mapping.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/__init__.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/__init__.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/athena_patch.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/aws_credentials.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/connect.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/databricks_patch.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/duckdb_connection.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/exasol_patch.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/hive_patch.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/iceberg.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/kafka.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/oracle_patch.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/redshift_credentials.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/redshift_patch.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/dtype_category.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/native_type.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/engines/ibis/snowflake_structured_types.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/__init__.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/avro_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/avro_idl_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/bigquery_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/custom_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/data_caterer_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/dbml_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/dbt_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/dcs_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/dqx_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/duckdb_type_converter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/excel_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/exporter_factory.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/go_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/great_expectations_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/html_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/iceberg_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/markdown_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/mermaid_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/odcs_v3_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/pandas_type_converter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/pydantic_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/rdf_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/sodacl_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/spark_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/sql_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/sql_type_converter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/sqlalchemy_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/export/xsd_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/athena_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/avro_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/bigquery_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/csv_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/dbml_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/dbt_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/dcs_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/excel_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/iceberg_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/importer_factory.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/json_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/mysql_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/object_storage_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/odcs_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/oracle_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/parquet_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/postgres_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/powerbi_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/protobuf_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/pydantic_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/redshift_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/snowflake_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/spark_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/spark_type_json.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/sql_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/sqlserver_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/trino_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/imports/xsd_importer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/init/init_template.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/integration/dbt_sync.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/integration/dbt_test_mapping.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/integration/entropy_data.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/lint/files.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/lint/resolve.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/lint/resources.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/lint/s3.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/lint/schema.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/lint/urls.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/model/changelog.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/model/exceptions.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/model/map_type.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/model/natural_keys.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/model/odcs.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/model/run.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/model/server.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/model/vector_type.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/model/workbook.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/output/__init__.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/output/ci_output.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/output/json_test_results.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/output/junit_test_results.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/output/output_format.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/output/text_changelog_results.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/py.typed +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/schemas/datacontract-1.2.1.init.yaml +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/schemas/datacontract-1.2.1.schema.json +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/schemas/odcs-3.0.2.schema.json +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/schemas/odcs-3.1.0.schema.json +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/schemas/odcs-3.2.0.init.yaml +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/schemas/odcs-3.2.0.schema.json +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/datacontract.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/datacontract_odcs.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/excel/odcs-template-v3.0.xlsx +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/excel/odcs-template-v3.1.xlsx +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/excel/odcs-template-v3.2.xlsx +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/index.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/macros/authoritative_definitions.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/macros/context.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/macros/schema.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/macros/server.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/macros/support.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials/datacontract_information.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials/datacontract_terms.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials/definition.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials/example.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials/model_field.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials/quality.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials/server.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/context.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/custom_properties.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/diagram.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/dialog_yaml.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/footer.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/fundamentals.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/header.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/pricing.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/roles.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/schema.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/servers.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/sla.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/support.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/team.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/term_of_use.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/title.html +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract/templates/style/output.css +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract_cli.egg-info/dependency_links.txt +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract_cli.egg-info/entry_points.txt +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/datacontract_cli.egg-info/top_level.txt +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/setup.cfg +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_api_concurrency.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_api_openapi.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_catalog.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_changelog.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_changelog_engine.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_changelog_normalize.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_changelog_output_text.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_check_quality_provenance.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_ci_output.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_cli.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_command_api.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_command_api_options.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_config_file.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_config_require.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_config_threading.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_athena.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_bigquery.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_clickhouse.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_databricks.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_exasol.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_hive.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_impala.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_mysql.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_oracle.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_postgres.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_redshift.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_s3_credentials.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_snowflake.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_sqlserver.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_connect_trino.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_create_checks_array_items.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_create_checks_physical_type.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_create_checks_primary_key.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_create_checks_retention_period.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_create_checks_servicelevel.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_create_checks_sql_placeholders.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_custom_quality_checks.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_data_contract.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_data_contract_checks.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_data_contract_specification.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_dbt_sync.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_dbt_test_mapping.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_description_linter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_docs_commands.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_docs_config_options.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_docs_ordering.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_download_datacontract_file.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_dtype_category.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_duckdb_json.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_edit.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_avro.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_avro_idl.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_bigquery.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_complex_data_contract.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_custom.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_custom_exporter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_custom_model.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_data_caterer.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_dbml.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_dbt_models.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_dbt_sources.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_dbt_staging_sql.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_dcs.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_dqx.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_excel.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_go.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_great_expectations.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_html.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_iceberg.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_large_contract.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_markdown.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_mermaid.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_odcs_v3.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_pydantic.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_rdf.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_sodacl.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_spark.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_sql.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_sql_clickhouse.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_sql_query.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_sqlalchemy.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_export_xsd.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_hana_connection.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_hana_schema_check.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_hana_type_mapping.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_ibis_mssql_pattern.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_ibis_mssql_schema.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_ibis_oracle_schema.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_avro.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_bigquery.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_csv.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_dbml.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_dbt.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_excel.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_glue.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_iceberg.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_json.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_jsonschema.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_mysql.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_object_storage.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_odcs_v3.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_oracle.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_parquet.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_postgres.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_powerbi.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_protobuf.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_pydantic_model.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_redshift.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_snowflake.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_spark_type_json.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_sql_clickhouse.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_sql_hive.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_sql_oracle.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_sql_postgres.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_sql_snowflake.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_sql_sqlserver.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_sql_struct.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_sqlserver.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_trino.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_unity_file.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_unmapped_types.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_import_xsd.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_install_extras.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_integration_entropydata.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_lint.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_lint_files.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_lint_schema.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_lint_urls.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_metadata_fields.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_native_type_schema_scope.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_nested_path_checks.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_oracle_patch.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_physical_type_match.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_publish_test_results.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_publish_test_results_payload.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_quality_sql_dialects.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_redshift_credentials.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_redshift_patch.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_resolve.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_resolve_definitions.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_resolve_local_definitions.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_roundtrip_jsonschema.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_roundtrip_pydantic_model.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_roundtrip_xsd.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_row_filter_duplicate_count.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_run_check_deprecated_fields.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_run_check_engine.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_server_overrides.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_server_type_mssql.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_server_type_synonyms.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_servers_3_2_0.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_snowflake_structured_types.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_sql_type_converter_physicaltype.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_array_items.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_athena_iceberg.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_azure_blob_file.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_azure_remote.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_bigquery.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_checks_filter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_clickhouse.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_databricks.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_delta.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_diagnostics.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_dry_run.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_duckdb.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_failed_samples.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_gcs_csv_remote.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_gcs_json_remote.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_hana.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_hive.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_iceberg_s3tables.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_kafka.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_kafka_decoding.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_kafka_remote.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_local_json_nd.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_local_xml.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_metadata_only.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_mysql.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_oracle.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_oracle_xe.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_output_json.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_output_junit.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_postgres.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_quality.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_quality_id_and_tag_filter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_quality_local_fallback.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_quality_percent_severity.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_redshift.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_relationships.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_row_filter.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_s3_csv.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_s3_delta.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_s3_json.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_s3_json_complex.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_s3_json_multiple_files.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_s3_json_multiple_models.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_schema_evolution.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_server_not_found.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_snowflake.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_soda_connection_error.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_sqlserver.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_test_variables.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_type_normalize.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_untrusted_contract.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_untrusted_contract_variables.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/tests/test_variables.py +0 -0
- {datacontract_cli-1.2.5 → datacontract_cli-1.2.7}/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.7
|
|
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
|
|
@@ -29,7 +29,7 @@ Description-Content-Type: text/markdown
|
|
|
29
29
|
License-File: LICENSE
|
|
30
30
|
Requires-Dist: typer<0.28,>=0.18.0
|
|
31
31
|
Requires-Dist: click<9.0.0,>=8.1.0
|
|
32
|
-
Requires-Dist: pydantic<2.
|
|
32
|
+
Requires-Dist: pydantic<2.15.0,>=2.8.2
|
|
33
33
|
Requires-Dist: pydantic-settings<3.0.0,>=2.5.0
|
|
34
34
|
Requires-Dist: pyyaml~=6.0.1
|
|
35
35
|
Requires-Dist: ruamel.yaml<0.20,>=0.17
|
|
@@ -70,7 +70,7 @@ Requires-Dist: rich>=12.4.4; extra == "dataframe"
|
|
|
70
70
|
Provides-Extra: databricks
|
|
71
71
|
Requires-Dist: ibis-framework[databricks]<13.0.0,>=10.0.0; extra == "databricks"
|
|
72
72
|
Requires-Dist: databricks-sql-connector<4.7.0,>=3.7.0; extra == "databricks"
|
|
73
|
-
Requires-Dist: databricks-sdk<0.
|
|
73
|
+
Requires-Dist: databricks-sdk<0.152.0; extra == "databricks"
|
|
74
74
|
Requires-Dist: packaging<27.0,>=21.3; extra == "databricks"
|
|
75
75
|
Provides-Extra: databricks-runtime
|
|
76
76
|
Requires-Dist: datacontract-cli[databricks]; extra == "databricks-runtime"
|
|
@@ -101,7 +101,7 @@ Requires-Dist: datacontract-cli[s3]; extra == "gcs"
|
|
|
101
101
|
Provides-Extra: azure
|
|
102
102
|
Requires-Dist: datacontract-cli[duckdb]; extra == "azure"
|
|
103
103
|
Requires-Dist: duckdb-extension-azure<1.6.0,>=1.5.0; extra == "azure"
|
|
104
|
-
Requires-Dist: azure-identity<1.
|
|
104
|
+
Requires-Dist: azure-identity<1.27,>=1.17.1; extra == "azure"
|
|
105
105
|
Requires-Dist: azure-storage-blob<12.31,>=12.24; extra == "azure"
|
|
106
106
|
Provides-Extra: snowflake
|
|
107
107
|
Requires-Dist: snowflake-connector-python[pandas]<4.9,>=3.6; extra == "snowflake"
|
|
@@ -161,12 +161,12 @@ 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.4; 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
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
|
-
Requires-Dist: trino==0.
|
|
169
|
+
Requires-Dist: trino==0.340.0; extra == "dev"
|
|
170
170
|
Dynamic: license-file
|
|
171
171
|
|
|
172
172
|
# Data Contract CLI
|
|
@@ -195,7 +195,7 @@ It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a P
|
|
|
195
195
|
>
|
|
196
196
|
> Quick links: [Quickstart](https://docs.datacontract.com/quickstart) · [Commands](https://docs.datacontract.com/commands) · [Best Practices](https://docs.datacontract.com/best-practices) · [Custom Export and Import](https://docs.datacontract.com/extending) · [Release Notes](https://docs.datacontract.com/release-notes) · [Development Setup](#development-setup)
|
|
197
197
|
>
|
|
198
|
-
> For LLMs: [docs.datacontract.com/llms.txt](https://docs.datacontract.com/llms.txt) · [docs.datacontract.com/llms-full.txt](https://docs.datacontract.com/llms-full.txt)
|
|
198
|
+
> For LLMs: [docs.datacontract.com/llms.txt](https://docs.datacontract.com/llms.txt) · [docs.datacontract.com/llms-full.txt](https://docs.datacontract.com/llms-full.txt) · [Data Contract Skills](https://github.com/datacontract/datacontract-skills) for coding agents
|
|
199
199
|
|
|
200
200
|
## Getting started
|
|
201
201
|
|
|
@@ -318,7 +318,7 @@ $ datacontract lint odcs.yaml
|
|
|
318
318
|
# show a changelog between two data contracts
|
|
319
319
|
$ datacontract changelog v1.odcs.yaml v2.odcs.yaml
|
|
320
320
|
|
|
321
|
-
# fail when a contract change
|
|
321
|
+
# fail when a contract change breaks a guarantee consumers rely on
|
|
322
322
|
$ datacontract breaking v1.odcs.yaml v2.odcs.yaml
|
|
323
323
|
|
|
324
324
|
# execute schema and quality checks (define credentials as environment variables)
|
|
@@ -356,6 +356,7 @@ if not run.has_passed():
|
|
|
356
356
|
## How to
|
|
357
357
|
|
|
358
358
|
- [How to integrate Data Contract CLI in your CI/CD pipeline as a GitHub Action](https://github.com/datacontract/datacontract-action/)
|
|
359
|
+
- [How to let your coding agent (Claude Code, Codex, GitHub Copilot) create and test data contracts with the Data Contract Skills](https://github.com/datacontract/datacontract-skills)
|
|
359
360
|
- [How to run the Data Contract CLI API to test data contracts with POST requests](https://docs.datacontract.com/api)
|
|
360
361
|
- [How to run Data Contract CLI in a Databricks pipeline](https://www.datamesh-architecture.com/howto/build-a-dataproduct-with-databricks#test-the-data-product)
|
|
361
362
|
|
|
@@ -24,7 +24,7 @@ It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a P
|
|
|
24
24
|
>
|
|
25
25
|
> Quick links: [Quickstart](https://docs.datacontract.com/quickstart) · [Commands](https://docs.datacontract.com/commands) · [Best Practices](https://docs.datacontract.com/best-practices) · [Custom Export and Import](https://docs.datacontract.com/extending) · [Release Notes](https://docs.datacontract.com/release-notes) · [Development Setup](#development-setup)
|
|
26
26
|
>
|
|
27
|
-
> For LLMs: [docs.datacontract.com/llms.txt](https://docs.datacontract.com/llms.txt) · [docs.datacontract.com/llms-full.txt](https://docs.datacontract.com/llms-full.txt)
|
|
27
|
+
> For LLMs: [docs.datacontract.com/llms.txt](https://docs.datacontract.com/llms.txt) · [docs.datacontract.com/llms-full.txt](https://docs.datacontract.com/llms-full.txt) · [Data Contract Skills](https://github.com/datacontract/datacontract-skills) for coding agents
|
|
28
28
|
|
|
29
29
|
## Getting started
|
|
30
30
|
|
|
@@ -147,7 +147,7 @@ $ datacontract lint odcs.yaml
|
|
|
147
147
|
# show a changelog between two data contracts
|
|
148
148
|
$ datacontract changelog v1.odcs.yaml v2.odcs.yaml
|
|
149
149
|
|
|
150
|
-
# fail when a contract change
|
|
150
|
+
# fail when a contract change breaks a guarantee consumers rely on
|
|
151
151
|
$ datacontract breaking v1.odcs.yaml v2.odcs.yaml
|
|
152
152
|
|
|
153
153
|
# execute schema and quality checks (define credentials as environment variables)
|
|
@@ -185,6 +185,7 @@ if not run.has_passed():
|
|
|
185
185
|
## How to
|
|
186
186
|
|
|
187
187
|
- [How to integrate Data Contract CLI in your CI/CD pipeline as a GitHub Action](https://github.com/datacontract/datacontract-action/)
|
|
188
|
+
- [How to let your coding agent (Claude Code, Codex, GitHub Copilot) create and test data contracts with the Data Contract Skills](https://github.com/datacontract/datacontract-skills)
|
|
188
189
|
- [How to run the Data Contract CLI API to test data contracts with POST requests](https://docs.datacontract.com/api)
|
|
189
190
|
- [How to run Data Contract CLI in a Databricks pipeline](https://www.datamesh-architecture.com/howto/build-a-dataproduct-with-databricks#test-the-data-product)
|
|
190
191
|
|
|
@@ -14,7 +14,7 @@ from pydantic import BaseModel, Field, ValidationError
|
|
|
14
14
|
from datacontract.config import Config, known_env_names
|
|
15
15
|
from datacontract.config.variables import CONTRACT_VARIABLES_ENV, allowed_environment, resolve_variables
|
|
16
16
|
from datacontract.data_contract import DataContract, ExportFormat
|
|
17
|
-
from datacontract.model.breaking import BreakingChangeEntry
|
|
17
|
+
from datacontract.model.breaking import BreakingChangeEntry, Perspective
|
|
18
18
|
from datacontract.model.changelog import ChangelogEntry
|
|
19
19
|
from datacontract.model.exceptions import DataContractException, DefinitionResolutionError
|
|
20
20
|
from datacontract.model.run import Check, ResultEnum, Run
|
|
@@ -259,9 +259,10 @@ A posted contract carries SQL and names the hosts to connect to, so the server t
|
|
|
259
259
|
untrusted input: a `quality.type: sql` rule must be a read-only query, a credential held in the
|
|
260
260
|
server's environment is never sent to a host the contract names, a `publish_url` may only point at
|
|
261
261
|
the Entropy Data platform or the host configured via `ENTROPY_DATA_HOST`, and `servers[].type: local`
|
|
262
|
-
is refused so a caller cannot read the server's own files
|
|
263
|
-
`DATACONTRACT_CLI_API_ALLOW_LOCAL_FILES=true` if the deployment
|
|
264
|
-
the contract is then still confined to the paths it declares.
|
|
262
|
+
is refused so a caller cannot read the server's own files, and an `api` server's requests may not
|
|
263
|
+
reach a private network address. Set `DATACONTRACT_CLI_API_ALLOW_LOCAL_FILES=true` if the deployment
|
|
264
|
+
serves its own files on purpose; the contract is then still confined to the paths it declares. Set
|
|
265
|
+
`DATACONTRACT_CLI_API_ALLOW_PRIVATE_NETWORK=true` to test APIs in the server's own network.
|
|
265
266
|
|
|
266
267
|
## Connecting to data sources
|
|
267
268
|
|
|
@@ -525,6 +526,8 @@ _ENVIRONMENT_CREDENTIAL_TARGETS: dict[str, tuple[str, str | None, tuple[str, ...
|
|
|
525
526
|
# option pins it), so an environment-held SASL password can never be paired
|
|
526
527
|
# with a posted contract safely -- host_field is None, so it is always rejected.
|
|
527
528
|
"kafka": ("broker host", None, ("kafka_sasl_password",)),
|
|
529
|
+
# Nothing pins an API server's location either.
|
|
530
|
+
"api": ("location", None, ("api_header_authorization", "api_header_x_api_key")),
|
|
528
531
|
}
|
|
529
532
|
|
|
530
533
|
|
|
@@ -552,6 +555,7 @@ def _selected_server(body: str, server_name: str | None, config):
|
|
|
552
555
|
_LOCAL_SERVER_TYPES = frozenset({"local", "duckdb"})
|
|
553
556
|
|
|
554
557
|
ALLOW_LOCAL_FILES_ENV = "DATACONTRACT_CLI_API_ALLOW_LOCAL_FILES"
|
|
558
|
+
ALLOW_PRIVATE_NETWORK_ENV = "DATACONTRACT_CLI_API_ALLOW_PRIVATE_NETWORK"
|
|
555
559
|
_TRUTHY = frozenset({"1", "true", "yes", "on"})
|
|
556
560
|
|
|
557
561
|
|
|
@@ -570,6 +574,11 @@ def _local_files_allowed() -> bool:
|
|
|
570
574
|
return (os.getenv(ALLOW_LOCAL_FILES_ENV) or "").strip().lower() in _TRUTHY
|
|
571
575
|
|
|
572
576
|
|
|
577
|
+
def _private_network_allowed() -> bool:
|
|
578
|
+
"""Whether the operator lets a posted contract's API requests reach private network addresses."""
|
|
579
|
+
return (os.getenv(ALLOW_PRIVATE_NETWORK_ENV) or "").strip().lower() in _TRUTHY
|
|
580
|
+
|
|
581
|
+
|
|
573
582
|
def _reject_local_server_type(body: str, server_name: str | None, config) -> None:
|
|
574
583
|
"""Keep a posted contract from reading the server's own disk.
|
|
575
584
|
|
|
@@ -623,20 +632,23 @@ def _reject_environment_credentials_to_untrusted_host(body: str, server_name: st
|
|
|
623
632
|
return # no environment-held secret for this server type; nothing to protect
|
|
624
633
|
if host_field is not None and resolved.option_source(host_field) == "env":
|
|
625
634
|
return # the operator pinned the target host; the contract's host is ignored
|
|
635
|
+
held = [
|
|
636
|
+
env_name(field, Config.model_fields[field]) for field in secret_fields if resolved.option_source(field) == "env"
|
|
637
|
+
]
|
|
626
638
|
if host_field is not None:
|
|
627
639
|
env_var = env_name(host_field, Config.model_fields[host_field])
|
|
628
640
|
detail = (
|
|
629
|
-
f"This server holds a {server.type}
|
|
630
|
-
f"{target_attr} must also come from the server's environment ({env_var}); it will not
|
|
631
|
-
f"taken from the posted data contract. Set {env_var}, or send the full set of credentials "
|
|
632
|
-
f"
|
|
641
|
+
f"This server holds a credential for {server.type} servers in its environment ({', '.join(held)}), so the "
|
|
642
|
+
f"connection {target_attr} must also come from the server's environment ({env_var}); it will not "
|
|
643
|
+
f"be taken from the posted data contract. Set {env_var}, or send the full set of credentials with "
|
|
644
|
+
f"the request instead of relying on the server's environment."
|
|
633
645
|
)
|
|
634
646
|
else:
|
|
635
647
|
detail = (
|
|
636
|
-
f"This server holds a {server.type}
|
|
637
|
-
f"can only come from the posted data contract, so the credential cannot be pinned to
|
|
638
|
-
f"trusted target. Send the credentials
|
|
639
|
-
f"
|
|
648
|
+
f"This server holds a credential for {server.type} servers in its environment ({', '.join(held)}), but "
|
|
649
|
+
f"their {target_attr} can only come from the posted data contract, so the credential cannot be pinned to "
|
|
650
|
+
f"a trusted target. Send the credentials as request headers instead "
|
|
651
|
+
f"({', '.join(name.lower().replace('_', '-') for name in held)})."
|
|
640
652
|
)
|
|
641
653
|
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=detail)
|
|
642
654
|
|
|
@@ -835,6 +847,7 @@ def test(
|
|
|
835
847
|
filters=parsed_filters,
|
|
836
848
|
untrusted_contract=untrusted_contract,
|
|
837
849
|
allowed_variables=_allowed_contract_variables(),
|
|
850
|
+
allow_private_network=_private_network_allowed(),
|
|
838
851
|
).test()
|
|
839
852
|
|
|
840
853
|
|
|
@@ -943,6 +956,9 @@ class BreakingChangesResponse(BaseModel):
|
|
|
943
956
|
entries: list[BreakingChangeEntry] = Field(
|
|
944
957
|
description="Every single change with its grade and the old and new value.",
|
|
945
958
|
)
|
|
959
|
+
perspective: Perspective = Field(
|
|
960
|
+
description="Whose expectations the changes were graded against: `consumer` or `producer`.",
|
|
961
|
+
)
|
|
946
962
|
is_breaking: bool = Field(
|
|
947
963
|
description="Whether any detected change is classified as an error-level breaking change.",
|
|
948
964
|
)
|
|
@@ -1006,13 +1022,21 @@ parsed is answered with `422`.
|
|
|
1006
1022
|
def breaking_endpoint(
|
|
1007
1023
|
body: ChangelogRequest,
|
|
1008
1024
|
api_key: Annotated[str | None, Depends(api_key_header)] = None,
|
|
1025
|
+
perspective: Annotated[
|
|
1026
|
+
Perspective,
|
|
1027
|
+
Query(
|
|
1028
|
+
description="`consumer` flags changes that lead to unexpected data for consumers, `producer` flags changes that can make data contract tests fail.",
|
|
1029
|
+
),
|
|
1030
|
+
] = Perspective.CONSUMER,
|
|
1009
1031
|
) -> BreakingChangesResponse:
|
|
1010
1032
|
check_api_key(api_key)
|
|
1011
1033
|
|
|
1012
1034
|
result = DataContract(data_contract_str=body.v1, untrusted_contract=True).breaking(
|
|
1013
|
-
DataContract(data_contract_str=body.v2, untrusted_contract=True)
|
|
1035
|
+
DataContract(data_contract_str=body.v2, untrusted_contract=True), perspective=perspective
|
|
1036
|
+
)
|
|
1037
|
+
return BreakingChangesResponse(
|
|
1038
|
+
summary=result.summary, entries=result.entries, perspective=result.perspective, is_breaking=result.is_breaking
|
|
1014
1039
|
)
|
|
1015
|
-
return BreakingChangesResponse(summary=result.summary, entries=result.entries, is_breaking=result.is_breaking)
|
|
1016
1040
|
|
|
1017
1041
|
|
|
1018
1042
|
@app.post(
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
from collections import defaultdict
|
|
2
2
|
from collections.abc import Iterable
|
|
3
3
|
|
|
4
|
-
from datacontract.breaking.rules import DEFAULT_RULES, BreakingChangeRule
|
|
5
|
-
from datacontract.model.breaking import
|
|
4
|
+
from datacontract.breaking.rules import DEFAULT_RULES, BreakingChangeRule, MetadataFallbackRule
|
|
5
|
+
from datacontract.model.breaking import (
|
|
6
|
+
BreakingChangeEntry,
|
|
7
|
+
BreakingChangeLevel,
|
|
8
|
+
BreakingChangeResult,
|
|
9
|
+
Direction,
|
|
10
|
+
Perspective,
|
|
11
|
+
)
|
|
6
12
|
from datacontract.model.changelog import ChangelogEntry, ChangelogResult, ChangelogType
|
|
7
13
|
|
|
8
14
|
_LEVEL_ORDER = {
|
|
@@ -20,43 +26,22 @@ class BreakingChangeDetector:
|
|
|
20
26
|
if not self._rules:
|
|
21
27
|
raise ValueError("At least one breaking-change rule is required")
|
|
22
28
|
|
|
23
|
-
def detect(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
def detect(
|
|
30
|
+
self, changelog: ChangelogResult, perspective: Perspective, before: dict, after: dict
|
|
31
|
+
) -> BreakingChangeResult:
|
|
32
|
+
"""Grade ``changelog``, built from the normalized contracts ``before`` and ``after``, for ``perspective``."""
|
|
33
|
+
entries = [self._classify(entry, perspective, before, after) for entry in changelog.entries]
|
|
34
|
+
# An added or removed element carries the grade for everything inside it.
|
|
35
|
+
elements = {
|
|
29
36
|
entry.path
|
|
30
37
|
for entry in entries
|
|
31
38
|
if entry.change_type in (ChangelogType.added, ChangelogType.removed)
|
|
32
|
-
and
|
|
33
|
-
entry.path.startswith("schema.")
|
|
34
|
-
and (len(entry.path.split(".")) == 2 or entry.path.split(".")[-2] in ("properties", "quality"))
|
|
35
|
-
)
|
|
36
|
-
}
|
|
37
|
-
removed_enums = {
|
|
38
|
-
entry.path
|
|
39
|
-
for entry in entries
|
|
40
|
-
if entry.change_type == ChangelogType.removed and entry.path.endswith(".enum")
|
|
39
|
+
and entry.rule_id != MetadataFallbackRule.rule_id
|
|
41
40
|
}
|
|
42
|
-
# Stable IDs may change or swap without changing the set of allowed
|
|
43
|
-
# values. Match removed/updated values against additions in the same enum.
|
|
44
|
-
added_values = defaultdict(set)
|
|
45
41
|
for entry in entries:
|
|
46
|
-
if entry.
|
|
47
|
-
|
|
48
|
-
added_values[entry.path.rsplit(".enum.", 1)[0]].add(entry.new_value)
|
|
49
|
-
for entry in entries:
|
|
50
|
-
segments = entry.path.split(".")
|
|
51
|
-
if any(".".join(segments[:i]) in added_or_removed for i in range(1, len(segments))):
|
|
42
|
+
if any(entry.path.startswith(f"{path}.") for path in elements):
|
|
43
|
+
entry.direction = None
|
|
52
44
|
entry.level = BreakingChangeLevel.INFO
|
|
53
|
-
if entry.rule_id == "enum-constraint-changed":
|
|
54
|
-
if any(entry.path.startswith(path + ".") for path in removed_enums):
|
|
55
|
-
entry.level = BreakingChangeLevel.INFO
|
|
56
|
-
elif entry.path.endswith(".value") and entry.old_value in added_values.get(
|
|
57
|
-
entry.path.rsplit(".enum.", 1)[0], set()
|
|
58
|
-
):
|
|
59
|
-
entry.level = BreakingChangeLevel.INFO
|
|
60
45
|
entries_by_prefix = defaultdict(list)
|
|
61
46
|
for entry in entries:
|
|
62
47
|
prefix = ""
|
|
@@ -64,16 +49,33 @@ class BreakingChangeDetector:
|
|
|
64
49
|
prefix = f"{prefix}.{segment}" if prefix else segment
|
|
65
50
|
entries_by_prefix[prefix].append(entry)
|
|
66
51
|
summary = [self._summarize(entry, entries_by_prefix.get(entry.path, [])) for entry in changelog.summary]
|
|
67
|
-
return BreakingChangeResult(
|
|
52
|
+
return BreakingChangeResult(
|
|
53
|
+
v1=changelog.v1, v2=changelog.v2, perspective=perspective, summary=summary, entries=entries
|
|
54
|
+
)
|
|
68
55
|
|
|
69
|
-
def _classify(
|
|
56
|
+
def _classify(
|
|
57
|
+
self, entry: ChangelogEntry, perspective: Perspective, before: dict, after: dict
|
|
58
|
+
) -> BreakingChangeEntry:
|
|
70
59
|
for rule in self._rules:
|
|
71
|
-
evaluation = rule.evaluate(entry)
|
|
60
|
+
evaluation = rule.evaluate(entry, before, after)
|
|
72
61
|
if evaluation is not None:
|
|
62
|
+
direction = evaluation.direction
|
|
63
|
+
if direction == Direction.BOTH:
|
|
64
|
+
level = BreakingChangeLevel.ERROR
|
|
65
|
+
elif direction == Direction.UNDETERMINED:
|
|
66
|
+
level = BreakingChangeLevel.WARNING
|
|
67
|
+
elif (direction, perspective) in (
|
|
68
|
+
(Direction.TIGHTENS, Perspective.PRODUCER),
|
|
69
|
+
(Direction.LOOSENS, Perspective.CONSUMER),
|
|
70
|
+
):
|
|
71
|
+
level = BreakingChangeLevel.ERROR
|
|
72
|
+
else:
|
|
73
|
+
level = BreakingChangeLevel.INFO
|
|
73
74
|
return BreakingChangeEntry(
|
|
74
75
|
path=entry.path,
|
|
75
76
|
change_type=entry.type,
|
|
76
|
-
level=
|
|
77
|
+
level=level,
|
|
78
|
+
direction=direction,
|
|
77
79
|
message=evaluation.message,
|
|
78
80
|
rule_id=evaluation.rule_id,
|
|
79
81
|
old_value=entry.old_value,
|