datacontract-cli 1.2.6__tar.gz → 1.2.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (481) hide show
  1. {datacontract_cli-1.2.6/datacontract_cli.egg-info → datacontract_cli-1.2.7}/PKG-INFO +4 -3
  2. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/README.md +3 -2
  3. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/api.py +38 -14
  4. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/breaking/detector.py +39 -37
  5. datacontract_cli-1.2.7/datacontract/breaking/rules.py +486 -0
  6. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_api.py +11 -1
  7. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_breaking.py +9 -1
  8. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_import.py +4 -3
  9. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/config/settings.py +4 -0
  10. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/config/variables.py +7 -8
  11. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/data_contract.py +29 -7
  12. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/checks/create_checks.py +2 -2
  13. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/data_contract_test.py +84 -19
  14. datacontract_cli-1.2.7/datacontract/engines/http_api.py +96 -0
  15. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/odata_importer.py +3 -13
  16. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/openapi_importer.py +86 -33
  17. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/model/breaking.py +20 -0
  18. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/output/test_results_writer.py +3 -0
  19. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/output/text_breaking_results.py +3 -0
  20. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7/datacontract_cli.egg-info}/PKG-INFO +4 -3
  21. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract_cli.egg-info/SOURCES.txt +1 -0
  22. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/pyproject.toml +1 -1
  23. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_api.py +74 -1
  24. datacontract_cli-1.2.7/tests/test_breaking.py +523 -0
  25. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_breaking_odcs_3_2.py +28 -23
  26. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_config.py +1 -0
  27. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_odata.py +9 -6
  28. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_openapi.py +78 -3
  29. datacontract_cli-1.2.7/tests/test_test_api.py +243 -0
  30. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_api_openapi_import.py +1 -44
  31. datacontract_cli-1.2.6/datacontract/breaking/rules.py +0 -280
  32. datacontract_cli-1.2.6/tests/test_breaking.py +0 -490
  33. datacontract_cli-1.2.6/tests/test_test_api.py +0 -83
  34. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/LICENSE +0 -0
  35. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/MANIFEST.in +0 -0
  36. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/__init__.py +0 -0
  37. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/breaking/__init__.py +0 -0
  38. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/catalog/catalog.py +0 -0
  39. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/changelog/__init__.py +0 -0
  40. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/changelog/changelog.py +0 -0
  41. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/changelog/normalize.py +0 -0
  42. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/cli.py +0 -0
  43. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_catalog.py +0 -0
  44. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_changelog.py +0 -0
  45. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_ci.py +0 -0
  46. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_dbt.py +0 -0
  47. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_edit.py +0 -0
  48. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_export.py +0 -0
  49. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_init.py +0 -0
  50. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_lint.py +0 -0
  51. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_publish.py +0 -0
  52. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/command_test.py +0 -0
  53. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/config/__init__.py +0 -0
  54. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/config/cli_context.py +0 -0
  55. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/editor_assets/VERSION +0 -0
  56. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/editor_assets/assets/editor.worker-4.7.0.js +0 -0
  57. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/editor_assets/assets/yaml.worker-4.7.0.js +0 -0
  58. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/editor_assets/datacontract-editor.css +0 -0
  59. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/editor_assets/datacontract-editor.es.js +0 -0
  60. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/editor_assets/index.html +0 -0
  61. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/editor_assets/logo_fuchsia_v2.svg +0 -0
  62. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/editor_assets/monaco-4.7.0.js +0 -0
  63. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/editor_assets/odcs.svg +0 -0
  64. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/editor_assets/robots.txt +0 -0
  65. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/editor_assets/rolldown-runtime-DY7j01NX.js +0 -0
  66. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/editor_assets/sitemap.xml +0 -0
  67. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/__init__.py +0 -0
  68. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/checks/__init__.py +0 -0
  69. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/checks/check_filter.py +0 -0
  70. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/checks/check_spec.py +0 -0
  71. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/checks/custom_quality_check.py +0 -0
  72. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/checks/dimensions.py +0 -0
  73. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/checks/physical_type_match.py +0 -0
  74. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/checks/severity.py +0 -0
  75. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/checks/sql_guard.py +0 -0
  76. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/checks/type_normalize.py +0 -0
  77. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/datacontract/check_azure_blob_file.py +0 -0
  78. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
  79. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
  80. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/fastjsonschema/check_jsonschema.py +0 -0
  81. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -0
  82. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/hana/__init__.py +0 -0
  83. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/hana/check_hana_execute.py +0 -0
  84. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/hana/hana_check_selection.py +0 -0
  85. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/hana/hana_connection.py +0 -0
  86. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/hana/hana_quality_check.py +0 -0
  87. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/hana/hana_schema_check.py +0 -0
  88. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/hana/hana_type_mapping.py +0 -0
  89. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/__init__.py +0 -0
  90. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/__init__.py +0 -0
  91. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/athena_patch.py +0 -0
  92. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/aws_credentials.py +0 -0
  93. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/connect.py +0 -0
  94. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/databricks_patch.py +0 -0
  95. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/duckdb_connection.py +0 -0
  96. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/exasol_patch.py +0 -0
  97. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/hive_patch.py +0 -0
  98. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/iceberg.py +0 -0
  99. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/kafka.py +0 -0
  100. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/oracle_patch.py +0 -0
  101. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/redshift_credentials.py +0 -0
  102. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/connections/redshift_patch.py +0 -0
  103. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/dtype_category.py +0 -0
  104. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/ibis_check_execute.py +0 -0
  105. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/native_type.py +0 -0
  106. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/engines/ibis/snowflake_structured_types.py +0 -0
  107. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/__init__.py +0 -0
  108. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/avro_exporter.py +0 -0
  109. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/avro_idl_exporter.py +0 -0
  110. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/bigquery_exporter.py +0 -0
  111. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/custom_exporter.py +0 -0
  112. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/data_caterer_exporter.py +0 -0
  113. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/dbml_exporter.py +0 -0
  114. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/dbt_exporter.py +0 -0
  115. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/dcs_exporter.py +0 -0
  116. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/dqx_exporter.py +0 -0
  117. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/duckdb_type_converter.py +0 -0
  118. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/excel_exporter.py +0 -0
  119. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/exporter.py +0 -0
  120. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/exporter_factory.py +0 -0
  121. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/go_exporter.py +0 -0
  122. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/great_expectations_exporter.py +0 -0
  123. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/html_exporter.py +0 -0
  124. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/iceberg_exporter.py +0 -0
  125. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/jsonschema_exporter.py +0 -0
  126. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/markdown_exporter.py +0 -0
  127. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/mermaid_exporter.py +0 -0
  128. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/odcs_v3_exporter.py +0 -0
  129. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/pandas_type_converter.py +0 -0
  130. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/protobuf_exporter.py +0 -0
  131. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/pydantic_exporter.py +0 -0
  132. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/rdf_exporter.py +0 -0
  133. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/sodacl_check_builder.py +0 -0
  134. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/sodacl_exporter.py +0 -0
  135. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/spark_exporter.py +0 -0
  136. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/sql_exporter.py +0 -0
  137. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/sql_type_converter.py +0 -0
  138. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/sqlalchemy_exporter.py +0 -0
  139. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/export/xsd_exporter.py +0 -0
  140. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/athena_importer.py +0 -0
  141. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/avro_importer.py +0 -0
  142. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/bigquery_importer.py +0 -0
  143. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/clickhouse_importer.py +0 -0
  144. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/csv_importer.py +0 -0
  145. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/dbml_importer.py +0 -0
  146. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/dbt_importer.py +0 -0
  147. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/dcs_importer.py +0 -0
  148. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/excel_importer.py +0 -0
  149. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/glue_importer.py +0 -0
  150. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/hive_importer.py +0 -0
  151. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/iceberg_importer.py +0 -0
  152. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/importer.py +0 -0
  153. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/importer_factory.py +0 -0
  154. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/json_importer.py +0 -0
  155. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/jsonschema_importer.py +0 -0
  156. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/mysql_importer.py +0 -0
  157. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/object_storage_importer.py +0 -0
  158. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/odcs_helper.py +0 -0
  159. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/odcs_importer.py +0 -0
  160. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/oracle_importer.py +0 -0
  161. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/parquet_importer.py +0 -0
  162. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/postgres_importer.py +0 -0
  163. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/powerbi_importer.py +0 -0
  164. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/protobuf_importer.py +0 -0
  165. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/pydantic_importer.py +0 -0
  166. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/redshift_importer.py +0 -0
  167. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/snowflake_importer.py +0 -0
  168. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/spark_importer.py +0 -0
  169. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/spark_type_json.py +0 -0
  170. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/sql_importer.py +0 -0
  171. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/sqlserver_importer.py +0 -0
  172. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/trino_importer.py +0 -0
  173. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/unity_importer.py +0 -0
  174. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/imports/xsd_importer.py +0 -0
  175. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/init/init_template.py +0 -0
  176. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/integration/dbt_sync.py +0 -0
  177. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/integration/dbt_test_mapping.py +0 -0
  178. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/integration/entropy_data.py +0 -0
  179. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/lint/constraints.py +0 -0
  180. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/lint/files.py +0 -0
  181. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/lint/resolve.py +0 -0
  182. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/lint/resources.py +0 -0
  183. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/lint/s3.py +0 -0
  184. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/lint/schema.py +0 -0
  185. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/lint/urls.py +0 -0
  186. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/model/changelog.py +0 -0
  187. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/model/enum_values.py +0 -0
  188. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/model/exceptions.py +0 -0
  189. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/model/map_type.py +0 -0
  190. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/model/natural_keys.py +0 -0
  191. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/model/odcs.py +0 -0
  192. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/model/run.py +0 -0
  193. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/model/server.py +0 -0
  194. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/model/vector_type.py +0 -0
  195. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/model/workbook.py +0 -0
  196. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/output/__init__.py +0 -0
  197. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/output/ci_output.py +0 -0
  198. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/output/json_test_results.py +0 -0
  199. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/output/junit_test_results.py +0 -0
  200. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/output/output_format.py +0 -0
  201. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/output/text_changelog_results.py +0 -0
  202. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/py.typed +0 -0
  203. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
  204. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
  205. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
  206. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
  207. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/schemas/datacontract-1.2.1.init.yaml +0 -0
  208. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/schemas/datacontract-1.2.1.schema.json +0 -0
  209. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/schemas/odcs-3.0.2.schema.json +0 -0
  210. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/schemas/odcs-3.1.0.schema.json +0 -0
  211. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/schemas/odcs-3.2.0.init.yaml +0 -0
  212. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/schemas/odcs-3.2.0.schema.json +0 -0
  213. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/datacontract.html +0 -0
  214. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/datacontract_odcs.html +0 -0
  215. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/excel/odcs-template-v3.0.xlsx +0 -0
  216. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/excel/odcs-template-v3.1.xlsx +0 -0
  217. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/excel/odcs-template-v3.2.xlsx +0 -0
  218. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/index.html +0 -0
  219. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/macros/authoritative_definitions.html +0 -0
  220. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/macros/context.html +0 -0
  221. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/macros/schema.html +0 -0
  222. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/macros/server.html +0 -0
  223. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/macros/support.html +0 -0
  224. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials/datacontract_information.html +0 -0
  225. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
  226. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials/datacontract_terms.html +0 -0
  227. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials/definition.html +0 -0
  228. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials/example.html +0 -0
  229. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials/model_field.html +0 -0
  230. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials/quality.html +0 -0
  231. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials/server.html +0 -0
  232. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/context.html +0 -0
  233. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/custom_properties.html +0 -0
  234. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/diagram.html +0 -0
  235. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/dialog_yaml.html +0 -0
  236. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/footer.html +0 -0
  237. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/fundamentals.html +0 -0
  238. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/header.html +0 -0
  239. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/pricing.html +0 -0
  240. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/roles.html +0 -0
  241. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/schema.html +0 -0
  242. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/servers.html +0 -0
  243. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/sla.html +0 -0
  244. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/support.html +0 -0
  245. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/team.html +0 -0
  246. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/term_of_use.html +0 -0
  247. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/partials_odcs/title.html +0 -0
  248. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract/templates/style/output.css +0 -0
  249. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract_cli.egg-info/dependency_links.txt +0 -0
  250. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract_cli.egg-info/entry_points.txt +0 -0
  251. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract_cli.egg-info/requires.txt +0 -0
  252. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/datacontract_cli.egg-info/top_level.txt +0 -0
  253. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/setup.cfg +0 -0
  254. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_api_concurrency.py +0 -0
  255. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_api_openapi.py +0 -0
  256. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_catalog.py +0 -0
  257. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_changelog.py +0 -0
  258. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_changelog_engine.py +0 -0
  259. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_changelog_normalize.py +0 -0
  260. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_changelog_output_text.py +0 -0
  261. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_check_quality_provenance.py +0 -0
  262. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_ci_output.py +0 -0
  263. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_cli.py +0 -0
  264. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_command_api.py +0 -0
  265. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_command_api_options.py +0 -0
  266. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_config_file.py +0 -0
  267. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_config_require.py +0 -0
  268. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_config_threading.py +0 -0
  269. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_athena.py +0 -0
  270. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_bigquery.py +0 -0
  271. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_clickhouse.py +0 -0
  272. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_databricks.py +0 -0
  273. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_exasol.py +0 -0
  274. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_hive.py +0 -0
  275. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_impala.py +0 -0
  276. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_mysql.py +0 -0
  277. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_oracle.py +0 -0
  278. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_postgres.py +0 -0
  279. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_redshift.py +0 -0
  280. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_s3_credentials.py +0 -0
  281. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_snowflake.py +0 -0
  282. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_sqlserver.py +0 -0
  283. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_connect_trino.py +0 -0
  284. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_create_checks_array_items.py +0 -0
  285. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_create_checks_nested.py +0 -0
  286. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_create_checks_nested_type.py +0 -0
  287. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_create_checks_physical_type.py +0 -0
  288. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_create_checks_primary_key.py +0 -0
  289. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_create_checks_retention_period.py +0 -0
  290. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_create_checks_servicelevel.py +0 -0
  291. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_create_checks_sql_placeholders.py +0 -0
  292. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_custom_quality_checks.py +0 -0
  293. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_data_contract.py +0 -0
  294. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_data_contract_checks.py +0 -0
  295. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_data_contract_specification.py +0 -0
  296. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_dbt_sync.py +0 -0
  297. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_dbt_test_mapping.py +0 -0
  298. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_description_linter.py +0 -0
  299. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_docs_commands.py +0 -0
  300. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_docs_config_options.py +0 -0
  301. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_docs_ordering.py +0 -0
  302. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_download_datacontract_file.py +0 -0
  303. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_dtype_category.py +0 -0
  304. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_duckdb_json.py +0 -0
  305. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_edit.py +0 -0
  306. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_enum_values.py +0 -0
  307. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_avro.py +0 -0
  308. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_avro_idl.py +0 -0
  309. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_bigquery.py +0 -0
  310. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_complex_data_contract.py +0 -0
  311. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_custom.py +0 -0
  312. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_custom_exporter.py +0 -0
  313. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_custom_model.py +0 -0
  314. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_data_caterer.py +0 -0
  315. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_dbml.py +0 -0
  316. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_dbt_models.py +0 -0
  317. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_dbt_sources.py +0 -0
  318. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_dbt_staging_sql.py +0 -0
  319. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_dcs.py +0 -0
  320. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_dqx.py +0 -0
  321. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_excel.py +0 -0
  322. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_go.py +0 -0
  323. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_great_expectations.py +0 -0
  324. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_html.py +0 -0
  325. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_iceberg.py +0 -0
  326. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_jsonschema.py +0 -0
  327. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_large_contract.py +0 -0
  328. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_markdown.py +0 -0
  329. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_mermaid.py +0 -0
  330. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_odcs_v3.py +0 -0
  331. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_protobuf.py +0 -0
  332. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_pydantic.py +0 -0
  333. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_rdf.py +0 -0
  334. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_sodacl.py +0 -0
  335. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_spark.py +0 -0
  336. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_sql.py +0 -0
  337. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_sql_clickhouse.py +0 -0
  338. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_sql_query.py +0 -0
  339. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_sqlalchemy.py +0 -0
  340. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_export_xsd.py +0 -0
  341. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_hana_connection.py +0 -0
  342. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_hana_quality_check.py +0 -0
  343. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_hana_schema_check.py +0 -0
  344. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_hana_type_mapping.py +0 -0
  345. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_ibis_check_execute.py +0 -0
  346. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_ibis_mssql_pattern.py +0 -0
  347. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_ibis_mssql_schema.py +0 -0
  348. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_ibis_oracle_schema.py +0 -0
  349. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_athena.py +0 -0
  350. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_avro.py +0 -0
  351. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_bigquery.py +0 -0
  352. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_clickhouse.py +0 -0
  353. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_csv.py +0 -0
  354. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_dbml.py +0 -0
  355. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_dbt.py +0 -0
  356. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_excel.py +0 -0
  357. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_glue.py +0 -0
  358. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_hive.py +0 -0
  359. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_iceberg.py +0 -0
  360. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_json.py +0 -0
  361. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_jsonschema.py +0 -0
  362. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_mysql.py +0 -0
  363. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_object_storage.py +0 -0
  364. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_odcs_v3.py +0 -0
  365. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_oracle.py +0 -0
  366. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_parquet.py +0 -0
  367. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_postgres.py +0 -0
  368. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_powerbi.py +0 -0
  369. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_protobuf.py +0 -0
  370. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_pydantic_model.py +0 -0
  371. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_redshift.py +0 -0
  372. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_snowflake.py +0 -0
  373. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_spark_type_json.py +0 -0
  374. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_sql_clickhouse.py +0 -0
  375. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_sql_hive.py +0 -0
  376. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_sql_oracle.py +0 -0
  377. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_sql_postgres.py +0 -0
  378. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_sql_snowflake.py +0 -0
  379. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_sql_sqlserver.py +0 -0
  380. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_sql_struct.py +0 -0
  381. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_sqlserver.py +0 -0
  382. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_trino.py +0 -0
  383. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_unity_file.py +0 -0
  384. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_unmapped_types.py +0 -0
  385. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_import_xsd.py +0 -0
  386. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_install_extras.py +0 -0
  387. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_integration_entropydata.py +0 -0
  388. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_lint.py +0 -0
  389. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_lint_files.py +0 -0
  390. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_lint_odcs_3_2_constraints.py +0 -0
  391. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_lint_schema.py +0 -0
  392. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_lint_urls.py +0 -0
  393. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_map_type.py +0 -0
  394. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_metadata_fields.py +0 -0
  395. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_native_type_schema_scope.py +0 -0
  396. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_nested_path_checks.py +0 -0
  397. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_oracle_patch.py +0 -0
  398. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_physical_type_match.py +0 -0
  399. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_publish_test_results.py +0 -0
  400. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_publish_test_results_payload.py +0 -0
  401. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_quality_sql_dialects.py +0 -0
  402. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_quality_unrunnable_rules.py +0 -0
  403. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_redshift_credentials.py +0 -0
  404. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_redshift_patch.py +0 -0
  405. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_resolve.py +0 -0
  406. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_resolve_definitions.py +0 -0
  407. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_resolve_local_definitions.py +0 -0
  408. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_roundtrip_jsonschema.py +0 -0
  409. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_roundtrip_pydantic_model.py +0 -0
  410. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_roundtrip_xsd.py +0 -0
  411. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_row_filter_duplicate_count.py +0 -0
  412. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_run_check_deprecated_fields.py +0 -0
  413. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_run_check_engine.py +0 -0
  414. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_server_overrides.py +0 -0
  415. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_server_type_mssql.py +0 -0
  416. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_server_type_synonyms.py +0 -0
  417. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_servers_3_2_0.py +0 -0
  418. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_snowflake_structured_types.py +0 -0
  419. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_sql_type_converter_physicaltype.py +0 -0
  420. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_array_items.py +0 -0
  421. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_athena_iceberg.py +0 -0
  422. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_azure_blob_file.py +0 -0
  423. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_azure_remote.py +0 -0
  424. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_bigquery.py +0 -0
  425. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_checks_filter.py +0 -0
  426. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_clickhouse.py +0 -0
  427. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_databricks.py +0 -0
  428. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_delta.py +0 -0
  429. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_diagnostics.py +0 -0
  430. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_dimension_filter.py +0 -0
  431. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_dry_run.py +0 -0
  432. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_duckdb.py +0 -0
  433. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_failed_samples.py +0 -0
  434. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_gcs_csv_remote.py +0 -0
  435. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_gcs_json_remote.py +0 -0
  436. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_hana.py +0 -0
  437. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_hive.py +0 -0
  438. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_iceberg.py +0 -0
  439. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_iceberg_rest.py +0 -0
  440. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_iceberg_s3tables.py +0 -0
  441. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_kafka.py +0 -0
  442. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_kafka_decoding.py +0 -0
  443. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_kafka_remote.py +0 -0
  444. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_local_json.py +0 -0
  445. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_local_json_nd.py +0 -0
  446. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_local_xml.py +0 -0
  447. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_metadata_only.py +0 -0
  448. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_mysql.py +0 -0
  449. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_nested_checks.py +0 -0
  450. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_oracle.py +0 -0
  451. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_oracle_xe.py +0 -0
  452. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_output_json.py +0 -0
  453. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_output_junit.py +0 -0
  454. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_parquet.py +0 -0
  455. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_postgres.py +0 -0
  456. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_quality.py +0 -0
  457. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_quality_id_and_tag_filter.py +0 -0
  458. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_quality_local_fallback.py +0 -0
  459. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_quality_percent_severity.py +0 -0
  460. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_redshift.py +0 -0
  461. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_relationships.py +0 -0
  462. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_results_writer.py +0 -0
  463. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_row_filter.py +0 -0
  464. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_s3_csv.py +0 -0
  465. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_s3_delta.py +0 -0
  466. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_s3_json.py +0 -0
  467. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_s3_json_complex.py +0 -0
  468. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_s3_json_multiple_files.py +0 -0
  469. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_s3_json_multiple_models.py +0 -0
  470. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_schema_evolution.py +0 -0
  471. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_server_not_found.py +0 -0
  472. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_snowflake.py +0 -0
  473. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_soda_connection_error.py +0 -0
  474. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_sqlserver.py +0 -0
  475. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_trino.py +0 -0
  476. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_test_variables.py +0 -0
  477. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_type_normalize.py +0 -0
  478. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_untrusted_contract.py +0 -0
  479. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_untrusted_contract_variables.py +0 -0
  480. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_variables.py +0 -0
  481. {datacontract_cli-1.2.6 → datacontract_cli-1.2.7}/tests/test_vector_type.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datacontract-cli
