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.
Files changed (378) hide show
  1. {datacontract_cli-1.0.8/datacontract_cli.egg-info → datacontract_cli-1.0.10}/PKG-INFO +11 -8
  2. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/README.md +3 -1
  3. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/cli.py +1 -0
  4. datacontract_cli-1.0.10/datacontract/command_dbt.py +531 -0
  5. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/checks/check_spec.py +2 -0
  6. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/checks/create_checks.py +33 -2
  7. datacontract_cli-1.0.10/datacontract/engines/checks/physical_type_match.py +133 -0
  8. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/checks/type_normalize.py +36 -14
  9. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/connections/kafka.py +9 -1
  10. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/dtype_category.py +2 -2
  11. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/ibis_check_execute.py +85 -1
  12. datacontract_cli-1.0.10/datacontract/engines/ibis/native_type.py +237 -0
  13. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/dbt_exporter.py +5 -1
  14. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/bigquery_importer.py +3 -3
  15. datacontract_cli-1.0.10/datacontract/integration/dbt_sync.py +2751 -0
  16. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/lint/resolve.py +9 -0
  17. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/model/run.py +9 -0
  18. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10/datacontract_cli.egg-info}/PKG-INFO +11 -8
  19. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract_cli.egg-info/SOURCES.txt +5 -0
  20. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract_cli.egg-info/requires.txt +7 -6
  21. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/pyproject.toml +8 -7
  22. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_ci_output.py +4 -0
  23. datacontract_cli-1.0.10/tests/test_create_checks_physical_type.py +46 -0
  24. datacontract_cli-1.0.10/tests/test_dbt_sync.py +2756 -0
  25. datacontract_cli-1.0.10/tests/test_dtype_category.py +28 -0
  26. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_dbt_models.py +26 -1
  27. datacontract_cli-1.0.10/tests/test_physical_type_match.py +125 -0
  28. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_kafka.py +57 -2
  29. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_output_json.py +1 -0
  30. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_parquet.py +15 -0
  31. datacontract_cli-1.0.10/tests/test_test_quality_local_fallback.py +50 -0
  32. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_quality_percent_severity.py +33 -0
  33. datacontract_cli-1.0.8/datacontract/command_dbt.py +0 -161
  34. datacontract_cli-1.0.8/datacontract/integration/dbt_sync.py +0 -1215
  35. datacontract_cli-1.0.8/tests/test_dbt_sync.py +0 -1333
  36. datacontract_cli-1.0.8/tests/test_test_quality_local_fallback.py +0 -13
  37. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/LICENSE +0 -0
  38. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/MANIFEST.in +0 -0
  39. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/__init__.py +0 -0
  40. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/api.py +0 -0
  41. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/catalog/catalog.py +0 -0
  42. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/changelog/__init__.py +0 -0
  43. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/changelog/changelog.py +0 -0
  44. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/changelog/normalize.py +0 -0
  45. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_api.py +0 -0
  46. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_catalog.py +0 -0
  47. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_changelog.py +0 -0
  48. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_ci.py +0 -0
  49. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_edit.py +0 -0
  50. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_export.py +0 -0
  51. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_import.py +0 -0
  52. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_init.py +0 -0
  53. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_lint.py +0 -0
  54. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_publish.py +0 -0
  55. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/command_test.py +0 -0
  56. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/data_contract.py +0 -0
  57. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/VERSION +0 -0
  58. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/abap-Bs8kvjsq.js +0 -0
  59. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/apex-Dspwrl5m.js +0 -0
  60. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/assets/editor.worker-4.7.0.js +0 -0
  61. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/assets/yaml.worker-4.7.0.js +0 -0
  62. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/azcli-k1BiOau1.js +0 -0
  63. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/bat-BIP72KWc.js +0 -0
  64. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/bicep-VhQeYhS3.js +0 -0
  65. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/cameligo-DnuAXtHg.js +0 -0
  66. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/clojure-BAuDPsal.js +0 -0
  67. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/coffee-BV06qSnj.js +0 -0
  68. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/cpp-Cz8Jeyrf.js +0 -0
  69. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/csharp-F6hhlXFb.js +0 -0
  70. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/csp-KzlEHCyI.js +0 -0
  71. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/css-e4FKntZ3.js +0 -0
  72. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/cssMode-BNkTa2xp.js +0 -0
  73. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/cypher-CpvDGKRr.js +0 -0
  74. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/dart-DdHeFWR0.js +0 -0
  75. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/datacontract-editor.css +0 -0
  76. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/datacontract-editor.es.js +0 -0
  77. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/dockerfile-aoNXDcio.js +0 -0
  78. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/ecl-C4Q0DYuA.js +0 -0
  79. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/elixir-C9X42b0T.js +0 -0
  80. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/flow9-Bff42pfB.js +0 -0
  81. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/freemarker2-Dyfzmb5A.js +0 -0
  82. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/fsharp-C6vPAsHG.js +0 -0
  83. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/go-DEr8zx9f.js +0 -0
  84. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/graphql-BiNBBRFh.js +0 -0
  85. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/handlebars-BtDNI-uC.js +0 -0
  86. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/hcl-2T9lKuFg.js +0 -0
  87. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/html-Cn4TGw_o.js +0 -0
  88. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/htmlMode-Bf84vbo2.js +0 -0
  89. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/index.html +0 -0
  90. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/ini-CZGtssYM.js +0 -0
  91. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/java-B260NeH3.js +0 -0
  92. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/javascript-B86Kac07.js +0 -0
  93. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/jsonMode-Ckgg5lAE.js +0 -0
  94. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/julia-kuNLM9c5.js +0 -0
  95. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/kotlin-Bz6kAefA.js +0 -0
  96. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/less-AZUtS89I.js +0 -0
  97. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/lexon-BcmgnyRb.js +0 -0
  98. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/liquid-D0NPwuu_.js +0 -0
  99. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/logo_fuchsia_v2.svg +0 -0
  100. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/lua-Dz1RbATg.js +0 -0
  101. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/m3-CIMooLFn.js +0 -0
  102. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/markdown-C1BsCK9P.js +0 -0
  103. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/mdx-QFRSBtVQ.js +0 -0
  104. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/mips-BovsnfLQ.js +0 -0
  105. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/monaco-4.7.0.js +0 -0
  106. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/msdax-CiRB2ZB-.js +0 -0
  107. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/mysql-BwdpPE19.js +0 -0
  108. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/objective-c-D4nfHfso.js +0 -0
  109. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/odcs.svg +0 -0
  110. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/pascal--j5-PYtz.js +0 -0
  111. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/pascaligo-C7TcJxNL.js +0 -0
  112. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/perl-BzEWqUb5.js +0 -0
  113. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/pgsql-B_KZ0mGX.js +0 -0
  114. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/php-A19QHzQV.js +0 -0
  115. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/pla-COeKY1hA.js +0 -0
  116. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/postiats-BfMp7zJL.js +0 -0
  117. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/powerquery-B0TS_5Gb.js +0 -0
  118. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/powershell-5jSbKdYB.js +0 -0
  119. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/protobuf-YgnOutn3.js +0 -0
  120. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/pug-DLej6kn5.js +0 -0
  121. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/python-C8RW9B6A.js +0 -0
  122. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/qsharp-AhjqtSHB.js +0 -0
  123. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/r-D-F4P80w.js +0 -0
  124. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/razor-CLZqdY_r.js +0 -0
  125. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/redis-hwwIlMnV.js +0 -0
  126. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/redshift-Bcm_kjEG.js +0 -0
  127. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/restructuredtext-CrdzfPP-.js +0 -0
  128. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/ruby-QC2UNm1s.js +0 -0
  129. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/rust-5aqiQ3L5.js +0 -0
  130. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/sb-B1g1ZfLJ.js +0 -0
  131. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/scala-C2U4R5Gb.js +0 -0
  132. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/scheme-DeFRbslr.js +0 -0
  133. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/scss-RSTCiCmI.js +0 -0
  134. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/shell-BpF-iNu8.js +0 -0
  135. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/solidity-C00r2mbQ.js +0 -0
  136. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/sophia-DVW5ZKDB.js +0 -0
  137. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/sparql-B0nmpxeX.js +0 -0
  138. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/sql-CJwKPERn.js +0 -0
  139. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/st-DPlKG5DT.js +0 -0
  140. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/swift-YZBAbVHV.js +0 -0
  141. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/systemverilog-CDQSaH63.js +0 -0
  142. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/tcl-Dlu8sp6Q.js +0 -0
  143. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/tsMode-yleMwhPq.js +0 -0
  144. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/twig-C5TO7-kw.js +0 -0
  145. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/typescript-CJBeebKU.js +0 -0
  146. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/typespec-BsmjDEu7.js +0 -0
  147. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/vb-ChHvIDrk.js +0 -0
  148. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/wgsl-XEp1ju8c.js +0 -0
  149. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/xml-vC-NMVX1.js +0 -0
  150. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/editor_assets/yaml-Dlf2VF-T.js +0 -0
  151. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/__init__.py +0 -0
  152. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/checks/__init__.py +0 -0
  153. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/data_contract_test.py +0 -0
  154. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/datacontract/check_azure_blob_file.py +0 -0
  155. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
  156. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
  157. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/fastjsonschema/check_jsonschema.py +0 -0
  158. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -0
  159. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/__init__.py +0 -0
  160. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/connections/__init__.py +0 -0
  161. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/connections/connect.py +0 -0
  162. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/connections/duckdb_connection.py +0 -0
  163. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/connections/oracle_patch.py +0 -0
  164. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/engines/ibis/connections/redshift_patch.py +0 -0
  165. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/__init__.py +0 -0
  166. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/avro_exporter.py +0 -0
  167. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/avro_idl_exporter.py +0 -0
  168. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/bigquery_exporter.py +0 -0
  169. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/custom_exporter.py +0 -0
  170. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/data_caterer_exporter.py +0 -0
  171. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/dbml_exporter.py +0 -0
  172. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/dcs_exporter.py +0 -0
  173. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/dqx_exporter.py +0 -0
  174. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/duckdb_type_converter.py +0 -0
  175. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/excel_exporter.py +0 -0
  176. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/exporter.py +0 -0
  177. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/exporter_factory.py +0 -0
  178. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/go_exporter.py +0 -0
  179. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/great_expectations_exporter.py +0 -0
  180. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/html_exporter.py +0 -0
  181. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/iceberg_exporter.py +0 -0
  182. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/jsonschema_exporter.py +0 -0
  183. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/markdown_exporter.py +0 -0
  184. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/mermaid_exporter.py +0 -0
  185. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/odcs_export_helper.py +0 -0
  186. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/odcs_v3_exporter.py +0 -0
  187. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/pandas_type_converter.py +0 -0
  188. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/protobuf_exporter.py +0 -0
  189. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/pydantic_exporter.py +0 -0
  190. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/rdf_exporter.py +0 -0
  191. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/sodacl_check_builder.py +0 -0
  192. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/sodacl_exporter.py +0 -0
  193. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/spark_exporter.py +0 -0
  194. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/sql_exporter.py +0 -0
  195. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/sql_type_converter.py +0 -0
  196. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/export/sqlalchemy_exporter.py +0 -0
  197. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/avro_importer.py +0 -0
  198. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/csv_importer.py +0 -0
  199. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/dbml_importer.py +0 -0
  200. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/dbt_importer.py +0 -0
  201. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/dcs_importer.py +0 -0
  202. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/excel_importer.py +0 -0
  203. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/glue_importer.py +0 -0
  204. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/iceberg_importer.py +0 -0
  205. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/importer.py +0 -0
  206. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/importer_factory.py +0 -0
  207. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/json_importer.py +0 -0
  208. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/jsonschema_importer.py +0 -0
  209. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/odcs_helper.py +0 -0
  210. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/odcs_importer.py +0 -0
  211. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/parquet_importer.py +0 -0
  212. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/powerbi_importer.py +0 -0
  213. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/protobuf_importer.py +0 -0
  214. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/snowflake_importer.py +0 -0
  215. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/spark_importer.py +0 -0
  216. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/sql_importer.py +0 -0
  217. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/imports/unity_importer.py +0 -0
  218. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/init/init_template.py +0 -0
  219. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/integration/dbt_test_mapping.py +0 -0
  220. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/integration/entropy_data.py +0 -0
  221. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/lint/files.py +0 -0
  222. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/lint/resources.py +0 -0
  223. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/lint/schema.py +0 -0
  224. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/lint/urls.py +0 -0
  225. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/model/changelog.py +0 -0
  226. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/model/exceptions.py +0 -0
  227. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/model/odcs.py +0 -0
  228. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/model/server.py +0 -0
  229. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/__init__.py +0 -0
  230. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/ci_output.py +0 -0
  231. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/json_test_results.py +0 -0
  232. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/junit_test_results.py +0 -0
  233. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/output_format.py +0 -0
  234. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/test_results_writer.py +0 -0
  235. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/output/text_changelog_results.py +0 -0
  236. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/py.typed +0 -0
  237. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
  238. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
  239. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
  240. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
  241. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/datacontract-1.2.1.init.yaml +0 -0
  242. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/datacontract-1.2.1.schema.json +0 -0
  243. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/odcs-3.0.1.schema.json +0 -0
  244. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/odcs-3.0.2.schema.json +0 -0
  245. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/odcs-3.1.0.init.yaml +0 -0
  246. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/schemas/odcs-3.1.0.schema.json +0 -0
  247. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/datacontract.html +0 -0
  248. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/datacontract_odcs.html +0 -0
  249. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/index.html +0 -0
  250. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/datacontract_information.html +0 -0
  251. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
  252. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/datacontract_terms.html +0 -0
  253. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/definition.html +0 -0
  254. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/example.html +0 -0
  255. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/model_field.html +0 -0
  256. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/quality.html +0 -0
  257. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/partials/server.html +0 -0
  258. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract/templates/style/output.css +0 -0
  259. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract_cli.egg-info/dependency_links.txt +0 -0
  260. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract_cli.egg-info/entry_points.txt +0 -0
  261. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/datacontract_cli.egg-info/top_level.txt +0 -0
  262. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/setup.cfg +0 -0
  263. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_api.py +0 -0
  264. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_catalog.py +0 -0
  265. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_changelog.py +0 -0
  266. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_changelog_engine.py +0 -0
  267. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_changelog_normalize.py +0 -0
  268. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_changelog_output_text.py +0 -0
  269. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_cli.py +0 -0
  270. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_connect_databricks.py +0 -0
  271. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_connect_sqlserver.py +0 -0
  272. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_connect_trino.py +0 -0
  273. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_data_contract.py +0 -0
  274. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_data_contract_checks.py +0 -0
  275. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_data_contract_specification.py +0 -0
  276. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_dbt_test_mapping.py +0 -0
  277. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_description_linter.py +0 -0
  278. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_download_datacontract_file.py +0 -0
  279. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_duckdb_json.py +0 -0
  280. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_edit.py +0 -0
  281. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_avro.py +0 -0
  282. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_avro_idl.py +0 -0
  283. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_bigquery.py +0 -0
  284. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_complex_data_contract.py +0 -0
  285. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_custom.py +0 -0
  286. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_custom_exporter.py +0 -0
  287. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_custom_model.py +0 -0
  288. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_data_caterer.py +0 -0
  289. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_dbml.py +0 -0
  290. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_dbt_sources.py +0 -0
  291. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_dbt_staging_sql.py +0 -0
  292. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_dqx.py +0 -0
  293. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_excel.py +0 -0
  294. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_go.py +0 -0
  295. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_great_expectations.py +0 -0
  296. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_html.py +0 -0
  297. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_iceberg.py +0 -0
  298. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_jsonschema.py +0 -0
  299. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_markdown.py +0 -0
  300. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_mermaid.py +0 -0
  301. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_odcs_v3.py +0 -0
  302. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_protobuf.py +0 -0
  303. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_pydantic.py +0 -0
  304. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_rdf.py +0 -0
  305. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_sodacl.py +0 -0
  306. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_spark.py +0 -0
  307. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_sql.py +0 -0
  308. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_sql_clickhouse.py +0 -0
  309. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_sql_query.py +0 -0
  310. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_export_sqlalchemy.py +0 -0
  311. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_ibis_mssql_pattern.py +0 -0
  312. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_ibis_oracle_schema.py +0 -0
  313. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_avro.py +0 -0
  314. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_bigquery.py +0 -0
  315. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_csv.py +0 -0
  316. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_dbml.py +0 -0
  317. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_dbt.py +0 -0
  318. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_excel.py +0 -0
  319. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_glue.py +0 -0
  320. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_iceberg.py +0 -0
  321. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_json.py +0 -0
  322. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_jsonschema.py +0 -0
  323. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_odcs_v3.py +0 -0
  324. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_parquet.py +0 -0
  325. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_powerbi.py +0 -0
  326. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_protobuf.py +0 -0
  327. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_snowflake.py +0 -0
  328. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_spark.py +0 -0
  329. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_sql_oracle.py +0 -0
  330. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_sql_postgres.py +0 -0
  331. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_sql_snowflake.py +0 -0
  332. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_sql_sqlserver.py +0 -0
  333. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_import_unity_file.py +0 -0
  334. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_integration_entropydata.py +0 -0
  335. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_lint.py +0 -0
  336. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_oracle_patch.py +0 -0
  337. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_redshift_patch.py +0 -0
  338. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_require_env.py +0 -0
  339. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_resolve.py +0 -0
  340. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_resolve_definitions.py +0 -0
  341. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_roundtrip_jsonschema.py +0 -0
  342. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_sql_type_converter_physicaltype.py +0 -0
  343. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_api.py +0 -0
  344. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_athena_iceberg.py +0 -0
  345. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_azure_blob_file.py +0 -0
  346. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_azure_remote.py +0 -0
  347. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_bigquery.py +0 -0
  348. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_checks_filter.py +0 -0
  349. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_databricks.py +0 -0
  350. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_dataframe.py +0 -0
  351. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_delta.py +0 -0
  352. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_diagnostics.py +0 -0
  353. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_failed_samples.py +0 -0
  354. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_gcs_csv_remote.py +0 -0
  355. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_gcs_json_remote.py +0 -0
  356. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_kafka_remote.py +0 -0
  357. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_local_json.py +0 -0
  358. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_local_json_nd.py +0 -0
  359. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_mysql.py +0 -0
  360. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_oracle.py +0 -0
  361. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_oracle_xe.py +0 -0
  362. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_output_junit.py +0 -0
  363. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_postgres.py +0 -0
  364. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_quality.py +0 -0
  365. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_redshift.py +0 -0
  366. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_s3_csv.py +0 -0
  367. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_s3_delta.py +0 -0
  368. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_s3_json.py +0 -0
  369. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_s3_json_complex.py +0 -0
  370. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_s3_json_multiple_models.py +0 -0
  371. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_s3_json_remote.py +0 -0
  372. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_schema_evolution.py +0 -0
  373. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_server_not_found.py +0 -0
  374. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_snowflake.py +0 -0
  375. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_soda_connection_error.py +0 -0
  376. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_sqlserver.py +0 -0
  377. {datacontract_cli-1.0.8 → datacontract_cli-1.0.10}/tests/test_test_trino.py +0 -0
  378. {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.8
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.119.0; extra == "databricks"
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.18,>=1.17.1; extra == "azure"
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.139.0,>=0.115.0; extra == "api"
96
- Requires-Dist: uvicorn<0.50.0,>=0.44.0; extra == "api"
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.18; extra == "dev"
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.337.0; extra == "dev"
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 and run `dbt test`
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 and run `dbt test`
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
@@ -25,6 +25,7 @@ COMMAND_ORDER = [
25
25
  "edit",
26
26
  "lint",
27
27
  "changelog",
28
+ "sync", # `dbt sync` subcommand; no top-level `sync`, so this only orders the dbt group
28
29
  "test",
29
30
  "ci",
30
31
  "export",
@@ -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)
@@ -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