datacontract-cli 1.2.6__tar.gz → 1.2.8__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.6/datacontract_cli.egg-info → datacontract_cli-1.2.8}/PKG-INFO +32 -27
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/README.md +19 -17
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/api.py +46 -22
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/breaking/detector.py +39 -37
- datacontract_cli-1.2.8/datacontract/breaking/rules.py +616 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/catalog/catalog.py +1 -1
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/changelog/changelog.py +7 -19
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/changelog/normalize.py +74 -2
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/cli.py +3 -3
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_api.py +12 -2
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_breaking.py +9 -1
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_edit.py +59 -9
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_import.py +59 -5
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/config/settings.py +4 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/config/variables.py +7 -8
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/data_contract.py +30 -7
- datacontract_cli-1.2.8/datacontract/editor_assets/VERSION +1 -0
- datacontract_cli-1.2.8/datacontract/editor_assets/assets/editor.worker-4.7.0.js +33 -0
- datacontract_cli-1.2.8/datacontract/editor_assets/assets/yaml.worker-4.7.0.js +476 -0
- datacontract_cli-1.2.8/datacontract/editor_assets/datacontract-editor-version.json +1 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/editor_assets/datacontract-editor.css +1 -1
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/editor_assets/datacontract-editor.es.js +16121 -12358
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/editor_assets/index.html +7 -5
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/editor_assets/monaco-4.7.0.js +9597 -10209
- datacontract_cli-1.2.6/datacontract/editor_assets/rolldown-runtime-DY7j01NX.js → datacontract_cli-1.2.8/datacontract/editor_assets/rolldown-runtime-CEFd7nDs.js +2 -2
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/checks/check_spec.py +1 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/checks/create_checks.py +41 -7
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/checks/custom_quality_check.py +109 -106
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/data_contract_test.py +153 -29
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/hana/check_hana_execute.py +5 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/hana/hana_quality_check.py +17 -4
- datacontract_cli-1.2.8/datacontract/engines/http_api.py +96 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/connect.py +1 -1
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/duckdb_connection.py +118 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/avro_exporter.py +11 -3
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/excel_exporter.py +14 -15
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/markdown_exporter.py +1 -1
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/rdf_exporter.py +1 -1
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/sodacl_check_builder.py +1 -1
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/sql_exporter.py +10 -4
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/avro_importer.py +8 -5
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/excel_importer.py +5 -5
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/odata_importer.py +3 -13
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/odcs_importer.py +2 -1
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/openapi_importer.py +137 -44
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/integration/dbt_sync.py +162 -28
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/integration/dbt_test_mapping.py +2 -1
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/lint/resolve.py +30 -4
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/model/breaking.py +20 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/model/workbook.py +4 -7
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/output/test_results_writer.py +3 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/output/text_breaking_results.py +3 -0
- datacontract_cli-1.2.8/datacontract/templates/excel/odcs-template-v3.2.xlsx +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8/datacontract_cli.egg-info}/PKG-INFO +32 -27
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract_cli.egg-info/SOURCES.txt +6 -1
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract_cli.egg-info/requires.txt +11 -7
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/pyproject.toml +18 -15
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_api.py +74 -1
- datacontract_cli-1.2.8/tests/test_breaking.py +759 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_breaking_odcs_3_2.py +28 -23
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_changelog_engine.py +8 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_changelog_normalize.py +0 -10
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_config.py +1 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_custom_quality_checks.py +106 -53
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_dbt_sync.py +294 -8
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_edit.py +20 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_markdown.py +12 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_rdf.py +18 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_sql.py +29 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_sql_clickhouse.py +37 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_hana_quality_check.py +21 -4
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_avro.py +15 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_excel.py +9 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_odata.py +9 -6
- datacontract_cli-1.2.8/tests/test_import_odcs_v3.py +30 -0
- datacontract_cli-1.2.8/tests/test_import_openapi.py +260 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_resolve.py +91 -1
- datacontract_cli-1.2.8/tests/test_test_api.py +243 -0
- datacontract_cli-1.2.8/tests/test_test_api_endpoints.py +208 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_api_openapi_import.py +1 -44
- datacontract_cli-1.2.8/tests/test_test_local_xlsx.py +190 -0
- datacontract_cli-1.2.8/tests/test_test_s3_xlsx.py +43 -0
- datacontract_cli-1.2.6/datacontract/breaking/rules.py +0 -280
- datacontract_cli-1.2.6/datacontract/editor_assets/VERSION +0 -1
- datacontract_cli-1.2.6/datacontract/editor_assets/assets/editor.worker-4.7.0.js +0 -33
- datacontract_cli-1.2.6/datacontract/editor_assets/assets/yaml.worker-4.7.0.js +0 -452
- datacontract_cli-1.2.6/datacontract/templates/excel/odcs-template-v3.2.xlsx +0 -0
- datacontract_cli-1.2.6/tests/test_breaking.py +0 -490
- datacontract_cli-1.2.6/tests/test_import_odcs_v3.py +0 -11
- datacontract_cli-1.2.6/tests/test_import_openapi.py +0 -138
- datacontract_cli-1.2.6/tests/test_test_api.py +0 -83
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/LICENSE +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/MANIFEST.in +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/__init__.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/breaking/__init__.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/changelog/__init__.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_catalog.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_changelog.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_ci.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_dbt.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_export.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_init.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_lint.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_publish.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/command_test.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/config/__init__.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/config/cli_context.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/editor_assets/logo_fuchsia_v2.svg +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/editor_assets/odcs.svg +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/editor_assets/robots.txt +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/editor_assets/sitemap.xml +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/__init__.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/checks/__init__.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/checks/check_filter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/checks/dimensions.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/checks/physical_type_match.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/checks/severity.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/checks/sql_guard.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/checks/type_normalize.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/datacontract/check_azure_blob_file.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/fastjsonschema/check_jsonschema.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/hana/__init__.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/hana/hana_check_selection.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/hana/hana_connection.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/hana/hana_schema_check.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/hana/hana_type_mapping.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/__init__.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/__init__.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/athena_patch.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/aws_credentials.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/databricks_patch.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/exasol_patch.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/hive_patch.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/iceberg.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/kafka.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/oracle_patch.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/redshift_credentials.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/connections/redshift_patch.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/dtype_category.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/ibis_check_execute.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/native_type.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/engines/ibis/snowflake_structured_types.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/__init__.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/avro_idl_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/bigquery_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/custom_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/data_caterer_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/dbml_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/dbt_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/dcs_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/dqx_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/duckdb_type_converter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/exporter_factory.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/go_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/great_expectations_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/html_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/iceberg_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/jsonschema_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/mermaid_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/odcs_v3_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/pandas_type_converter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/protobuf_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/pydantic_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/sodacl_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/spark_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/sql_type_converter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/sqlalchemy_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/export/xsd_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/athena_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/bigquery_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/clickhouse_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/csv_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/dbml_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/dbt_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/dcs_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/glue_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/hive_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/iceberg_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/importer_factory.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/json_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/jsonschema_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/mysql_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/object_storage_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/odcs_helper.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/oracle_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/parquet_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/postgres_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/powerbi_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/protobuf_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/pydantic_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/redshift_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/snowflake_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/spark_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/spark_type_json.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/sql_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/sqlserver_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/trino_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/unity_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/imports/xsd_importer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/init/init_template.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/integration/entropy_data.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/lint/constraints.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/lint/files.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/lint/resources.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/lint/s3.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/lint/schema.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/lint/urls.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/model/changelog.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/model/enum_values.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/model/exceptions.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/model/map_type.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/model/natural_keys.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/model/odcs.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/model/run.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/model/server.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/model/vector_type.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/output/__init__.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/output/ci_output.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/output/json_test_results.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/output/junit_test_results.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/output/output_format.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/output/text_changelog_results.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/py.typed +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/schemas/datacontract-1.2.1.init.yaml +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/schemas/datacontract-1.2.1.schema.json +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/schemas/odcs-3.0.2.schema.json +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/schemas/odcs-3.1.0.schema.json +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/schemas/odcs-3.2.0.init.yaml +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/schemas/odcs-3.2.0.schema.json +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/datacontract.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/datacontract_odcs.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/excel/odcs-template-v3.0.xlsx +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/excel/odcs-template-v3.1.xlsx +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/index.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/macros/authoritative_definitions.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/macros/context.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/macros/schema.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/macros/server.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/macros/support.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials/datacontract_information.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials/datacontract_terms.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials/definition.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials/example.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials/model_field.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials/quality.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials/server.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/context.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/custom_properties.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/diagram.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/dialog_yaml.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/footer.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/fundamentals.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/header.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/pricing.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/roles.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/schema.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/servers.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/sla.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/support.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/team.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/term_of_use.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/partials_odcs/title.html +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract/templates/style/output.css +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract_cli.egg-info/dependency_links.txt +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract_cli.egg-info/entry_points.txt +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/datacontract_cli.egg-info/top_level.txt +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/setup.cfg +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_api_concurrency.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_api_openapi.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_catalog.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_changelog.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_changelog_output_text.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_check_quality_provenance.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_ci_output.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_cli.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_command_api.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_command_api_options.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_config_file.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_config_require.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_config_threading.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_athena.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_bigquery.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_clickhouse.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_databricks.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_exasol.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_hive.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_impala.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_mysql.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_oracle.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_postgres.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_redshift.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_s3_credentials.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_snowflake.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_sqlserver.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_connect_trino.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_create_checks_array_items.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_create_checks_nested.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_create_checks_nested_type.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_create_checks_physical_type.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_create_checks_primary_key.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_create_checks_retention_period.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_create_checks_servicelevel.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_create_checks_sql_placeholders.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_data_contract.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_data_contract_checks.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_data_contract_specification.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_dbt_test_mapping.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_description_linter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_docs_commands.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_docs_config_options.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_docs_ordering.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_download_datacontract_file.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_dtype_category.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_duckdb_json.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_enum_values.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_avro.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_avro_idl.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_bigquery.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_complex_data_contract.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_custom.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_custom_exporter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_custom_model.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_data_caterer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_dbml.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_dbt_models.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_dbt_sources.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_dbt_staging_sql.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_dcs.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_dqx.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_excel.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_go.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_great_expectations.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_html.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_iceberg.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_jsonschema.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_large_contract.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_mermaid.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_odcs_v3.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_protobuf.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_pydantic.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_sodacl.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_spark.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_sql_query.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_sqlalchemy.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_export_xsd.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_hana_connection.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_hana_schema_check.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_hana_type_mapping.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_ibis_check_execute.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_ibis_mssql_pattern.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_ibis_mssql_schema.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_ibis_oracle_schema.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_athena.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_bigquery.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_clickhouse.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_csv.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_dbml.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_dbt.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_glue.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_hive.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_iceberg.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_json.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_jsonschema.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_mysql.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_object_storage.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_oracle.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_parquet.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_postgres.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_powerbi.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_protobuf.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_pydantic_model.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_redshift.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_snowflake.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_spark_type_json.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_sql_clickhouse.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_sql_hive.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_sql_oracle.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_sql_postgres.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_sql_snowflake.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_sql_sqlserver.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_sql_struct.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_sqlserver.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_trino.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_unity_file.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_unmapped_types.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_import_xsd.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_install_extras.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_integration_entropydata.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_lint.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_lint_files.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_lint_odcs_3_2_constraints.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_lint_schema.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_lint_urls.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_map_type.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_metadata_fields.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_native_type_schema_scope.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_nested_path_checks.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_oracle_patch.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_physical_type_match.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_publish_test_results.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_publish_test_results_payload.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_quality_sql_dialects.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_quality_unrunnable_rules.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_redshift_credentials.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_redshift_patch.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_resolve_definitions.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_resolve_local_definitions.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_roundtrip_jsonschema.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_roundtrip_pydantic_model.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_roundtrip_xsd.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_row_filter_duplicate_count.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_run_check_deprecated_fields.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_run_check_engine.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_server_overrides.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_server_type_mssql.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_server_type_synonyms.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_servers_3_2_0.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_snowflake_structured_types.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_sql_type_converter_physicaltype.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_array_items.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_athena_iceberg.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_azure_blob_file.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_azure_remote.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_bigquery.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_checks_filter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_clickhouse.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_databricks.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_delta.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_diagnostics.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_dimension_filter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_dry_run.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_duckdb.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_failed_samples.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_gcs_csv_remote.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_gcs_json_remote.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_hana.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_hive.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_iceberg.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_iceberg_rest.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_iceberg_s3tables.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_kafka.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_kafka_decoding.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_kafka_remote.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_local_json.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_local_json_nd.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_local_xml.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_metadata_only.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_mysql.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_nested_checks.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_oracle.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_oracle_xe.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_output_json.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_output_junit.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_parquet.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_postgres.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_quality.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_quality_id_and_tag_filter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_quality_local_fallback.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_quality_percent_severity.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_redshift.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_relationships.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_results_writer.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_row_filter.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_s3_csv.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_s3_delta.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_s3_json.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_s3_json_complex.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_s3_json_multiple_files.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_s3_json_multiple_models.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_schema_evolution.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_server_not_found.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_snowflake.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_soda_connection_error.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_sqlserver.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_trino.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_test_variables.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_type_normalize.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_untrusted_contract.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_untrusted_contract_variables.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_variables.py +0 -0
- {datacontract_cli-1.2.6 → datacontract_cli-1.2.8}/tests/test_vector_type.py +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datacontract-cli
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.8
|
|
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
|
|
7
7
|
Project-URL: Homepage, https://cli.datacontract.com
|
|
8
|
-
Project-URL: Documentation, https://
|
|
8
|
+
Project-URL: Documentation, https://cli.datacontract.com
|
|
9
9
|
Project-URL: Repository, https://github.com/datacontract/datacontract-cli
|
|
10
10
|
Project-URL: Issues, https://github.com/datacontract/datacontract-cli/issues
|
|
11
|
-
Project-URL: Changelog, https://
|
|
11
|
+
Project-URL: Changelog, https://cli.datacontract.com/release-notes
|
|
12
12
|
Keywords: data-contract,data-contracts,odcs,open-data-contract-standard,data-quality,data-governance,data-mesh,data-product,data-engineering,schema,dbt,snowflake,databricks,bigquery
|
|
13
13
|
Classifier: Development Status :: 5 - Production/Stable
|
|
14
14
|
Classifier: Environment :: Console
|
|
@@ -47,7 +47,7 @@ Requires-Dist: Jinja2<4.0.0,>=3.1.5
|
|
|
47
47
|
Requires-Dist: jinja_partials<1.0.0,>=0.2.1
|
|
48
48
|
Requires-Dist: datacontract-specification<2.0.0,>=1.2.3
|
|
49
49
|
Requires-Dist: open-data-contract-standard<3.3.0,>=3.2.0
|
|
50
|
-
Requires-Dist: deepdiff<10.0.0,>=
|
|
50
|
+
Requires-Dist: deepdiff<10.0.0,>=8.0.0
|
|
51
51
|
Provides-Extra: avro
|
|
52
52
|
Requires-Dist: avro==1.12.2; extra == "avro"
|
|
53
53
|
Provides-Extra: bigquery
|
|
@@ -59,6 +59,9 @@ Provides-Extra: csv
|
|
|
59
59
|
Requires-Dist: datacontract-cli[duckdb]; extra == "csv"
|
|
60
60
|
Provides-Extra: excel
|
|
61
61
|
Requires-Dist: openpyxl<4.0.0,>=3.1.5; extra == "excel"
|
|
62
|
+
Provides-Extra: xlsx
|
|
63
|
+
Requires-Dist: datacontract-cli[duckdb]; extra == "xlsx"
|
|
64
|
+
Requires-Dist: duckdb-extension-excel<1.6.0,>=1.5.0; extra == "xlsx"
|
|
62
65
|
Provides-Extra: dataframe
|
|
63
66
|
Requires-Dist: ibis-framework<13.0.0,>=10.0.0; extra == "dataframe"
|
|
64
67
|
Requires-Dist: numpy<3,>=1.23.2; extra == "dataframe"
|
|
@@ -70,7 +73,7 @@ Requires-Dist: rich>=12.4.4; extra == "dataframe"
|
|
|
70
73
|
Provides-Extra: databricks
|
|
71
74
|
Requires-Dist: ibis-framework[databricks]<13.0.0,>=10.0.0; extra == "databricks"
|
|
72
75
|
Requires-Dist: databricks-sql-connector<4.7.0,>=3.7.0; extra == "databricks"
|
|
73
|
-
Requires-Dist: databricks-sdk<0.
|
|
76
|
+
Requires-Dist: databricks-sdk<0.154.0; extra == "databricks"
|
|
74
77
|
Requires-Dist: packaging<27.0,>=21.3; extra == "databricks"
|
|
75
78
|
Provides-Extra: databricks-runtime
|
|
76
79
|
Requires-Dist: datacontract-cli[databricks]; extra == "databricks-runtime"
|
|
@@ -102,7 +105,7 @@ Provides-Extra: azure
|
|
|
102
105
|
Requires-Dist: datacontract-cli[duckdb]; extra == "azure"
|
|
103
106
|
Requires-Dist: duckdb-extension-azure<1.6.0,>=1.5.0; extra == "azure"
|
|
104
107
|
Requires-Dist: azure-identity<1.27,>=1.17.1; extra == "azure"
|
|
105
|
-
Requires-Dist: azure-storage-blob<12.
|
|
108
|
+
Requires-Dist: azure-storage-blob<12.32,>=12.24; extra == "azure"
|
|
106
109
|
Provides-Extra: snowflake
|
|
107
110
|
Requires-Dist: snowflake-connector-python[pandas]<4.9,>=3.6; extra == "snowflake"
|
|
108
111
|
Requires-Dist: ibis-framework[snowflake]<13.0.0,>=10.0.0; extra == "snowflake"
|
|
@@ -141,20 +144,20 @@ Requires-Dist: pyarrow>=18.1.0; extra == "parquet"
|
|
|
141
144
|
Provides-Extra: rdf
|
|
142
145
|
Requires-Dist: rdflib==7.6.0; extra == "rdf"
|
|
143
146
|
Provides-Extra: api
|
|
144
|
-
Requires-Dist: fastapi<0.
|
|
147
|
+
Requires-Dist: fastapi<0.144.0,>=0.115.0; extra == "api"
|
|
145
148
|
Requires-Dist: uvicorn<0.55.0,>=0.44.0; extra == "api"
|
|
146
149
|
Provides-Extra: protobuf
|
|
147
150
|
Requires-Dist: proto-schema-parser<3.0,>=1.0; extra == "protobuf"
|
|
148
151
|
Provides-Extra: xml
|
|
149
152
|
Requires-Dist: xmlschema<5.0,>=4.0; extra == "xml"
|
|
150
153
|
Provides-Extra: all
|
|
151
|
-
Requires-Dist: datacontract-cli[api,athena,avro,azure,bigquery,clickhouse,csv,databricks,dataframe,dbml,duckdb,exasol,excel,gcs,hive,iceberg,impala,kafka,mysql,oracle,parquet,postgres,protobuf,rdf,redshift,s3,snowflake,sqlserver,trino,xml]; extra == "all"
|
|
154
|
+
Requires-Dist: datacontract-cli[api,athena,avro,azure,bigquery,clickhouse,csv,databricks,dataframe,dbml,duckdb,exasol,excel,gcs,hive,iceberg,impala,kafka,mysql,oracle,parquet,postgres,protobuf,rdf,redshift,s3,snowflake,sqlserver,trino,xlsx,xml]; extra == "all"
|
|
152
155
|
Provides-Extra: dev
|
|
153
156
|
Requires-Dist: datacontract-cli[all]; extra == "dev"
|
|
154
157
|
Requires-Dist: httpx==0.28.1; extra == "dev"
|
|
155
158
|
Requires-Dist: kafka-python; extra == "dev"
|
|
156
159
|
Requires-Dist: minio==7.2.20; extra == "dev"
|
|
157
|
-
Requires-Dist: moto==5.2.
|
|
160
|
+
Requires-Dist: moto==5.2.4; extra == "dev"
|
|
158
161
|
Requires-Dist: openapi-spec-validator<0.10,>=0.7; extra == "dev"
|
|
159
162
|
Requires-Dist: pandas>=2.1.0; extra == "dev"
|
|
160
163
|
Requires-Dist: pre-commit<4.7.0,>=3.7.1; extra == "dev"
|
|
@@ -164,7 +167,7 @@ Requires-Dist: pytest-xdist; extra == "dev"
|
|
|
164
167
|
Requires-Dist: pymssql==2.4.4; extra == "dev"
|
|
165
168
|
Requires-Dist: psycopg2-binary<3.0,>=2.9; extra == "dev"
|
|
166
169
|
Requires-Dist: mysql-connector-python<26.8.0,>=8.0.30; extra == "dev"
|
|
167
|
-
Requires-Dist: ruff==0.
|
|
170
|
+
Requires-Dist: ruff==0.17.1; extra == "dev"
|
|
168
171
|
Requires-Dist: testcontainers[kafka,minio,mssql,mysql,postgres]==4.15.0; extra == "dev"
|
|
169
172
|
Requires-Dist: trino==0.340.0; extra == "dev"
|
|
170
173
|
Dynamic: license-file
|
|
@@ -191,11 +194,11 @@ It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a P
|
|
|
191
194
|
|
|
192
195
|