3
- Version: 1.2.6
3
+ Version: 1.2.7
4
4
  Summary: The datacontract CLI is an open source command-line tool for working with Data Contracts. It uses data contract YAML files to lint the data contract, connect to data sources and execute schema and quality tests, detect breaking changes, and export to different formats. The tool is written in Python. It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a Python library.
5
5
  Author-email: Jochen Christ <jochen.christ@entropy-data.com>, Stefan Negele <stefan.negele@innoq.com>, Simon Harrer <simon.harrer@entropy-data.com>
6
6
  License-Expression: MIT
@@ -195,7 +195,7 @@ It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a P
195
195
  >
196
196
  > Quick links: [Quickstart](https://docs.datacontract.com/quickstart) · [Commands](https://docs.datacontract.com/commands) · [Best Practices](https://docs.datacontract.com/best-practices) · [Custom Export and Import](https://docs.datacontract.com/extending) · [Release Notes](https://docs.datacontract.com/release-notes) · [Development Setup](#development-setup)
197
197
  >
198
- > For LLMs: [docs.datacontract.com/llms.txt](https://docs.datacontract.com/llms.txt) · [docs.datacontract.com/llms-full.txt](https://docs.datacontract.com/llms-full.txt)
198
+ > For LLMs: [docs.datacontract.com/llms.txt](https://docs.datacontract.com/llms.txt) · [docs.datacontract.com/llms-full.txt](https://docs.datacontract.com/llms-full.txt) · [Data Contract Skills](https://github.com/datacontract/datacontract-skills) for coding agents
199
199
 
200
200
  ## Getting started
201
201
 
@@ -318,7 +318,7 @@ $ datacontract lint odcs.yaml
318
318
  # show a changelog between two data contracts
319
319
  $ datacontract changelog v1.odcs.yaml v2.odcs.yaml
320
320
 
321
- # fail when a contract change is backward-incompatible
321
+ # fail when a contract change breaks a guarantee consumers rely on
322
322
  $ datacontract breaking v1.odcs.yaml v2.odcs.yaml
323
323
 
324
324
  # execute schema and quality checks (define credentials as environment variables)
@@ -356,6 +356,7 @@ if not run.has_passed():
356
356
  ## How to
357
357
 
358
358
  - [How to integrate Data Contract CLI in your CI/CD pipeline as a GitHub Action](https://github.com/datacontract/datacontract-action/)
359
+ - [How to let your coding agent (Claude Code, Codex, GitHub Copilot) create and test data contracts with the Data Contract Skills](https://github.com/datacontract/datacontract-skills)
359
360
  - [How to run the Data Contract CLI API to test data contracts with POST requests](https://docs.datacontract.com/api)
360
361
  - [How to run Data Contract CLI in a Databricks pipeline](https://www.datamesh-architecture.com/howto/build-a-dataproduct-with-databricks#test-the-data-product)
361
362
 
@@ -24,7 +24,7 @@ It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a P
24
24
  >
25
25
  > Quick links: [Quickstart](https://docs.datacontract.com/quickstart) · [Commands](https://docs.datacontract.com/commands) · [Best Practices](https://docs.datacontract.com/best-practices) · [Custom Export and Import](https://docs.datacontract.com/extending) · [Release Notes](https://docs.datacontract.com/release-notes) · [Development Setup](#development-setup)
26
26
  >
27
- > For LLMs: [docs.datacontract.com/llms.txt](https://docs.datacontract.com/llms.txt) · [docs.datacontract.com/llms-full.txt](https://docs.datacontract.com/llms-full.txt)
27
+ > For LLMs: [docs.datacontract.com/llms.txt](https://docs.datacontract.com/llms.txt) · [docs.datacontract.com/llms-full.txt](https://docs.datacontract.com/llms-full.txt) · [Data Contract Skills](https://github.com/datacontract/datacontract-skills) for coding agents
28
28
 
29
29
  ## Getting started
30
30
 
@@ -147,7 +147,7 @@ $ datacontract lint odcs.yaml
147
147
  # show a changelog between two data contracts
148
148
  $ datacontract changelog v1.odcs.yaml v2.odcs.yaml
149
149
 
150
- # fail when a contract change is backward-incompatible
150
+ # fail when a contract change breaks a guarantee consumers rely on
151
151
  $ datacontract breaking v1.odcs.yaml v2.odcs.yaml
152
152
 
153
153
  # execute schema and quality checks (define credentials as environment variables)
@@ -185,6 +185,7 @@ if not run.has_passed():
185
185
  ## How to
186
186
 
187
187
  - [How to integrate Data Contract CLI in your CI/CD pipeline as a GitHub Action](https://github.com/datacontract/datacontract-action/)
188
+ - [How to let your coding agent (Claude Code, Codex, GitHub Copilot) create and test data contracts with the Data Contract Skills](https://github.com/datacontract/datacontract-skills)
188
189
  - [How to run the Data Contract CLI API to test data contracts with POST requests](https://docs.datacontract.com/api)
189
190
  - [How to run Data Contract CLI in a Databricks pipeline](https://www.datamesh-architecture.com/howto/build-a-dataproduct-with-databricks#test-the-data-product)
190
191
 
@@ -14,7 +14,7 @@ from pydantic import BaseModel, Field, ValidationError
14
14
  from datacontract.config import Config, known_env_names
15
15
  from datacontract.config.variables import CONTRACT_VARIABLES_ENV, allowed_environment, resolve_variables
16
16
  from datacontract.data_contract import DataContract, ExportFormat
17
- from datacontract.model.breaking import BreakingChangeEntry
17
+ from datacontract.model.breaking import BreakingChangeEntry, Perspective
18
18
  from datacontract.model.changelog import ChangelogEntry
19
19
  from datacontract.model.exceptions import DataContractException, DefinitionResolutionError
20
20
  from datacontract.model.run import Check, ResultEnum, Run
@@ -259,9 +259,10 @@ A posted contract carries SQL and names the hosts to connect to, so the server t
259
259
  untrusted input: a `quality.type: sql` rule must be a read-only query, a credential held in the
260
260
  server's environment is never sent to a host the contract names, a `publish_url` may only point at
261
261
  the Entropy Data platform or the host configured via `ENTROPY_DATA_HOST`, and `servers[].type: local`
262
- is refused so a caller cannot read the server's own files. Set
263
- `DATACONTRACT_CLI_API_ALLOW_LOCAL_FILES=true` if the deployment serves its own files on purpose;
264
- the contract is then still confined to the paths it declares.
262
+ is refused so a caller cannot read the server's own files, and an `api` server's requests may not
263
+ reach a private network address. Set `DATACONTRACT_CLI_API_ALLOW_LOCAL_FILES=true` if the deployment
264
+ serves its own files on purpose; the contract is then still confined to the paths it declares. Set
265
+ `DATACONTRACT_CLI_API_ALLOW_PRIVATE_NETWORK=true` to test APIs in the server's own network.
265
266
 
266
267
  ## Connecting to data sources
267
268
 
@@ -525,6 +526,8 @@ _ENVIRONMENT_CREDENTIAL_TARGETS: dict[str, tuple[str, str | None, tuple[str, ...
525
526
  # option pins it), so an environment-held SASL password can never be paired
526
527
  # with a posted contract safely -- host_field is None, so it is always rejected.
527
528
  "kafka": ("broker host", None, ("kafka_sasl_password",)),
529
+ # Nothing pins an API server's location either.
530
+ "api": ("location", None, ("api_header_authorization", "api_header_x_api_key")),
528
531
  }
529
532
 
530
533
 
@@ -552,6 +555,7 @@ def _selected_server(body: str, server_name: str | None, config):
552
555
  _LOCAL_SERVER_TYPES = frozenset({"local", "duckdb"})
553
556
 
554
557
  ALLOW_LOCAL_FILES_ENV = "DATACONTRACT_CLI_API_ALLOW_LOCAL_FILES"
558
+ ALLOW_PRIVATE_NETWORK_ENV = "DATACONTRACT_CLI_API_ALLOW_PRIVATE_NETWORK"
555
559
  _TRUTHY = frozenset({"1", "true", "yes", "on"})
556
560
 
557
561
 
@@ -570,6 +574,11 @@ def _local_files_allowed() -> bool:
570
574
  return (os.getenv(ALLOW_LOCAL_FILES_ENV) or "").strip().lower() in _TRUTHY
571
575
 
572
576
 
577
+ def _private_network_allowed() -> bool:
578
+ """Whether the operator lets a posted contract's API requests reach private network addresses."""
579
+ return (os.getenv(ALLOW_PRIVATE_NETWORK_ENV) or "").strip().lower() in _TRUTHY
580
+
581
+
573
582
  def _reject_local_server_type(body: str, server_name: str | None, config) -> None:
574
583
  """Keep a posted contract from reading the server's own disk.
575
584
 
@@ -623,20 +632,23 @@ def _reject_environment_credentials_to_untrusted_host(body: str, server_name: st
623
632
  return # no environment-held secret for this server type; nothing to protect
624
633
  if host_field is not None and resolved.option_source(host_field) == "env":
625
634
  return # the operator pinned the target host; the contract's host is ignored
635
+ held = [
636
+ env_name(field, Config.model_fields[field]) for field in secret_fields if resolved.option_source(field) == "env"
637
+ ]
626
638
  if host_field is not None:
627
639
  env_var = env_name(host_field, Config.model_fields[host_field])
628
640
  detail = (
629
- f"This server holds a {server.type} credential in its environment, so the connection "
630
- f"{target_attr} must also come from the server's environment ({env_var}); it will not be "
631
- f"taken from the posted data contract. Set {env_var}, or send the full set of credentials "
632
- f"with the request instead of relying on the server's environment."
641
+ f"This server holds a credential for {server.type} servers in its environment ({', '.join(held)}), so the "
642
+ f"connection {target_attr} must also come from the server's environment ({env_var}); it will not "
643
+ f"be taken from the posted data contract. Set {env_var}, or send the full set of credentials with "
644
+ f"the request instead of relying on the server's environment."
633
645
  )
634
646
  else:
635
647
  detail = (
636
- f"This server holds a {server.type} credential in its environment, but its {target_attr} "
637
- f"can only come from the posted data contract, so the credential cannot be pinned to a "
638
- f"trusted target. Send the credentials with the request instead of relying on the server's "
639
- f"environment."
648
+ f"This server holds a credential for {server.type} servers in its environment ({', '.join(held)}), but "
649
+ f"their {target_attr} can only come from the posted data contract, so the credential cannot be pinned to "
650
+ f"a trusted target. Send the credentials as request headers instead "
651
+ f"({', '.join(name.lower().replace('_', '-') for name in held)})."
640
652
  )
641
653
  raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=detail)
642
654
 
@@ -835,6 +847,7 @@ def test(
835
847
  filters=parsed_filters,
836
848
  untrusted_contract=untrusted_contract,
837
849
  allowed_variables=_allowed_contract_variables(),
850
+ allow_private_network=_private_network_allowed(),
838
851
  ).test()
839
852
 
840
853
 
@@ -943,6 +956,9 @@ class BreakingChangesResponse(BaseModel):
943
956
  entries: list[BreakingChangeEntry] = Field(
944
957
  description="Every single change with its grade and the old and new value.",
945
958
  )
959
+ perspective: Perspective = Field(
960
+ description="Whose expectations the changes were graded against: `consumer` or `producer`.",
961
+ )
946
962
  is_breaking: bool = Field(
947
963
  description="Whether any detected change is classified as an error-level breaking change.",
948
964
  )
@@ -1006,13 +1022,21 @@ parsed is answered with `422`.
1006
1022
  def breaking_endpoint(
1007
1023
  body: ChangelogRequest,
1008
1024
  api_key: Annotated[str | None, Depends(api_key_header)] = None,
1025
+ perspective: Annotated[
1026
+ Perspective,
1027
+ Query(
1028
+ description="`consumer` flags changes that lead to unexpected data for consumers, `producer` flags changes that can make data contract tests fail.",
1029
+ ),
1030
+ ] = Perspective.CONSUMER,
1009
1031
  ) -> BreakingChangesResponse:
1010
1032
  check_api_key(api_key)
1011
1033
 
1012
1034
  result = DataContract(data_contract_str=body.v1, untrusted_contract=True).breaking(
1013
- DataContract(data_contract_str=body.v2, untrusted_contract=True)
1035
+ DataContract(data_contract_str=body.v2, untrusted_contract=True), perspective=perspective
1036
+ )
1037
+ return BreakingChangesResponse(
1038
+ summary=result.summary, entries=result.entries, perspective=result.perspective, is_breaking=result.is_breaking
1014
1039
  )
1015
- return BreakingChangesResponse(summary=result.summary, entries=result.entries, is_breaking=result.is_breaking)
1016
1040
 
1017
1041
 
1018
1042
  @app.post(
@@ -1,8 +1,14 @@
1
1
  from collections import defaultdict
2
2
  from collections.abc import Iterable
3
3
 
4
- from datacontract.breaking.rules import DEFAULT_RULES, BreakingChangeRule
5
- from datacontract.model.breaking import BreakingChangeEntry, BreakingChangeLevel, BreakingChangeResult
4
+ from datacontract.breaking.rules import DEFAULT_RULES, BreakingChangeRule, MetadataFallbackRule
5
+ from datacontract.model.breaking import (
6
+ BreakingChangeEntry,
7
+ BreakingChangeLevel,
8
+ BreakingChangeResult,
9
+ Direction,
10
+ Perspective,
11
+ )
6
12
  from datacontract.model.changelog import ChangelogEntry, ChangelogResult, ChangelogType
7
13
 
8
14
  _LEVEL_ORDER = {
@@ -20,43 +26,22 @@ class BreakingChangeDetector:
20
26
  if not self._rules:
21
27
  raise ValueError("At least one breaking-change rule is required")
22
28
 
23
- def detect(self, changelog: ChangelogResult) -> BreakingChangeResult:
24
- entries = [self._classify(entry) for entry in changelog.entries]
25
- # Nothing inside an added element can break a consumer: it did not exist before.
26
- # Inside a removed one, the element's own entry carries the grade; its former
27
- # constraints are gone, which is a relaxation.
28
- added_or_removed = {
29
+ def detect(
30
+ self, changelog: ChangelogResult, perspective: Perspective, before: dict, after: dict
31
+ ) -> BreakingChangeResult:
32
+ """Grade ``changelog``, built from the normalized contracts ``before`` and ``after``, for ``perspective``."""
33
+ entries = [self._classify(entry, perspective, before, after) for entry in changelog.entries]
34
+ # An added or removed element carries the grade for everything inside it.
35
+ elements = {
29
36
  entry.path
30
37
  for entry in entries
31
38
  if entry.change_type in (ChangelogType.added, ChangelogType.removed)
32
- and (
33
- entry.path.startswith("schema.")
34
- and (len(entry.path.split(".")) == 2 or entry.path.split(".")[-2] in ("properties", "quality"))
35
- )
36
- }
37
- removed_enums = {
38
- entry.path
39
- for entry in entries
40
- if entry.change_type == ChangelogType.removed and entry.path.endswith(".enum")
39
+ and entry.rule_id != MetadataFallbackRule.rule_id
41
40
  }
42
- # Stable IDs may change or swap without changing the set of allowed
43
- # values. Match removed/updated values against additions in the same enum.
44
- added_values = defaultdict(set)
45
41
  for entry in entries:
46
- if entry.rule_id == "enum-constraint-changed" and entry.path.endswith(".value"):
47
- if entry.change_type in (ChangelogType.added, ChangelogType.updated):
48
- added_values[entry.path.rsplit(".enum.", 1)[0]].add(entry.new_value)
49
- for entry in entries:
50
- segments = entry.path.split(".")
51
- if any(".".join(segments[:i]) in added_or_removed for i in range(1, len(segments))):
42
+ if any(entry.path.startswith(f"{path}.") for path in elements):
43
+ entry.direction = None
52
44
  entry.level = BreakingChangeLevel.INFO
53
- if entry.rule_id == "enum-constraint-changed":
54
- if any(entry.path.startswith(path + ".") for path in removed_enums):
55
- entry.level = BreakingChangeLevel.INFO
56
- elif entry.path.endswith(".value") and entry.old_value in added_values.get(
57
- entry.path.rsplit(".enum.", 1)[0], set()
58
- ):
59
- entry.level = BreakingChangeLevel.INFO
60
45
  entries_by_prefix = defaultdict(list)
61
46
  for entry in entries:
62
47
  prefix = ""
@@ -64,16 +49,33 @@ class BreakingChangeDetector:
64
49
  prefix = f"{prefix}.{segment}" if prefix else segment
65
50
  entries_by_prefix[prefix].append(entry)
66
51
  summary = [self._summarize(entry, entries_by_prefix.get(entry.path, [])) for entry in changelog.summary]
67
- return BreakingChangeResult(v1=changelog.v1, v2=changelog.v2, summary=summary, entries=entries)
52
+ return BreakingChangeResult(
53
+ v1=changelog.v1, v2=changelog.v2, perspective=perspective, summary=summary, entries=entries
54
+ )
68
55
 
69
- def _classify(self, entry: ChangelogEntry) -> BreakingChangeEntry:
56
+ def _classify(
57
+ self, entry: ChangelogEntry, perspective: Perspective, before: dict, after: dict
58
+ ) -> BreakingChangeEntry:
70
59
  for rule in self._rules:
71
- evaluation = rule.evaluate(entry)
60
+ evaluation = rule.evaluate(entry, before, after)
72
61
  if evaluation is not None:
62
+ direction = evaluation.direction
63
+ if direction == Direction.BOTH:
64
+ level = BreakingChangeLevel.ERROR
65
+ elif direction == Direction.UNDETERMINED:
66
+ level = BreakingChangeLevel.WARNING
67
+ elif (direction, perspective) in (
68
+ (Direction.TIGHTENS, Perspective.PRODUCER),
69
+ (Direction.LOOSENS, Perspective.CONSUMER),
70
+ ):
71
+ level = BreakingChangeLevel.ERROR
72
+ else:
73
+ level = BreakingChangeLevel.INFO
73
74
  return BreakingChangeEntry(
74
75
  path=entry.path,
75
76
  change_type=entry.type,
76
- level=evaluation.level,
77
+ level=level,
78
+ direction=direction,
77
79
  message=evaluation.message,
78
80
  rule_id=evaluation.rule_id,
79
81
  old_value=entry.old_value,