datacontract-cli 1.0.8__tar.gz → 1.0.10__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.0.8/datacontract_cli.egg-info → datacontract_cli-1.0.10}/PKG-INFO +11 -8
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/README.md +3 -1
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/cli.py +1 -0
- datacontract_cli-1.0.10/datacontract/command_dbt.py +531 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/checks/check_spec.py +2 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/checks/create_checks.py +33 -2
- datacontract_cli-1.0.10/datacontract/engines/checks/physical_type_match.py +133 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/checks/type_normalize.py +36 -14
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/connections/kafka.py +9 -1
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/dtype_category.py +2 -2
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/ibis_check_execute.py +85 -1
- datacontract_cli-1.0.10/datacontract/engines/ibis/native_type.py +237 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/dbt_exporter.py +5 -1
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/bigquery_importer.py +3 -3
- datacontract_cli-1.0.10/datacontract/integration/dbt_sync.py +2751 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/lint/resolve.py +9 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/model/run.py +9 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10/datacontract_cli.egg-info}/PKG-INFO +11 -8
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract_cli.egg-info/SOURCES.txt +5 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract_cli.egg-info/requires.txt +7 -6
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/pyproject.toml +8 -7
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_ci_output.py +4 -0
- datacontract_cli-1.0.10/tests/test_create_checks_physical_type.py +46 -0
- datacontract_cli-1.0.10/tests/test_dbt_sync.py +2756 -0
- datacontract_cli-1.0.10/tests/test_dtype_category.py +28 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_dbt_models.py +26 -1
- datacontract_cli-1.0.10/tests/test_physical_type_match.py +125 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_kafka.py +57 -2
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_output_json.py +1 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_parquet.py +15 -0
- datacontract_cli-1.0.10/tests/test_test_quality_local_fallback.py +50 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_quality_percent_severity.py +33 -0
- datacontract_cli-1.0.8/datacontract/command_dbt.py +0 -161
- datacontract_cli-1.0.8/datacontract/integration/dbt_sync.py +0 -1215
- datacontract_cli-1.0.8/tests/test_dbt_sync.py +0 -1333
- datacontract_cli-1.0.8/tests/test_test_quality_local_fallback.py +0 -13
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/LICENSE +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/MANIFEST.in +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/__init__.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/api.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/catalog/catalog.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/changelog/__init__.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/changelog/changelog.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/changelog/normalize.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_api.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_catalog.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_changelog.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_ci.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_edit.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_export.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_import.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_init.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_lint.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_publish.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_test.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/data_contract.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/VERSION +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/abap-Bs8kvjsq.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/apex-Dspwrl5m.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/assets/editor.worker-4.7.0.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/assets/yaml.worker-4.7.0.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/azcli-k1BiOau1.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/bat-BIP72KWc.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/bicep-VhQeYhS3.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/cameligo-DnuAXtHg.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/clojure-BAuDPsal.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/coffee-BV06qSnj.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/cpp-Cz8Jeyrf.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/csharp-F6hhlXFb.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/csp-KzlEHCyI.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/css-e4FKntZ3.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/cssMode-BNkTa2xp.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/cypher-CpvDGKRr.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/dart-DdHeFWR0.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/datacontract-editor.css +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/datacontract-editor.es.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/dockerfile-aoNXDcio.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/ecl-C4Q0DYuA.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/elixir-C9X42b0T.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/flow9-Bff42pfB.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/freemarker2-Dyfzmb5A.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/fsharp-C6vPAsHG.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/go-DEr8zx9f.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/graphql-BiNBBRFh.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/handlebars-BtDNI-uC.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/hcl-2T9lKuFg.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/html-Cn4TGw_o.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/htmlMode-Bf84vbo2.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/index.html +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/ini-CZGtssYM.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/java-B260NeH3.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/javascript-B86Kac07.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/jsonMode-Ckgg5lAE.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/julia-kuNLM9c5.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/kotlin-Bz6kAefA.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/less-AZUtS89I.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/lexon-BcmgnyRb.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/liquid-D0NPwuu_.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/logo_fuchsia_v2.svg +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/lua-Dz1RbATg.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/m3-CIMooLFn.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/markdown-C1BsCK9P.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/mdx-QFRSBtVQ.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/mips-BovsnfLQ.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/monaco-4.7.0.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/msdax-CiRB2ZB-.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/mysql-BwdpPE19.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/objective-c-D4nfHfso.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/odcs.svg +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/pascal--j5-PYtz.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/pascaligo-C7TcJxNL.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/perl-BzEWqUb5.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/pgsql-B_KZ0mGX.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/php-A19QHzQV.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/pla-COeKY1hA.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/postiats-BfMp7zJL.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/powerquery-B0TS_5Gb.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/powershell-5jSbKdYB.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/protobuf-YgnOutn3.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/pug-DLej6kn5.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/python-C8RW9B6A.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/qsharp-AhjqtSHB.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/r-D-F4P80w.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/razor-CLZqdY_r.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/redis-hwwIlMnV.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/redshift-Bcm_kjEG.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/restructuredtext-CrdzfPP-.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/ruby-QC2UNm1s.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/rust-5aqiQ3L5.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/sb-B1g1ZfLJ.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/scala-C2U4R5Gb.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/scheme-DeFRbslr.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/scss-RSTCiCmI.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/shell-BpF-iNu8.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/solidity-C00r2mbQ.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/sophia-DVW5ZKDB.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/sparql-B0nmpxeX.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/sql-CJwKPERn.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/st-DPlKG5DT.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/swift-YZBAbVHV.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/systemverilog-CDQSaH63.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/tcl-Dlu8sp6Q.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/tsMode-yleMwhPq.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/twig-C5TO7-kw.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/typescript-CJBeebKU.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/typespec-BsmjDEu7.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/vb-ChHvIDrk.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/wgsl-XEp1ju8c.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/xml-vC-NMVX1.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/yaml-Dlf2VF-T.js +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/__init__.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/checks/__init__.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/data_contract_test.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/datacontract/check_azure_blob_file.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/fastjsonschema/check_jsonschema.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/__init__.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/connections/__init__.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/connections/connect.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/connections/duckdb_connection.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/connections/oracle_patch.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/connections/redshift_patch.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/__init__.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/avro_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/avro_idl_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/bigquery_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/custom_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/data_caterer_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/dbml_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/dcs_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/dqx_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/duckdb_type_converter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/excel_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/exporter_factory.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/go_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/great_expectations_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/html_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/iceberg_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/jsonschema_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/markdown_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/mermaid_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/odcs_export_helper.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/odcs_v3_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/pandas_type_converter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/protobuf_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/pydantic_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/rdf_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/sodacl_check_builder.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/sodacl_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/spark_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/sql_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/sql_type_converter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/sqlalchemy_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/avro_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/csv_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/dbml_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/dbt_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/dcs_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/excel_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/glue_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/iceberg_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/importer_factory.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/json_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/jsonschema_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/odcs_helper.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/odcs_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/parquet_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/powerbi_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/protobuf_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/snowflake_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/spark_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/sql_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/unity_importer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/init/init_template.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/integration/dbt_test_mapping.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/integration/entropy_data.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/lint/files.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/lint/resources.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/lint/schema.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/lint/urls.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/model/changelog.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/model/exceptions.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/model/odcs.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/model/server.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/__init__.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/ci_output.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/json_test_results.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/junit_test_results.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/output_format.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/test_results_writer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/text_changelog_results.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/py.typed +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/datacontract-1.2.1.init.yaml +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/datacontract-1.2.1.schema.json +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/odcs-3.0.1.schema.json +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/odcs-3.0.2.schema.json +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/odcs-3.1.0.init.yaml +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/odcs-3.1.0.schema.json +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/datacontract.html +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/datacontract_odcs.html +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/index.html +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/datacontract_information.html +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/datacontract_terms.html +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/definition.html +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/example.html +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/model_field.html +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/quality.html +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/server.html +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/style/output.css +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract_cli.egg-info/dependency_links.txt +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract_cli.egg-info/entry_points.txt +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract_cli.egg-info/top_level.txt +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/setup.cfg +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_api.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_catalog.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_changelog.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_changelog_engine.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_changelog_normalize.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_changelog_output_text.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_cli.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_connect_databricks.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_connect_sqlserver.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_connect_trino.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_data_contract.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_data_contract_checks.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_data_contract_specification.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_dbt_test_mapping.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_description_linter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_download_datacontract_file.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_duckdb_json.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_edit.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_avro.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_avro_idl.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_bigquery.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_complex_data_contract.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_custom.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_custom_exporter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_custom_model.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_data_caterer.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_dbml.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_dbt_sources.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_dbt_staging_sql.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_dqx.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_excel.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_go.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_great_expectations.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_html.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_iceberg.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_jsonschema.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_markdown.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_mermaid.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_odcs_v3.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_protobuf.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_pydantic.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_rdf.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_sodacl.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_spark.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_sql.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_sql_clickhouse.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_sql_query.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_sqlalchemy.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_ibis_mssql_pattern.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_ibis_oracle_schema.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_avro.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_bigquery.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_csv.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_dbml.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_dbt.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_excel.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_glue.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_iceberg.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_json.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_jsonschema.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_odcs_v3.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_parquet.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_powerbi.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_protobuf.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_snowflake.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_spark.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_sql_oracle.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_sql_postgres.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_sql_snowflake.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_sql_sqlserver.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_unity_file.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_integration_entropydata.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_lint.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_oracle_patch.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_redshift_patch.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_require_env.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_resolve.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_resolve_definitions.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_roundtrip_jsonschema.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_sql_type_converter_physicaltype.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_api.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_athena_iceberg.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_azure_blob_file.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_azure_remote.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_bigquery.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_checks_filter.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_databricks.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_dataframe.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_delta.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_diagnostics.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_failed_samples.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_gcs_csv_remote.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_gcs_json_remote.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_kafka_remote.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_local_json.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_local_json_nd.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_mysql.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_oracle.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_oracle_xe.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_output_junit.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_postgres.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_quality.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_redshift.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_s3_csv.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_s3_delta.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_s3_json.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_s3_json_complex.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_s3_json_multiple_models.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_s3_json_remote.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_schema_evolution.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_server_not_found.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_snowflake.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_soda_connection_error.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_sqlserver.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_trino.py +0 -0
- {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_type_normalize.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datacontract-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.10
|
|
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@innoq.com>, Stefan Negele <stefan.negele@innoq.com>, Simon Harrer <simon.harrer@innoq.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -15,6 +15,7 @@ Requires-Dist: typer<0.27,>=0.18.0
|
|
|
15
15
|
Requires-Dist: click<9.0.0,>=8.1.0
|
|
16
16
|
Requires-Dist: pydantic<2.14.0,>=2.8.2
|
|
17
17
|
Requires-Dist: pyyaml~=6.0.1
|
|
18
|
+
Requires-Dist: ruamel.yaml<0.19,>=0.17
|
|
18
19
|
Requires-Dist: requests<2.35,>=2.31
|
|
19
20
|
Requires-Dist: truststore<1.0,>=0.10
|
|
20
21
|
Requires-Dist: fastjsonschema<2.22.0,>=2.19.1
|
|
@@ -41,7 +42,7 @@ Requires-Dist: openpyxl<4.0.0,>=3.1.5; extra == "excel"
|
|
|
41
42
|
Provides-Extra: databricks
|
|
42
43
|
Requires-Dist: ibis-framework[databricks,pyspark]<13.0.0,>=10.0.0; extra == "databricks"
|
|
43
44
|
Requires-Dist: databricks-sql-connector<4.4.0,>=3.7.0; extra == "databricks"
|
|
44
|
-
Requires-Dist: databricks-sdk<0.
|
|
45
|
+
Requires-Dist: databricks-sdk<0.121.0; extra == "databricks"
|
|
45
46
|
Requires-Dist: pyspark<5.0.0,>=3.5.0; extra == "databricks"
|
|
46
47
|
Provides-Extra: iceberg
|
|
47
48
|
Requires-Dist: pyiceberg==0.11.1; extra == "iceberg"
|
|
@@ -67,7 +68,7 @@ Requires-Dist: duckdb-extension-httpfs<1.6.0,>=1.5.0; extra == "gcs"
|
|
|
67
68
|
Provides-Extra: azure
|
|
68
69
|
Requires-Dist: datacontract-cli[duckdb]; extra == "azure"
|
|
69
70
|
Requires-Dist: duckdb-extension-azure<1.6.0,>=1.5.0; extra == "azure"
|
|
70
|
-
Requires-Dist: azure-identity<1.
|
|
71
|
+
Requires-Dist: azure-identity<1.26,>=1.17.1; extra == "azure"
|
|
71
72
|
Requires-Dist: azure-storage-blob<12.31,>=12.24; extra == "azure"
|
|
72
73
|
Provides-Extra: snowflake
|
|
73
74
|
Requires-Dist: snowflake-connector-python[pandas]<4.7,>=3.6; extra == "snowflake"
|
|
@@ -92,8 +93,8 @@ Requires-Dist: pyarrow>=18.1.0; extra == "parquet"
|
|
|
92
93
|
Provides-Extra: rdf
|
|
93
94
|
Requires-Dist: rdflib==7.6.0; extra == "rdf"
|
|
94
95
|
Provides-Extra: api
|
|
95
|
-
Requires-Dist: fastapi<0.
|
|
96
|
-
Requires-Dist: uvicorn<0.
|
|
96
|
+
Requires-Dist: fastapi<0.140.0,>=0.115.0; extra == "api"
|
|
97
|
+
Requires-Dist: uvicorn<0.51.0,>=0.44.0; extra == "api"
|
|
97
98
|
Provides-Extra: protobuf
|
|
98
99
|
Requires-Dist: proto-schema-parser<3.0,>=1.0; extra == "protobuf"
|
|
99
100
|
Provides-Extra: all
|
|
@@ -111,9 +112,9 @@ Requires-Dist: pytest-xdist; extra == "dev"
|
|
|
111
112
|
Requires-Dist: pymssql==2.3.13; extra == "dev"
|
|
112
113
|
Requires-Dist: psycopg2-binary<3.0,>=2.9; extra == "dev"
|
|
113
114
|
Requires-Dist: mysql-connector-python<9.7.0,>=8.0.30; extra == "dev"
|
|
114
|
-
Requires-Dist: ruff==0.15.
|
|
115
|
+
Requires-Dist: ruff==0.15.20; extra == "dev"
|
|
115
116
|
Requires-Dist: testcontainers[kafka,minio,mssql,mysql,postgres]==4.14.2; extra == "dev"
|
|
116
|
-
Requires-Dist: trino==0.
|
|
117
|
+
Requires-Dist: trino==0.338.0; extra == "dev"
|
|
117
118
|
Dynamic: license-file
|
|
118
119
|
|
|
119
120
|
# Data Contract CLI
|
|
@@ -249,8 +250,10 @@ $ datacontract changelog v1.odcs.yaml v2.odcs.yaml
|
|
|
249
250
|
# execute schema and quality checks (define credentials as environment variables)
|
|
250
251
|
$ datacontract test odcs.yaml
|
|
251
252
|
|
|
252
|
-
# generate dbt tests from a contract into your dbt project
|
|
253
|
+
# generate dbt tests from a contract into your dbt project, then run them
|
|
254
|
+
# (omit the contract to sync/test every *.odcs.yaml in the project)
|
|
253
255
|
$ datacontract dbt sync orders.odcs.yaml --project-dir ./warehouse
|
|
256
|
+
$ datacontract dbt test orders.odcs.yaml --project-dir ./warehouse
|
|
254
257
|
|
|
255
258
|
# export data contract as html (other formats: avro, dbt-models, dbt-sources, dbt-staging-sql, jsonschema, odcs, rdf, sql, sodacl, terraform, ...)
|
|
256
259
|
$ datacontract export html datacontract.yaml --output odcs.html
|
|
@@ -131,8 +131,10 @@ $ datacontract changelog v1.odcs.yaml v2.odcs.yaml
|
|
|
131
131
|
# execute schema and quality checks (define credentials as environment variables)
|
|
132
132
|
$ datacontract test odcs.yaml
|
|
133
133
|
|
|
134
|
-
# generate dbt tests from a contract into your dbt project
|
|
134
|
+
# generate dbt tests from a contract into your dbt project, then run them
|
|
135
|
+
# (omit the contract to sync/test every *.odcs.yaml in the project)
|
|
135
136
|
$ datacontract dbt sync orders.odcs.yaml --project-dir ./warehouse
|
|
137
|
+
$ datacontract dbt test orders.odcs.yaml --project-dir ./warehouse
|
|
136
138
|
|
|
137
139
|
# export data contract as html (other formats: avro, dbt-models, dbt-sources, dbt-staging-sql, jsonschema, odcs, rdf, sql, sodacl, terraform, ...)
|
|
138
140
|
$ datacontract export html datacontract.yaml --output odcs.html
|
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
import typer
|
|
7
|
+
from open_data_contract_standard.model import OpenDataContractStandard
|
|
8
|
+
from typing_extensions import Annotated
|
|
9
|
+
|
|
10
|
+
from datacontract.cli import (
|
|
11
|
+
OrderedCommandsWithMigrationHints,
|
|
12
|
+
console,
|
|
13
|
+
debug_option,
|
|
14
|
+
enable_debug_logging,
|
|
15
|
+
validate_publish_url,
|
|
16
|
+
)
|
|
17
|
+
from datacontract.integration.dbt_sync import (
|
|
18
|
+
ModelResolution,
|
|
19
|
+
_ensure_dbt_project,
|
|
20
|
+
_is_odcs_file,
|
|
21
|
+
_resolve_contract_paths,
|
|
22
|
+
check_dbt_on_path,
|
|
23
|
+
generate_dbt_tests,
|
|
24
|
+
parse_dbt_test_run,
|
|
25
|
+
parse_filename_version,
|
|
26
|
+
resolve_model_names,
|
|
27
|
+
resolve_versioned_target,
|
|
28
|
+
run_dbt_test,
|
|
29
|
+
)
|
|
30
|
+
from datacontract.integration.entropy_data import publish_test_results_to_entropy_data
|
|
31
|
+
from datacontract.lint.resolve import resolve_data_contract
|
|
32
|
+
from datacontract.model.run import ResultEnum, Run
|
|
33
|
+
from datacontract.output.test_results_writer import print_test_results_table, to_field
|
|
34
|
+
|
|
35
|
+
dbt_app = typer.Typer(cls=OrderedCommandsWithMigrationHints, no_args_is_help=True)
|
|
36
|
+
|
|
37
|
+
_RESULT_EMOJI = {
|
|
38
|
+
ResultEnum.passed: "🟢",
|
|
39
|
+
ResultEnum.warning: "🟠",
|
|
40
|
+
ResultEnum.failed: "🔴",
|
|
41
|
+
ResultEnum.error: "🔴",
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass
|
|
46
|
+
class _ContractCtx:
|
|
47
|
+
"""One contract resolved for a `dbt test` run (shared across sync's run path and `dbt test`)."""
|
|
48
|
+
|
|
49
|
+
contract_path: Path
|
|
50
|
+
odcs: OpenDataContractStandard
|
|
51
|
+
model_names: list[str] # effective dbt model names — drive selection and result attribution
|
|
52
|
+
generation_run: Optional[Run] # set on sync's --run-tests path, None on `dbt test`
|
|
53
|
+
dbt_version: Optional[str] = None # filename-derived dbt model version, when this contract is versioned
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass
|
|
57
|
+
class _Owner:
|
|
58
|
+
path: Path
|
|
59
|
+
contract_id: Optional[str]
|
|
60
|
+
contract_version: str
|
|
61
|
+
dbt_version: Optional[str] # filename-derived version, None if the contract can't map to one
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _check_model_ownership(owners_by_model: dict) -> None:
|
|
65
|
+
"""Hard-error unless every model shared by multiple contracts is a clean version group.
|
|
66
|
+
|
|
67
|
+
A shared model is allowed only when its owners are versions of the *same* contract: one
|
|
68
|
+
`odcs.id`, distinct `version`s, and each with a filename `v<N>` that maps to a dbt model version.
|
|
69
|
+
"""
|
|
70
|
+
errors: list[str] = []
|
|
71
|
+
for model, owners in owners_by_model.items():
|
|
72
|
+
if len(owners) < 2:
|
|
73
|
+
continue
|
|
74
|
+
ids = {o.contract_id for o in owners}
|
|
75
|
+
versions = [o.contract_version for o in owners]
|
|
76
|
+
if len(ids) > 1:
|
|
77
|
+
listed = ", ".join(f"{o.path.name} ({o.contract_id})" for o in owners)
|
|
78
|
+
errors.append(
|
|
79
|
+
f" - `{model}` is claimed by different contracts. If those are versions of the same contract, make sure they have the same ID: {listed}"
|
|
80
|
+
)
|
|
81
|
+
elif len(set(versions)) != len(versions):
|
|
82
|
+
errors.append(f" - `{model}`: Two contracts share ID `{next(iter(ids))}` and version `{versions[0]}`.")
|
|
83
|
+
elif any(o.dbt_version is None for o in owners):
|
|
84
|
+
listed = ", ".join(o.path.name for o in owners if o.dbt_version is None)
|
|
85
|
+
errors.append(
|
|
86
|
+
f" - `{model}` is claimed by different contracts. If those are versions of the same contract, "
|
|
87
|
+
f"rename the files to contain the version number followed by the letter `v`, e.g. `my-contract-v1.odcs.yaml`: {listed}"
|
|
88
|
+
)
|
|
89
|
+
if errors:
|
|
90
|
+
console.print("[red]Cannot sync — overlapping dbt models:\n" + "\n".join(errors) + "[/red]")
|
|
91
|
+
raise typer.Exit(code=1)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _validate_server_declared(odcs, server: Optional[str]) -> None:
|
|
95
|
+
"""Reject a `--server` that the contract doesn't declare."""
|
|
96
|
+
if server is None:
|
|
97
|
+
return
|
|
98
|
+
known = [s.server for s in odcs.servers or [] if s.server]
|
|
99
|
+
if server not in known:
|
|
100
|
+
console.print(
|
|
101
|
+
f"[red]--server {server!r} is not declared in the contract. Available: {', '.join(known) or '(none)'}[/red]"
|
|
102
|
+
)
|
|
103
|
+
raise typer.Exit(code=1)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _maybe_publish(run: Run, odcs, publish: Optional[str], ssl_verification: bool) -> bool:
|
|
107
|
+
"""Publish the run if requested; return True if a publish was attempted and failed."""
|
|
108
|
+
if publish is None:
|
|
109
|
+
return False
|
|
110
|
+
if run.server is None:
|
|
111
|
+
if not odcs.servers:
|
|
112
|
+
console.print(
|
|
113
|
+
"[yellow]Skipping publish: the contract declares no servers. "
|
|
114
|
+
"Add a `servers:` block to identify the run.[/yellow]"
|
|
115
|
+
)
|
|
116
|
+
else:
|
|
117
|
+
known = ", ".join(s.server for s in odcs.servers if s.server) or "(none)"
|
|
118
|
+
console.print(
|
|
119
|
+
f"[yellow]Skipping publish: the contract declares multiple servers ({known}). "
|
|
120
|
+
f"Pass --server to identify the run.[/yellow]"
|
|
121
|
+
)
|
|
122
|
+
return False
|
|
123
|
+
return not publish_test_results_to_entropy_data(run, publish, ssl_verification)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _report_run(run: Run, *, run_only: bool, publish_failed: bool, ctx: _ContractCtx) -> bool:
|
|
127
|
+
"""Print one contract's results; return True if it should fail the invocation."""
|
|
128
|
+
console.print(f"\n[bold]Contract {run.dataContractId}@{run.dataContractVersion}[/bold] — {ctx.contract_path}")
|
|
129
|
+
if not run.checks:
|
|
130
|
+
if run_only:
|
|
131
|
+
console.print(
|
|
132
|
+
"[yellow]No managed tests found. Run `datacontract dbt sync` first to "
|
|
133
|
+
"generate tests from your contract.[/yellow]"
|
|
134
|
+
)
|
|
135
|
+
else:
|
|
136
|
+
console.print("[yellow]No tests ran for this contract.[/yellow]")
|
|
137
|
+
return publish_failed
|
|
138
|
+
|
|
139
|
+
print_test_results_table(run, console)
|
|
140
|
+
total = len(run.checks)
|
|
141
|
+
took = (run.timestampEnd - run.timestampStart).total_seconds()
|
|
142
|
+
if run.result == ResultEnum.passed:
|
|
143
|
+
console.print(f"🟢 dbt tests passed. Ran {total} tests. Took {took} seconds.")
|
|
144
|
+
return publish_failed
|
|
145
|
+
if run.result == ResultEnum.warning:
|
|
146
|
+
console.print("🟠 dbt tests have warnings:")
|
|
147
|
+
else:
|
|
148
|
+
console.print("🔴 dbt tests failed, found the following errors:")
|
|
149
|
+
i = 1
|
|
150
|
+
for check in run.checks:
|
|
151
|
+
if check.result not in (None, ResultEnum.passed):
|
|
152
|
+
field = to_field(run, check)
|
|
153
|
+
prefix = f"{field} " if field else ""
|
|
154
|
+
console.print(f"{i}) {prefix}{check.name}: {check.reason}")
|
|
155
|
+
i += 1
|
|
156
|
+
return run.result in (ResultEnum.failed, ResultEnum.error) or publish_failed
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def _rel(path: Path, project_dir: Path) -> str:
|
|
160
|
+
try:
|
|
161
|
+
return str(path.relative_to(project_dir))
|
|
162
|
+
except ValueError:
|
|
163
|
+
return str(path)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _count(n: int, noun: str) -> str:
|
|
167
|
+
return f"{n} {noun}" + ("" if n == 1 else "s")
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# List filenames individually up to this many; beyond it, truncate with "... and N more".
|
|
171
|
+
_MAX_LISTED_FILES = 5
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _print_sync_summary(gen, project_dir: Path, *, debug: bool = False) -> None:
|
|
175
|
+
"""Print the per-contract sync summary, naming the touched files."""
|
|
176
|
+
prefix = f"{gen.contract_path.name}: "
|
|
177
|
+
line = f"{prefix}Synced {_count(len(gen.resolved_models), 'model')}: updated {_count(len(gen.written_yaml), 'YAML file')}"
|
|
178
|
+
if gen.written_sql:
|
|
179
|
+
line += f", wrote {_count(len(gen.written_sql), 'singular SQL test')}"
|
|
180
|
+
if gen.deleted_files:
|
|
181
|
+
line += f", removed {_count(len(gen.deleted_files), 'YAML file')}"
|
|
182
|
+
console.print(line + ".")
|
|
183
|
+
|
|
184
|
+
entries = (
|
|
185
|
+
[f"~ {_rel(p, project_dir)}" for p in gen.written_yaml]
|
|
186
|
+
+ [f"+ {_rel(p, project_dir)}" for p in gen.written_sql]
|
|
187
|
+
+ [f"- {_rel(p, project_dir)}" for p in gen.deleted_files]
|
|
188
|
+
)
|
|
189
|
+
shown = entries if debug else entries[:_MAX_LISTED_FILES]
|
|
190
|
+
for entry in shown:
|
|
191
|
+
console.print(f" {entry}")
|
|
192
|
+
if len(entries) > len(shown):
|
|
193
|
+
console.print(f" ... and {len(entries) - len(shown)} more [dim](pass --debug to show all)[/dim]")
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _warn_prunable(gen, project_dir: Path) -> None:
|
|
197
|
+
"""Warn that the project has contract-absent columns/tags `--prune` would remove (it wasn't passed)."""
|
|
198
|
+
if not gen.prunable:
|
|
199
|
+
return
|
|
200
|
+
prefix = f"{gen.contract_path.name}: "
|
|
201
|
+
shown = gen.prunable[:_MAX_LISTED_FILES]
|
|
202
|
+
console.print(
|
|
203
|
+
f"[yellow]{prefix}{_count(len(gen.prunable), 'item')} in the project "
|
|
204
|
+
f"{'is' if len(gen.prunable) == 1 else 'are'} not declared in the contract; "
|
|
205
|
+
"pass --prune to remove:[/yellow]"
|
|
206
|
+
)
|
|
207
|
+
for item in shown:
|
|
208
|
+
console.print(f"[yellow] - {item}[/yellow]")
|
|
209
|
+
if len(gen.prunable) > len(shown):
|
|
210
|
+
console.print(f"[yellow] ... and {len(gen.prunable) - len(shown)} more[/yellow]")
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def _run_and_report(
|
|
214
|
+
ctxs: list[_ContractCtx],
|
|
215
|
+
project_dir: Path,
|
|
216
|
+
*,
|
|
217
|
+
target: Optional[str],
|
|
218
|
+
profiles_dir: Optional[Path],
|
|
219
|
+
publish: Optional[str],
|
|
220
|
+
server: Optional[str],
|
|
221
|
+
ssl_verification: bool,
|
|
222
|
+
error_rows: list[tuple[Path, str]],
|
|
223
|
+
multiple_contracts: bool,
|
|
224
|
+
) -> bool:
|
|
225
|
+
"""Run `dbt test` once (scoped to all requested contracts' models), then report per contract.
|
|
226
|
+
|
|
227
|
+
Returns True if the invocation should exit non-zero.
|
|
228
|
+
"""
|
|
229
|
+
model_versions = sorted(
|
|
230
|
+
{(m, c.dbt_version, str(c.odcs.version or "no_version")) for c in ctxs for m in c.model_names},
|
|
231
|
+
key=lambda t: (t[0], t[1] or "", t[2]),
|
|
232
|
+
)
|
|
233
|
+
if model_versions:
|
|
234
|
+
completed = run_dbt_test(project_dir, target=target, profiles_dir=profiles_dir, model_versions=model_versions)
|
|
235
|
+
else:
|
|
236
|
+
completed = subprocess.CompletedProcess(args=[], returncode=0, stdout="", stderr="")
|
|
237
|
+
|
|
238
|
+
any_failed = bool(error_rows)
|
|
239
|
+
footer: list[tuple[str, str, str]] = []
|
|
240
|
+
for c in ctxs:
|
|
241
|
+
model_filter: set[str] = {m.lower() for m in c.model_names}
|
|
242
|
+
run = parse_dbt_test_run(
|
|
243
|
+
project_dir, c.odcs, completed, model_filter=model_filter, generation_run=c.generation_run
|
|
244
|
+
)
|
|
245
|
+
if server is not None:
|
|
246
|
+
run.server = server
|
|
247
|
+
elif c.odcs.servers and len(c.odcs.servers) == 1:
|
|
248
|
+
run.server = c.odcs.servers[0].server
|
|
249
|
+
else:
|
|
250
|
+
run.server = target
|
|
251
|
+
publish_failed = _maybe_publish(run, c.odcs, publish, ssl_verification)
|
|
252
|
+
failed = _report_run(
|
|
253
|
+
run,
|
|
254
|
+
run_only=(c.generation_run is None),
|
|
255
|
+
publish_failed=publish_failed,
|
|
256
|
+
ctx=c,
|
|
257
|
+
)
|
|
258
|
+
any_failed = any_failed or failed
|
|
259
|
+
label = f"{run.dataContractId}@{run.dataContractVersion}"
|
|
260
|
+
if not run.checks:
|
|
261
|
+
footer.append(("⚪", label, "no tests"))
|
|
262
|
+
else:
|
|
263
|
+
footer.append((_RESULT_EMOJI.get(run.result, "🔴"), label, run.result.value))
|
|
264
|
+
|
|
265
|
+
for path, msg in error_rows:
|
|
266
|
+
console.print(f"[red]🔴 {path}: {msg}[/red]")
|
|
267
|
+
footer.append(("🔴", str(path), "error"))
|
|
268
|
+
|
|
269
|
+
if multiple_contracts:
|
|
270
|
+
# Render the per-contract status block + tally.
|
|
271
|
+
console.print("\n[bold]Contract results:[/bold]")
|
|
272
|
+
for emoji, label, status in footer:
|
|
273
|
+
console.print(f" {emoji} {label} — {status}")
|
|
274
|
+
tally = {}
|
|
275
|
+
for _, _, status in footer:
|
|
276
|
+
tally[status] = tally.get(status, 0) + 1
|
|
277
|
+
summary = " · ".join(f"{n} {status}" for status, n in tally.items())
|
|
278
|
+
console.print(f"Tested {len(footer)} contract(s): {summary}.")
|
|
279
|
+
return any_failed
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
@dbt_app.command(
|
|
283
|
+
name="sync",
|
|
284
|
+
epilog="Example: datacontract dbt sync orders.odcs.yaml --project-dir ./warehouse",
|
|
285
|
+
)
|
|
286
|
+
def sync_command(
|
|
287
|
+
contract: Annotated[
|
|
288
|
+
Optional[list[str]],
|
|
289
|
+
typer.Argument(
|
|
290
|
+
help="Path(s) or glob(s) of ODCS contracts to sync. If omitted, syncs every `*.odcs.yaml` "
|
|
291
|
+
"under --project-dir (default: current directory) and its subdirectories.",
|
|
292
|
+
),
|
|
293
|
+
] = None,
|
|
294
|
+
project_dir: Annotated[
|
|
295
|
+
Optional[Path],
|
|
296
|
+
typer.Option(
|
|
297
|
+
help="Path to the dbt project root (must contain `dbt_project.yml`). Defaults to the current directory."
|
|
298
|
+
),
|
|
299
|
+
] = None,
|
|
300
|
+
schema_name: Annotated[
|
|
301
|
+
str,
|
|
302
|
+
typer.Option(help="Which ODCS schema object to sync, by name."),
|
|
303
|
+
] = "all",
|
|
304
|
+
model_resolution: Annotated[
|
|
305
|
+
ModelResolution,
|
|
306
|
+
typer.Option(help="How to map an ODCS schema to a dbt model name."),
|
|
307
|
+
] = ModelResolution.name,
|
|
308
|
+
target: Annotated[Optional[str], typer.Option(help="Forwarded to `dbt test --target`.")] = None,
|
|
309
|
+
profiles_dir: Annotated[
|
|
310
|
+
Optional[Path],
|
|
311
|
+
typer.Option(help="Forwarded to `dbt test --profiles-dir`."),
|
|
312
|
+
] = None,
|
|
313
|
+
prune: Annotated[
|
|
314
|
+
bool,
|
|
315
|
+
typer.Option(help="Remove model columns and tags that are not declared in the contract."),
|
|
316
|
+
] = False,
|
|
317
|
+
run_tests_flag: Annotated[
|
|
318
|
+
bool,
|
|
319
|
+
typer.Option(
|
|
320
|
+
"--run-tests/--skip-tests",
|
|
321
|
+
help="Run `dbt test` on the generated tests after syncing. Default: skip (generate only).",
|
|
322
|
+
),
|
|
323
|
+
] = False,
|
|
324
|
+
publish: Annotated[Optional[str], typer.Option(help="The url to publish the results after the test.")] = None,
|
|
325
|
+
server: Annotated[
|
|
326
|
+
Optional[str],
|
|
327
|
+
typer.Option(
|
|
328
|
+
help="Selected ODCS server. Determines the dialect for data types and for the server label when publishing results. Default: Auto-selected if only one server exists, else --target.",
|
|
329
|
+
),
|
|
330
|
+
] = None,
|
|
331
|
+
ssl_verification: Annotated[bool, typer.Option(help="SSL verification when publishing test results.")] = True,
|
|
332
|
+
debug: debug_option = None,
|
|
333
|
+
):
|
|
334
|
+
"""
|
|
335
|
+
Generate dbt tests and model metadata from one or more ODCS contracts.
|
|
336
|
+
|
|
337
|
+
Modifies the existing dbt model YAML in place (preserving comments and formatting), and creates new model YAML files
|
|
338
|
+
or singular SQL tests if needed. Use `datacontract dbt test` or pass --run-tests to run the generated tests.
|
|
339
|
+
"""
|
|
340
|
+
enable_debug_logging(debug)
|
|
341
|
+
validate_publish_url(publish)
|
|
342
|
+
|
|
343
|
+
if publish is not None and not run_tests_flag:
|
|
344
|
+
console.print("[red]--publish requires --run-tests.[/red]")
|
|
345
|
+
raise typer.Exit(code=1)
|
|
346
|
+
|
|
347
|
+
explicit_project_dir = project_dir is not None
|
|
348
|
+
project_dir = (project_dir or Path.cwd()).resolve()
|
|
349
|
+
_ensure_dbt_project(project_dir, explicit=explicit_project_dir)
|
|
350
|
+
paths = _resolve_contract_paths(contract or [], project_dir)
|
|
351
|
+
if paths and not any(_is_odcs_file(p) for p in paths):
|
|
352
|
+
console.print("[red]None of the passed contracts are valid ODCS data contracts.[/red]")
|
|
353
|
+
raise typer.Exit(code=1)
|
|
354
|
+
multiple_contracts = len(paths) > 1
|
|
355
|
+
|
|
356
|
+
# Load + resolve models for the ownership pre-flight, before any contract writes to disk.
|
|
357
|
+
loaded: list[tuple[Path, object, list[str], Optional[str]]] = []
|
|
358
|
+
error_rows: list[tuple[Path, str]] = []
|
|
359
|
+
owners_by_model: dict = {}
|
|
360
|
+
for path in paths:
|
|
361
|
+
if not _is_odcs_file(path):
|
|
362
|
+
console.print(f"[yellow]Skipping {path}: not an ODCS data contract.[/yellow]")
|
|
363
|
+
continue
|
|
364
|
+
try:
|
|
365
|
+
odcs = resolve_data_contract(str(path))
|
|
366
|
+
model_names = list(resolve_model_names(odcs, model_resolution, schema_name).values())
|
|
367
|
+
dbt_version = resolve_versioned_target(project_dir, model_names, parse_filename_version(path))
|
|
368
|
+
loaded.append((path, odcs, model_names, dbt_version))
|
|
369
|
+
for model in {m.lower() for m in model_names}:
|
|
370
|
+
owners_by_model.setdefault(model, []).append(
|
|
371
|
+
_Owner(path, odcs.id, odcs.version or "no_version", dbt_version)
|
|
372
|
+
)
|
|
373
|
+
except Exception as e:
|
|
374
|
+
if not multiple_contracts:
|
|
375
|
+
raise
|
|
376
|
+
error_rows.append((path, str(e)))
|
|
377
|
+
_check_model_ownership(owners_by_model)
|
|
378
|
+
for _, odcs, _, _ in loaded:
|
|
379
|
+
_validate_server_declared(odcs, server)
|
|
380
|
+
|
|
381
|
+
ctxs: list[_ContractCtx] = []
|
|
382
|
+
for path, odcs, _, dbt_version in loaded:
|
|
383
|
+
try:
|
|
384
|
+
gen = generate_dbt_tests(
|
|
385
|
+
contract=str(path),
|
|
386
|
+
project_dir=project_dir,
|
|
387
|
+
schema_name=schema_name,
|
|
388
|
+
model_resolution=model_resolution,
|
|
389
|
+
prune=prune,
|
|
390
|
+
model_version=dbt_version,
|
|
391
|
+
server=server,
|
|
392
|
+
)
|
|
393
|
+
except Exception as e:
|
|
394
|
+
if not multiple_contracts:
|
|
395
|
+
raise
|
|
396
|
+
error_rows.append((path, str(e)))
|
|
397
|
+
continue
|
|
398
|
+
if not contract and not multiple_contracts:
|
|
399
|
+
console.print(f"Resolved contract {gen.contract_path}")
|
|
400
|
+
_print_sync_summary(gen, project_dir, debug=bool(debug))
|
|
401
|
+
if not prune:
|
|
402
|
+
_warn_prunable(gen, project_dir)
|
|
403
|
+
ctxs.append(_ContractCtx(gen.contract_path, gen.odcs, gen.resolved_models, gen.generation_run, dbt_version))
|
|
404
|
+
|
|
405
|
+
if not run_tests_flag:
|
|
406
|
+
console.print("[dim]Run `datacontract dbt test` to execute the generated tests.[/dim]")
|
|
407
|
+
for path, msg in error_rows:
|
|
408
|
+
console.print(f"[red]🔴 {path}: {msg}[/red]")
|
|
409
|
+
if error_rows:
|
|
410
|
+
raise typer.Exit(code=1)
|
|
411
|
+
return
|
|
412
|
+
|
|
413
|
+
check_dbt_on_path()
|
|
414
|
+
failed = _run_and_report(
|
|
415
|
+
ctxs,
|
|
416
|
+
project_dir,
|
|
417
|
+
target=target,
|
|
418
|
+
profiles_dir=profiles_dir,
|
|
419
|
+
publish=publish,
|
|
420
|
+
server=server,
|
|
421
|
+
ssl_verification=ssl_verification,
|
|
422
|
+
error_rows=error_rows,
|
|
423
|
+
multiple_contracts=multiple_contracts,
|
|
424
|
+
)
|
|
425
|
+
if failed:
|
|
426
|
+
raise typer.Exit(code=1)
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
@dbt_app.command(
|
|
430
|
+
name="test",
|
|
431
|
+
epilog="Example: datacontract dbt test orders.odcs.yaml --project-dir ./warehouse",
|
|
432
|
+
)
|
|
433
|
+
def test_command(
|
|
434
|
+
contract: Annotated[
|
|
435
|
+
Optional[list[str]],
|
|
436
|
+
typer.Argument(
|
|
437
|
+
help="Path(s) or glob(s) of ODCS contracts to test. If omitted, tests every `*.odcs.yaml` "
|
|
438
|
+
"under --project-dir (default: current directory) and its subdirectories.",
|
|
439
|
+
),
|
|
440
|
+
] = None,
|
|
441
|
+
project_dir: Annotated[
|
|
442
|
+
Optional[Path],
|
|
443
|
+
typer.Option(
|
|
444
|
+
help="Path to the dbt project root (must contain `dbt_project.yml`). Defaults to the current directory."
|
|
445
|
+
),
|
|
446
|
+
] = None,
|
|
447
|
+
target: Annotated[Optional[str], typer.Option(help="Forwarded to `dbt test --target`.")] = None,
|
|
448
|
+
profiles_dir: Annotated[
|
|
449
|
+
Optional[Path],
|
|
450
|
+
typer.Option(help="Forwarded to `dbt test --profiles-dir`."),
|
|
451
|
+
] = None,
|
|
452
|
+
publish: Annotated[Optional[str], typer.Option(help="The url to publish the results after the test.")] = None,
|
|
453
|
+
server: Annotated[
|
|
454
|
+
Optional[str],
|
|
455
|
+
typer.Option(
|
|
456
|
+
help="Selected ODCS server, used as the server label when publishing results. Default: Auto-selected if only one server exists, else --target.",
|
|
457
|
+
),
|
|
458
|
+
] = None,
|
|
459
|
+
ssl_verification: Annotated[bool, typer.Option(help="SSL verification when publishing test results.")] = True,
|
|
460
|
+
debug: debug_option = None,
|
|
461
|
+
):
|
|
462
|
+
"""
|
|
463
|
+
Run the contract-managed dbt tests that `datacontract dbt sync` generated.
|
|
464
|
+
|
|
465
|
+
Runs `dbt test` scoped to the specified data contract(s), reports the results, and optionally publishes
|
|
466
|
+
them. Use `datacontract dbt sync` to create and update the tests first.
|
|
467
|
+
"""
|
|
468
|
+
enable_debug_logging(debug)
|
|
469
|
+
validate_publish_url(publish)
|
|
470
|
+
check_dbt_on_path()
|
|
471
|
+
|
|
472
|
+
explicit_project_dir = project_dir is not None
|
|
473
|
+
project_dir = (project_dir or Path.cwd()).resolve()
|
|
474
|
+
_ensure_dbt_project(project_dir, explicit=explicit_project_dir)
|
|
475
|
+
paths = _resolve_contract_paths(contract or [], project_dir)
|
|
476
|
+
multiple_contracts = len(paths) > 1
|
|
477
|
+
|
|
478
|
+
ctxs: list[_ContractCtx] = []
|
|
479
|
+
error_rows: list[tuple[Path, str]] = []
|
|
480
|
+
owners_by_model: dict = {}
|
|
481
|
+
skipped: list[Path] = []
|
|
482
|
+
for path in paths:
|
|
483
|
+
if not _is_odcs_file(path):
|
|
484
|
+
skipped.append(path)
|
|
485
|
+
continue
|
|
486
|
+
try:
|
|
487
|
+
odcs = resolve_data_contract(str(path))
|
|
488
|
+
except Exception as e:
|
|
489
|
+
if not multiple_contracts:
|
|
490
|
+
raise
|
|
491
|
+
error_rows.append((path, str(e)))
|
|
492
|
+
continue
|
|
493
|
+
if not contract and not multiple_contracts:
|
|
494
|
+
console.print(f"Resolved contract {path}")
|
|
495
|
+
# `dbt test` doesn't know which `--model-resolution` `dbt sync` used, so match on both name and physicalName.
|
|
496
|
+
model_names: list[str] = []
|
|
497
|
+
for s in odcs.schema_ or []:
|
|
498
|
+
if s.name:
|
|
499
|
+
model_names.append(s.name)
|
|
500
|
+
if getattr(s, "physicalName", None):
|
|
501
|
+
model_names.append(s.physicalName)
|
|
502
|
+
dbt_version = resolve_versioned_target(project_dir, model_names, parse_filename_version(path))
|
|
503
|
+
ctxs.append(_ContractCtx(path, odcs, model_names, None, dbt_version))
|
|
504
|
+
for model in {m.lower() for m in model_names}:
|
|
505
|
+
owners_by_model.setdefault(model, []).append(
|
|
506
|
+
_Owner(path, odcs.id, odcs.version or "no_version", dbt_version)
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
if paths and not ctxs and not error_rows:
|
|
510
|
+
console.print("[red]None of the passed contracts are valid ODCS data contracts.[/red]")
|
|
511
|
+
raise typer.Exit(code=1)
|
|
512
|
+
for path in skipped:
|
|
513
|
+
console.print(f"[yellow]Skipping {path}: not an ODCS data contract.[/yellow]")
|
|
514
|
+
|
|
515
|
+
_check_model_ownership(owners_by_model)
|
|
516
|
+
for c in ctxs:
|
|
517
|
+
_validate_server_declared(c.odcs, server)
|
|
518
|
+
|
|
519
|
+
failed = _run_and_report(
|
|
520
|
+
ctxs,
|
|
521
|
+
project_dir,
|
|
522
|
+
target=target,
|
|
523
|
+
profiles_dir=profiles_dir,
|
|
524
|
+
publish=publish,
|
|
525
|
+
server=server,
|
|
526
|
+
ssl_verification=ssl_verification,
|
|
527
|
+
error_rows=error_rows,
|
|
528
|
+
multiple_contracts=multiple_contracts,
|
|
529
|
+
)
|
|
530
|
+
if failed:
|
|
531
|
+
raise typer.Exit(code=1)
|
{datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/checks/check_spec.py
RENAMED
|
@@ -29,6 +29,7 @@ class MetricType(str, Enum):
|
|
|
29
29
|
INVALID_COUNT = "invalid_count"
|
|
30
30
|
FIELD_PRESENT = "field_present"
|
|
31
31
|
FIELD_TYPE = "field_type"
|
|
32
|
+
FIELD_PHYSICAL_TYPE = "field_physical_type"
|
|
32
33
|
FRESHNESS = "freshness"
|
|
33
34
|
RETENTION = "retention"
|
|
34
35
|
CUSTOM_SQL = "custom_sql"
|
|
@@ -122,6 +123,7 @@ class CheckSpec:
|
|
|
122
123
|
expected_category: Optional[str] = None # FIELD_TYPE: human-readable label (display only)
|
|
123
124
|
expected_type_label: Optional[str] = None # FIELD_TYPE: human-readable expected type
|
|
124
125
|
expected_schema_property: Optional["SchemaProperty"] = None # FIELD_TYPE: structural comparison
|
|
126
|
+
expected_physical_type: Optional[str] = None # FIELD_PHYSICAL_TYPE: contract physicalType
|
|
125
127
|
|
|
126
128
|
columns: Optional[List[str]] = None # DUPLICATE_COUNT across multiple columns
|
|
127
129
|
|