|
|
193
196
|
|
|
194
|
-
> 📖 **Full documentation: [
|
|
197
|
+
> 📖 **Full documentation: [cli.datacontract.com](https://cli.datacontract.com)**
|
|
195
198
|
>
|
|
196
|
-
> Quick links: [Quickstart](https://
|
|
199
|
+
> Quick links: [Quickstart](https://cli.datacontract.com/quickstart) · [Commands](https://cli.datacontract.com/commands) · [Best Practices](https://cli.datacontract.com/best-practices) · [Custom Export and Import](https://cli.datacontract.com/extending) · [Release Notes](https://cli.datacontract.com/release-notes) · [Development Setup](#development-setup)
|
|
197
200
|
>
|
|
198
|
-
> For LLMs: [
|
|
201
|
+
> For LLMs: [cli.datacontract.com/llms.txt](https://cli.datacontract.com/llms.txt) · [cli.datacontract.com/llms-full.txt](https://cli.datacontract.com/llms-full.txt) · [Data Contract Skills](https://github.com/datacontract/datacontract-skills) for coding agents
|
|
199
202
|
|
|
200
203
|
## Getting started
|
|
201
204
|
|
|
@@ -269,9 +272,9 @@ $ datacontract import snowflake --source <account> --database ORDER_DB --schema
|
|
|
269
272
|
$ datacontract test datacontract.yaml
|
|
270
273
|
```
|
|
271
274
|
|
|
272
|
-
Copy-paste guides with credentials setup are available for [Snowflake](https://
|
|
275
|
+
Copy-paste guides with credentials setup are available for [Snowflake](https://cli.datacontract.com/testing/snowflake), [BigQuery](https://cli.datacontract.com/testing/bigquery), [Databricks](https://cli.datacontract.com/testing/databricks), and [15+ other sources](https://cli.datacontract.com/testing).
|
|
273
276
|
|
|
274
|
-
We can also use the data contract metadata to export in many [formats](https://
|
|
277
|
+
We can also use the data contract metadata to export in many [formats](https://cli.datacontract.com/exports), e.g., to generate a SQL DDL:
|
|
275
278
|
|
|
276
279
|
```bash
|
|
277
280
|
$ datacontract export sql https://datacontract.com/orders-v1.odcs.yaml
|
|
@@ -318,7 +321,7 @@ $ datacontract lint odcs.yaml
|
|
|
318
321
|
# show a changelog between two data contracts
|
|
319
322
|
$ datacontract changelog v1.odcs.yaml v2.odcs.yaml
|
|
320
323
|
|
|
321
|
-
# fail when a contract change
|
|
324
|
+
# fail when a contract change breaks a guarantee consumers rely on
|
|
322
325
|
$ datacontract breaking v1.odcs.yaml v2.odcs.yaml
|
|
323
326
|
|
|
324
327
|
# execute schema and quality checks (define credentials as environment variables)
|
|
@@ -356,7 +359,8 @@ if not run.has_passed():
|
|
|
356
359
|
## How to
|
|
357
360
|
|
|
358
361
|
- [How to integrate Data Contract CLI in your CI/CD pipeline as a GitHub Action](https://github.com/datacontract/datacontract-action/)
|
|
359
|
-
- [How to
|
|
362
|
+
- [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)
|
|
363
|
+
- [How to run the Data Contract CLI API to test data contracts with POST requests](https://cli.datacontract.com/api)
|
|
360
364
|
- [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
365
|
|
|
362
366
|
|
|
@@ -426,7 +430,7 @@ alias datacontract='docker run --rm -v "${PWD}:/home/datacontract" datacontract/
|
|
|
426
430
|
|
|
427
431
|
_Note:_ The output of Docker command line messages is limited to 80 columns and may include line breaks. Don't pipe docker output to files if you want to export code. Use the `--output` option instead.
|
|
428
432
|
|
|
429
|
-
Released images are signed with [cosign](https://docs.sigstore.dev/cosign/signing/overview/) keyless signing. See [Verifying the image](https://
|
|
433
|
+
Released images are signed with [cosign](https://docs.sigstore.dev/cosign/signing/overview/) keyless signing. See [Verifying the image](https://cli.datacontract.com/installation#verifying-the-image) to check a signature before you run it.
|
|
430
434
|
|
|
431
435
|
|
|
432
436
|
|
|
@@ -454,6 +458,7 @@ A list of available extras:
|
|
|
454
458
|
| DuckDB (local file, CSV import and API response testing) | `pip install datacontract-cli[duckdb]` |
|
|
455
459
|
| Exasol | `pip install datacontract-cli[exasol]` |
|
|
456
460
|
| Excel | `pip install datacontract-cli[excel]` |
|
|
461
|
+
| Excel workbooks (testing) | `pip install datacontract-cli[xlsx]` |
|
|
457
462
|
| GCS | `pip install datacontract-cli[gcs]` |
|
|
458
463
|
| SAP HANA / Datasphere | `pip install datacontract-cli[hana]` (not part of `all`: `hdbcli` is proprietary) |
|
|
459
464
|
| Apache Iceberg (schema import and export, REST catalog testing) | `pip install datacontract-cli[iceberg]` |
|
|
@@ -475,18 +480,18 @@ A list of available extras:
|
|
|
475
480
|
|
|
476
481
|
## Documentation
|
|
477
482
|
|
|
478
|
-
📖 **The full documentation is at [
|
|
483
|
+
📖 **The full documentation is at [cli.datacontract.com](https://cli.datacontract.com).**
|
|
479
484
|
|
|
480
485
|
It covers everything in depth, including the complete command reference:
|
|
481
486
|
|
|
482
|
-
- [Quickstart](https://
|
|
483
|
-
- [Open Data Contract Standard](https://
|
|
484
|
-
- [Test your Data](https://
|
|
485
|
-
- [Define your Quality Rules](https://
|
|
486
|
-
- [Sync with dbt](https://
|
|
487
|
-
- [Imports](https://
|
|
488
|
-
- [API](https://
|
|
489
|
-
- [Command reference](https://
|
|
487
|
+
- [Quickstart](https://cli.datacontract.com/quickstart) — install and run your first test
|
|
488
|
+
- [Open Data Contract Standard](https://cli.datacontract.com/open-data-contract-standard) — the contract format
|
|
489
|
+
- [Test your Data](https://cli.datacontract.com/testing) — schema & quality tests against 18+ data sources
|
|
490
|
+
- [Define your Quality Rules](https://cli.datacontract.com/quality-rules) — SQL, library, text, and custom checks
|
|
491
|
+
- [Sync with dbt](https://cli.datacontract.com/dbt) · [Edit your contract](https://cli.datacontract.com/editor)
|
|
492
|
+
- [Imports](https://cli.datacontract.com/imports) and [Exports](https://cli.datacontract.com/exports) — convert to/from 25+ formats
|
|
493
|
+
- [API](https://cli.datacontract.com/api) and [Python Library](https://cli.datacontract.com/python-library)
|
|
494
|
+
- [Command reference](https://cli.datacontract.com/commands) — `init`, `lint`, `test`, `export`, `import`, `dbt`, `ci`, `catalog`, `publish`, `api`, and more
|
|
490
495
|
|
|
491
496
|
## Development Setup
|
|
492
497
|
|
|
@@ -20,11 +20,11 @@ It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a P
|
|
|
20
20
|
|
|
21
21
|

|
|
22
22
|
|
|
23
|
-
> 📖 **Full documentation: [
|
|
23
|
+
> 📖 **Full documentation: [cli.datacontract.com](https://cli.datacontract.com)**
|
|
24
24
|
>
|
|
25
|
-
> Quick links: [Quickstart](https://
|
|
25
|
+
> Quick links: [Quickstart](https://cli.datacontract.com/quickstart) · [Commands](https://cli.datacontract.com/commands) · [Best Practices](https://cli.datacontract.com/best-practices) · [Custom Export and Import](https://cli.datacontract.com/extending) · [Release Notes](https://cli.datacontract.com/release-notes) · [Development Setup](#development-setup)
|
|
26
26
|
>
|
|
27
|
-
> For LLMs: [
|
|
27
|
+
> For LLMs: [cli.datacontract.com/llms.txt](https://cli.datacontract.com/llms.txt) · [cli.datacontract.com/llms-full.txt](https://cli.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
|
|
|
@@ -98,9 +98,9 @@ $ datacontract import snowflake --source <account> --database ORDER_DB --schema
|
|
|
98
98
|
$ datacontract test datacontract.yaml
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
Copy-paste guides with credentials setup are available for [Snowflake](https://
|
|
101
|
+
Copy-paste guides with credentials setup are available for [Snowflake](https://cli.datacontract.com/testing/snowflake), [BigQuery](https://cli.datacontract.com/testing/bigquery), [Databricks](https://cli.datacontract.com/testing/databricks), and [15+ other sources](https://cli.datacontract.com/testing).
|
|
102
102
|
|
|
103
|
-
We can also use the data contract metadata to export in many [formats](https://
|
|
103
|
+
We can also use the data contract metadata to export in many [formats](https://cli.datacontract.com/exports), e.g., to generate a SQL DDL:
|
|
104
104
|
|
|
105
105
|
```bash
|
|
106
106
|
$ datacontract export sql https://datacontract.com/orders-v1.odcs.yaml
|
|
@@ -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,7 +185,8 @@ 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
|
|
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)
|
|
189
|
+
- [How to run the Data Contract CLI API to test data contracts with POST requests](https://cli.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
|
|
|
191
192
|
|
|
@@ -255,7 +256,7 @@ alias datacontract='docker run --rm -v "${PWD}:/home/datacontract" datacontract/
|
|
|
255
256
|
|
|
256
257
|
_Note:_ The output of Docker command line messages is limited to 80 columns and may include line breaks. Don't pipe docker output to files if you want to export code. Use the `--output` option instead.
|
|
257
258
|
|
|
258
|
-
Released images are signed with [cosign](https://docs.sigstore.dev/cosign/signing/overview/) keyless signing. See [Verifying the image](https://
|
|
259
|
+
Released images are signed with [cosign](https://docs.sigstore.dev/cosign/signing/overview/) keyless signing. See [Verifying the image](https://cli.datacontract.com/installation#verifying-the-image) to check a signature before you run it.
|
|
259
260
|
|
|
260
261
|
|
|
261
262
|
|
|
@@ -283,6 +284,7 @@ A list of available extras:
|
|
|
283
284
|
| DuckDB (local file, CSV import and API response testing) | `pip install datacontract-cli[duckdb]` |
|
|
284
285
|
| Exasol | `pip install datacontract-cli[exasol]` |
|
|
285
286
|
| Excel | `pip install datacontract-cli[excel]` |
|
|
287
|
+
| Excel workbooks (testing) | `pip install datacontract-cli[xlsx]` |
|
|
286
288
|
| GCS | `pip install datacontract-cli[gcs]` |
|
|
287
289
|
| SAP HANA / Datasphere | `pip install datacontract-cli[hana]` (not part of `all`: `hdbcli` is proprietary) |
|
|
288
290
|
| Apache Iceberg (schema import and export, REST catalog testing) | `pip install datacontract-cli[iceberg]` |
|
|
@@ -304,18 +306,18 @@ A list of available extras:
|
|
|
304
306
|
|
|
305
307
|
## Documentation
|
|
306
308
|
|
|
307
|
-
📖 **The full documentation is at [
|
|
309
|
+
📖 **The full documentation is at [cli.datacontract.com](https://cli.datacontract.com).**
|
|
308
310
|
|
|
309
311
|
It covers everything in depth, including the complete command reference:
|
|
310
312
|
|
|
311
|
-
- [Quickstart](https://
|
|
312
|
-
- [Open Data Contract Standard](https://
|
|
313
|
-
- [Test your Data](https://
|
|
314
|
-
- [Define your Quality Rules](https://
|
|
315
|
-
- [Sync with dbt](https://
|
|
316
|
-
- [Imports](https://
|
|
317
|
-
- [API](https://
|
|
318
|
-
- [Command reference](https://
|
|
313
|
+
- [Quickstart](https://cli.datacontract.com/quickstart) — install and run your first test
|
|
314
|
+
- [Open Data Contract Standard](https://cli.datacontract.com/open-data-contract-standard) — the contract format
|
|
315
|
+
- [Test your Data](https://cli.datacontract.com/testing) — schema & quality tests against 18+ data sources
|
|
316
|
+
- [Define your Quality Rules](https://cli.datacontract.com/quality-rules) — SQL, library, text, and custom checks
|
|
317
|
+
- [Sync with dbt](https://cli.datacontract.com/dbt) · [Edit your contract](https://cli.datacontract.com/editor)
|
|
318
|
+
- [Imports](https://cli.datacontract.com/imports) and [Exports](https://cli.datacontract.com/exports) — convert to/from 25+ formats
|
|
319
|
+
- [API](https://cli.datacontract.com/api) and [Python Library](https://cli.datacontract.com/python-library)
|
|
320
|
+
- [Command reference](https://cli.datacontract.com/commands) — `init`, `lint`, `test`, `export`, `import`, `dbt`, `ci`, `catalog`, `publish`, `api`, and more
|
|
319
321
|
|
|
320
322
|
## Development Setup
|
|
321
323
|
|
|
@@ -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
|
|
|
@@ -272,7 +273,7 @@ headers, which are matched case-insensitively and map mechanically to the enviro
|
|
|
272
273
|
Per-request headers are never written to the process environment, so one server can serve several
|
|
273
274
|
tenants. Send them over HTTPS only.
|
|
274
275
|
|
|
275
|
-
See [Configuration](https://
|
|
276
|
+
See [Configuration](https://cli.datacontract.com/configuration) for the full list of options.
|
|
276
277
|
"""
|
|
277
278
|
|
|
278
279
|
# The endpoints are plain `def`, not `async def`: they block on data sources, and FastAPI runs
|
|
@@ -289,7 +290,7 @@ app = FastAPI(
|
|
|
289
290
|
},
|
|
290
291
|
contact={
|
|
291
292
|
"name": "Data Contract CLI",
|
|
292
|
-
"url": "https://
|
|
293
|
+
"url": "https://cli.datacontract.com/",
|
|
293
294
|
},
|
|
294
295
|
# Relative, so the document works for any deployment. A second, absolute entry would
|
|
295
296
|
# show up as a target in the Swagger UI dropdown and invite sending contracts there.
|
|
@@ -300,7 +301,7 @@ app = FastAPI(
|
|
|
300
301
|
"description": "Run the schema and quality tests of a data contract against the actual data.",
|
|
301
302
|
"externalDocs": {
|
|
302
303
|
"description": "Documentation",
|
|
303
|
-
"url": "https://
|
|
304
|
+
"url": "https://cli.datacontract.com/testing/",
|
|
304
305
|
},
|
|
305
306
|
},
|
|
306
307
|
{
|
|
@@ -308,7 +309,7 @@ app = FastAPI(
|
|
|
308
309
|
"description": "Validate that a data contract is syntactically correct and follows the standard.",
|
|
309
310
|
"externalDocs": {
|
|
310
311
|
"description": "Documentation",
|
|
311
|
-
"url": "https://
|
|
312
|
+
"url": "https://cli.datacontract.com/commands/lint",
|
|
312
313
|
},
|
|
313
314
|
},
|
|
314
315
|
{
|
|
@@ -316,7 +317,7 @@ app = FastAPI(
|
|
|
316
317
|
"description": "Convert a data contract into another format, such as SQL DDL, Avro, or dbt.",
|
|
317
318
|
"externalDocs": {
|
|
318
319
|
"description": "Documentation",
|
|
319
|
-
"url": "https://
|
|
320
|
+
"url": "https://cli.datacontract.com/exports/",
|
|
320
321
|
},
|
|
321
322
|
},
|
|
322
323
|
{
|
|
@@ -324,7 +325,7 @@ app = FastAPI(
|
|
|
324
325
|
"description": "Compare two versions of a data contract and list what changed.",
|
|
325
326
|
"externalDocs": {
|
|
326
327
|
"description": "Documentation",
|
|
327
|
-
"url": "https://
|
|
328
|
+
"url": "https://cli.datacontract.com/commands/changelog",
|
|
328
329
|
},
|
|
329
330
|
},
|
|
330
331
|
{
|
|
@@ -332,7 +333,7 @@ app = FastAPI(
|
|
|
332
333
|
"description": "Compare two versions of a data contract and grade each change by compatibility impact.",
|
|
333
334
|
"externalDocs": {
|
|
334
335
|
"description": "Documentation",
|
|
335
|
-
"url": "https://
|
|
336
|
+
"url": "https://cli.datacontract.com/commands/breaking",
|
|
336
337
|
},
|
|
337
338
|
},
|
|
338
339
|
],
|
|
@@ -367,7 +368,7 @@ def _openapi_with_external_docs() -> dict:
|
|
|
367
368
|
"externalDocs",
|
|
368
369
|
{
|
|
369
370
|
"description": "Data Contract CLI documentation",
|
|
370
|
-
"url": "https://
|
|
371
|
+
"url": "https://cli.datacontract.com/api",
|
|
371
372
|
},
|
|
372
373
|
)
|
|
373
374
|
return schema
|
|
@@ -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,
|