datacontract-cli 1.2.0__tar.gz → 1.2.1__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 (447) hide show
  1. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/MANIFEST.in +1 -1
  2. {datacontract_cli-1.2.0/datacontract_cli.egg-info → datacontract_cli-1.2.1}/PKG-INFO +45 -38
  3. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/README.md +30 -30
  4. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/api.py +47 -72
  5. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/breaking/detector.py +7 -5
  6. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/breaking/rules.py +47 -2
  7. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/catalog/catalog.py +3 -1
  8. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/changelog/changelog.py +13 -1
  9. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/changelog/normalize.py +8 -7
  10. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/cli.py +57 -1
  11. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_api.py +1 -1
  12. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_breaking.py +2 -8
  13. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_changelog.py +2 -8
  14. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_ci.py +2 -7
  15. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_export.py +28 -10
  16. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_lint.py +9 -8
  17. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_test.py +3 -46
  18. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/config/settings.py +58 -0
  19. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/data_contract.py +23 -5
  20. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/checks/create_checks.py +111 -16
  21. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/checks/dimensions.py +2 -0
  22. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/checks/physical_type_match.py +44 -4
  23. datacontract_cli-1.2.1/datacontract/engines/checks/severity.py +11 -0
  24. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/checks/sql_guard.py +5 -0
  25. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/data_contract_test.py +19 -0
  26. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/fastjsonschema/check_jsonschema.py +6 -4
  27. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +3 -1
  28. datacontract_cli-1.2.1/datacontract/engines/hana/check_hana_execute.py +105 -0
  29. datacontract_cli-1.2.1/datacontract/engines/hana/hana_check_selection.py +76 -0
  30. datacontract_cli-1.2.1/datacontract/engines/hana/hana_connection.py +63 -0
  31. datacontract_cli-1.2.1/datacontract/engines/hana/hana_quality_check.py +707 -0
  32. datacontract_cli-1.2.1/datacontract/engines/hana/hana_schema_check.py +607 -0
  33. datacontract_cli-1.2.1/datacontract/engines/hana/hana_type_mapping.py +205 -0
  34. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/connections/connect.py +108 -11
  35. datacontract_cli-1.2.1/datacontract/engines/ibis/connections/exasol_patch.py +24 -0
  36. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/ibis_check_execute.py +267 -71
  37. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/native_type.py +21 -0
  38. datacontract_cli-1.2.1/datacontract/export/excel_exporter.py +1119 -0
  39. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/great_expectations_exporter.py +58 -19
  40. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/html_exporter.py +3 -1
  41. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/sodacl_check_builder.py +13 -2
  42. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/sql_type_converter.py +8 -0
  43. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/athena_importer.py +2 -1
  44. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/avro_importer.py +6 -6
  45. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/csv_importer.py +20 -6
  46. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/dbml_importer.py +2 -0
  47. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/dbt_importer.py +10 -8
  48. datacontract_cli-1.2.1/datacontract/imports/excel_importer.py +1070 -0
  49. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/glue_importer.py +10 -4
  50. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/iceberg_importer.py +2 -0
  51. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/mysql_importer.py +8 -1
  52. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/object_storage_importer.py +9 -2
  53. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/odcs_helper.py +66 -37
  54. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/oracle_importer.py +8 -1
  55. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/postgres_importer.py +8 -1
  56. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/powerbi_importer.py +15 -6
  57. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/pydantic_importer.py +4 -4
  58. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/redshift_importer.py +8 -1
  59. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/snowflake_importer.py +8 -1
  60. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/spark_importer.py +2 -2
  61. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/spark_type_json.py +2 -2
  62. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/sql_importer.py +61 -18
  63. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/sqlserver_importer.py +8 -1
  64. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/trino_importer.py +8 -1
  65. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/unity_importer.py +5 -2
  66. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/init/init_template.py +3 -1
  67. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/integration/dbt_sync.py +54 -13
  68. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/lint/resolve.py +151 -47
  69. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/lint/schema.py +5 -3
  70. datacontract_cli-1.2.1/datacontract/model/natural_keys.py +18 -0
  71. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/model/run.py +6 -3
  72. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/model/server.py +0 -1
  73. datacontract_cli-1.2.1/datacontract/model/workbook.py +260 -0
  74. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/output/text_breaking_results.py +9 -5
  75. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/output/text_changelog_results.py +8 -4
  76. datacontract_cli-1.2.0/datacontract/templates/excel/odcs-template.xlsx → datacontract_cli-1.2.1/datacontract/templates/excel/odcs-template-v3.0.xlsx +0 -0
  77. datacontract_cli-1.2.1/datacontract/templates/excel/odcs-template-v3.1.xlsx +0 -0
  78. datacontract_cli-1.2.1/datacontract/templates/excel/odcs-template-v3.2.xlsx +0 -0
  79. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1/datacontract_cli.egg-info}/PKG-INFO +45 -38
  80. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract_cli.egg-info/SOURCES.txt +25 -2
  81. datacontract_cli-1.2.1/datacontract_cli.egg-info/dependency_links.txt +1 -0
  82. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract_cli.egg-info/requires.txt +16 -7
  83. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/pyproject.toml +28 -8
  84. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_api.py +112 -17
  85. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_breaking.py +153 -0
  86. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_changelog.py +53 -0
  87. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_changelog_normalize.py +7 -7
  88. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_changelog_output_text.py +25 -6
  89. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_cli.py +10 -1
  90. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_command_api.py +14 -0
  91. datacontract_cli-1.2.1/tests/test_connect_exasol.py +117 -0
  92. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_connect_sqlserver.py +85 -9
  93. datacontract_cli-1.2.1/tests/test_create_checks_nested.py +187 -0
  94. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_create_checks_nested_type.py +28 -3
  95. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_create_checks_servicelevel.py +60 -0
  96. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_dbt_sync.py +116 -4
  97. datacontract_cli-1.2.1/tests/test_export_excel.py +465 -0
  98. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_great_expectations.py +108 -0
  99. datacontract_cli-1.2.1/tests/test_hana_connection.py +99 -0
  100. datacontract_cli-1.2.1/tests/test_hana_quality_check.py +422 -0
  101. datacontract_cli-1.2.1/tests/test_hana_schema_check.py +436 -0
  102. datacontract_cli-1.2.1/tests/test_hana_type_mapping.py +94 -0
  103. datacontract_cli-1.2.1/tests/test_ibis_check_execute.py +152 -0
  104. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_csv.py +9 -1
  105. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_dbt.py +10 -0
  106. datacontract_cli-1.2.1/tests/test_import_excel.py +124 -0
  107. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_iceberg.py +12 -0
  108. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_object_storage.py +47 -0
  109. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_postgres.py +1 -0
  110. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_powerbi.py +0 -1
  111. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_pydantic_model.py +12 -0
  112. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_redshift.py +1 -0
  113. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_spark_type_json.py +2 -2
  114. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_sql_oracle.py +5 -0
  115. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_sql_postgres.py +30 -0
  116. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_sql_snowflake.py +16 -0
  117. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_sql_sqlserver.py +2 -0
  118. datacontract_cli-1.2.1/tests/test_import_unmapped_types.py +94 -0
  119. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_install_extras.py +2 -0
  120. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_lint.py +54 -0
  121. datacontract_cli-1.2.1/tests/test_nested_path_checks.py +102 -0
  122. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_physical_type_match.py +38 -0
  123. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_resolve_definitions.py +18 -1
  124. datacontract_cli-1.2.1/tests/test_row_filter_duplicate_count.py +61 -0
  125. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_servers_3_2_0.py +3 -3
  126. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_snowflake_structured_types.py +1 -3
  127. datacontract_cli-1.2.1/tests/test_test_hana.py +415 -0
  128. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_untrusted_contract.py +17 -0
  129. datacontract_cli-1.2.0/datacontract/export/excel_exporter.py +0 -993
  130. datacontract_cli-1.2.0/datacontract/imports/excel_importer.py +0 -1134
  131. datacontract_cli-1.2.0/datacontract/schemas/odcs-3.0.1.schema.json +0 -2634
  132. datacontract_cli-1.2.0/tests/test_export_excel.py +0 -164
  133. datacontract_cli-1.2.0/tests/test_import_excel.py +0 -49
  134. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/LICENSE +0 -0
  135. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/__init__.py +0 -0
  136. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/breaking/__init__.py +0 -0
  137. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/changelog/__init__.py +0 -0
  138. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_catalog.py +0 -0
  139. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_dbt.py +0 -0
  140. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_edit.py +0 -0
  141. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_import.py +0 -0
  142. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_init.py +0 -0
  143. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/command_publish.py +0 -0
  144. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/config/__init__.py +0 -0
  145. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/config/cli_context.py +0 -0
  146. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/config/variables.py +0 -0
  147. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/editor_assets/VERSION +0 -0
  148. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/editor_assets/assets/editor.worker-4.7.0.js +0 -0
  149. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/editor_assets/assets/yaml.worker-4.7.0.js +0 -0
  150. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/editor_assets/datacontract-editor.css +0 -0
  151. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/editor_assets/datacontract-editor.es.js +0 -0
  152. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/editor_assets/index.html +0 -0
  153. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/editor_assets/logo_fuchsia_v2.svg +0 -0
  154. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/editor_assets/monaco-4.7.0.js +0 -0
  155. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/editor_assets/odcs.svg +0 -0
  156. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/editor_assets/robots.txt +0 -0
  157. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/editor_assets/rolldown-runtime-DY7j01NX.js +0 -0
  158. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/editor_assets/sitemap.xml +0 -0
  159. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/__init__.py +0 -0
  160. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/checks/__init__.py +0 -0
  161. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/checks/check_filter.py +0 -0
  162. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/checks/check_spec.py +0 -0
  163. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/checks/type_normalize.py +0 -0
  164. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/datacontract/check_azure_blob_file.py +0 -0
  165. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
  166. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
  167. /datacontract_cli-1.2.0/datacontract_cli.egg-info/dependency_links.txt → /datacontract_cli-1.2.1/datacontract/engines/hana/__init__.py +0 -0
  168. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/__init__.py +0 -0
  169. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/connections/__init__.py +0 -0
  170. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/connections/aws_credentials.py +0 -0
  171. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/connections/databricks_patch.py +0 -0
  172. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/connections/duckdb_connection.py +0 -0
  173. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/connections/iceberg.py +0 -0
  174. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/connections/kafka.py +0 -0
  175. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/connections/oracle_patch.py +0 -0
  176. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/connections/redshift_credentials.py +0 -0
  177. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/connections/redshift_patch.py +0 -0
  178. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/dtype_category.py +0 -0
  179. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/engines/ibis/snowflake_structured_types.py +0 -0
  180. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/__init__.py +0 -0
  181. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/avro_exporter.py +0 -0
  182. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/avro_idl_exporter.py +0 -0
  183. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/bigquery_exporter.py +0 -0
  184. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/custom_exporter.py +0 -0
  185. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/data_caterer_exporter.py +0 -0
  186. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/dbml_exporter.py +0 -0
  187. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/dbt_exporter.py +0 -0
  188. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/dcs_exporter.py +0 -0
  189. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/dqx_exporter.py +0 -0
  190. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/duckdb_type_converter.py +0 -0
  191. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/exporter.py +0 -0
  192. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/exporter_factory.py +0 -0
  193. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/go_exporter.py +0 -0
  194. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/iceberg_exporter.py +0 -0
  195. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/jsonschema_exporter.py +0 -0
  196. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/markdown_exporter.py +0 -0
  197. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/mermaid_exporter.py +0 -0
  198. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/odcs_v3_exporter.py +0 -0
  199. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/pandas_type_converter.py +0 -0
  200. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/protobuf_exporter.py +0 -0
  201. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/pydantic_exporter.py +0 -0
  202. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/rdf_exporter.py +0 -0
  203. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/sodacl_exporter.py +0 -0
  204. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/spark_exporter.py +0 -0
  205. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/sql_exporter.py +0 -0
  206. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/export/sqlalchemy_exporter.py +0 -0
  207. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/bigquery_importer.py +0 -0
  208. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/dcs_importer.py +0 -0
  209. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/importer.py +0 -0
  210. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/importer_factory.py +0 -0
  211. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/json_importer.py +0 -0
  212. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/jsonschema_importer.py +0 -0
  213. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/odcs_importer.py +0 -0
  214. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/parquet_importer.py +0 -0
  215. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/imports/protobuf_importer.py +0 -0
  216. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/integration/dbt_test_mapping.py +0 -0
  217. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/integration/entropy_data.py +0 -0
  218. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/lint/constraints.py +0 -0
  219. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/lint/files.py +0 -0
  220. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/lint/resources.py +0 -0
  221. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/lint/s3.py +0 -0
  222. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/lint/urls.py +0 -0
  223. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/model/breaking.py +0 -0
  224. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/model/changelog.py +0 -0
  225. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/model/enum_values.py +0 -0
  226. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/model/exceptions.py +0 -0
  227. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/model/map_type.py +0 -0
  228. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/model/odcs.py +0 -0
  229. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/model/vector_type.py +0 -0
  230. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/output/__init__.py +0 -0
  231. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/output/ci_output.py +0 -0
  232. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/output/json_test_results.py +0 -0
  233. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/output/junit_test_results.py +0 -0
  234. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/output/output_format.py +0 -0
  235. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/output/test_results_writer.py +0 -0
  236. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/py.typed +0 -0
  237. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
  238. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
  239. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
  240. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
  241. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/schemas/datacontract-1.2.1.init.yaml +0 -0
  242. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/schemas/datacontract-1.2.1.schema.json +0 -0
  243. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/schemas/odcs-3.0.2.schema.json +0 -0
  244. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/schemas/odcs-3.1.0.schema.json +0 -0
  245. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/schemas/odcs-3.2.0.init.yaml +0 -0
  246. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/schemas/odcs-3.2.0.schema.json +0 -0
  247. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/datacontract.html +0 -0
  248. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/datacontract_odcs.html +0 -0
  249. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/index.html +0 -0
  250. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/macros/authoritative_definitions.html +0 -0
  251. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/macros/context.html +0 -0
  252. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/macros/schema.html +0 -0
  253. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/macros/server.html +0 -0
  254. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/macros/support.html +0 -0
  255. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials/datacontract_information.html +0 -0
  256. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
  257. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials/datacontract_terms.html +0 -0
  258. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials/definition.html +0 -0
  259. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials/example.html +0 -0
  260. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials/model_field.html +0 -0
  261. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials/quality.html +0 -0
  262. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials/server.html +0 -0
  263. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/context.html +0 -0
  264. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/custom_properties.html +0 -0
  265. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/diagram.html +0 -0
  266. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/dialog_yaml.html +0 -0
  267. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/footer.html +0 -0
  268. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/fundamentals.html +0 -0
  269. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/header.html +0 -0
  270. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/pricing.html +0 -0
  271. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/roles.html +0 -0
  272. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/schema.html +0 -0
  273. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/servers.html +0 -0
  274. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/sla.html +0 -0
  275. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/support.html +0 -0
  276. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/team.html +0 -0
  277. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/term_of_use.html +0 -0
  278. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/partials_odcs/title.html +0 -0
  279. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract/templates/style/output.css +0 -0
  280. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract_cli.egg-info/entry_points.txt +0 -0
  281. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/datacontract_cli.egg-info/top_level.txt +0 -0
  282. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/setup.cfg +0 -0
  283. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_api_openapi.py +0 -0
  284. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_breaking_odcs_3_2.py +0 -0
  285. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_catalog.py +0 -0
  286. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_changelog_engine.py +0 -0
  287. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_check_quality_provenance.py +0 -0
  288. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_ci_output.py +0 -0
  289. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_config.py +0 -0
  290. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_config_file.py +0 -0
  291. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_config_require.py +0 -0
  292. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_config_threading.py +0 -0
  293. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_connect_athena.py +0 -0
  294. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_connect_bigquery.py +0 -0
  295. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_connect_databricks.py +0 -0
  296. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_connect_impala.py +0 -0
  297. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_connect_mysql.py +0 -0
  298. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_connect_oracle.py +0 -0
  299. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_connect_postgres.py +0 -0
  300. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_connect_redshift.py +0 -0
  301. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_connect_s3_credentials.py +0 -0
  302. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_connect_snowflake.py +0 -0
  303. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_connect_trino.py +0 -0
  304. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_create_checks_array_items.py +0 -0
  305. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_create_checks_physical_type.py +0 -0
  306. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_create_checks_primary_key.py +0 -0
  307. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_create_checks_retention_period.py +0 -0
  308. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_create_checks_sql_placeholders.py +0 -0
  309. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_data_contract.py +0 -0
  310. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_data_contract_checks.py +0 -0
  311. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_data_contract_specification.py +0 -0
  312. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_dbt_test_mapping.py +0 -0
  313. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_description_linter.py +0 -0
  314. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_docs_commands.py +0 -0
  315. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_docs_config_options.py +0 -0
  316. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_docs_ordering.py +0 -0
  317. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_download_datacontract_file.py +0 -0
  318. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_dtype_category.py +0 -0
  319. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_duckdb_json.py +0 -0
  320. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_edit.py +0 -0
  321. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_enum_values.py +0 -0
  322. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_avro.py +0 -0
  323. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_avro_idl.py +0 -0
  324. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_bigquery.py +0 -0
  325. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_complex_data_contract.py +0 -0
  326. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_custom.py +0 -0
  327. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_custom_exporter.py +0 -0
  328. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_custom_model.py +0 -0
  329. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_data_caterer.py +0 -0
  330. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_dbml.py +0 -0
  331. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_dbt_models.py +0 -0
  332. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_dbt_sources.py +0 -0
  333. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_dbt_staging_sql.py +0 -0
  334. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_dcs.py +0 -0
  335. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_dqx.py +0 -0
  336. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_go.py +0 -0
  337. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_html.py +0 -0
  338. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_iceberg.py +0 -0
  339. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_jsonschema.py +0 -0
  340. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_large_contract.py +0 -0
  341. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_markdown.py +0 -0
  342. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_mermaid.py +0 -0
  343. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_odcs_v3.py +0 -0
  344. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_protobuf.py +0 -0
  345. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_pydantic.py +0 -0
  346. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_rdf.py +0 -0
  347. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_sodacl.py +0 -0
  348. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_spark.py +0 -0
  349. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_sql.py +0 -0
  350. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_sql_clickhouse.py +0 -0
  351. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_sql_query.py +0 -0
  352. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_export_sqlalchemy.py +0 -0
  353. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_ibis_mssql_pattern.py +0 -0
  354. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_ibis_mssql_schema.py +0 -0
  355. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_ibis_oracle_schema.py +0 -0
  356. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_athena.py +0 -0
  357. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_avro.py +0 -0
  358. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_bigquery.py +0 -0
  359. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_dbml.py +0 -0
  360. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_glue.py +0 -0
  361. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_json.py +0 -0
  362. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_jsonschema.py +0 -0
  363. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_mysql.py +0 -0
  364. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_odcs_v3.py +0 -0
  365. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_oracle.py +0 -0
  366. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_parquet.py +0 -0
  367. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_protobuf.py +0 -0
  368. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_snowflake.py +0 -0
  369. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_sqlserver.py +0 -0
  370. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_trino.py +0 -0
  371. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_import_unity_file.py +0 -0
  372. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_integration_entropydata.py +0 -0
  373. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_lint_odcs_3_2_constraints.py +0 -0
  374. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_lint_urls.py +0 -0
  375. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_map_type.py +0 -0
  376. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_metadata_fields.py +0 -0
  377. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_native_type_schema_scope.py +0 -0
  378. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_oracle_patch.py +0 -0
  379. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_publish_test_results.py +0 -0
  380. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_publish_test_results_payload.py +0 -0
  381. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_quality_sql_dialects.py +0 -0
  382. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_redshift_credentials.py +0 -0
  383. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_redshift_patch.py +0 -0
  384. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_resolve.py +0 -0
  385. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_resolve_local_definitions.py +0 -0
  386. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_roundtrip_jsonschema.py +0 -0
  387. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_roundtrip_pydantic_model.py +0 -0
  388. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_run_check_deprecated_fields.py +0 -0
  389. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_run_check_engine.py +0 -0
  390. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_server_overrides.py +0 -0
  391. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_server_type_mssql.py +0 -0
  392. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_server_type_synonyms.py +0 -0
  393. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_sql_type_converter_physicaltype.py +0 -0
  394. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_api.py +0 -0
  395. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_array_items.py +0 -0
  396. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_athena_iceberg.py +0 -0
  397. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_azure_blob_file.py +0 -0
  398. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_azure_remote.py +0 -0
  399. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_bigquery.py +0 -0
  400. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_checks_filter.py +0 -0
  401. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_databricks.py +0 -0
  402. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_delta.py +0 -0
  403. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_diagnostics.py +0 -0
  404. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_dimension_filter.py +0 -0
  405. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_dry_run.py +0 -0
  406. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_duckdb.py +0 -0
  407. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_failed_samples.py +0 -0
  408. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_gcs_csv_remote.py +0 -0
  409. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_gcs_json_remote.py +0 -0
  410. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_iceberg.py +0 -0
  411. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_iceberg_rest.py +0 -0
  412. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_iceberg_s3tables.py +0 -0
  413. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_kafka.py +0 -0
  414. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_kafka_decoding.py +0 -0
  415. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_kafka_remote.py +0 -0
  416. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_local_json.py +0 -0
  417. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_local_json_nd.py +0 -0
  418. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_metadata_only.py +0 -0
  419. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_mysql.py +0 -0
  420. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_oracle.py +0 -0
  421. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_oracle_xe.py +0 -0
  422. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_output_json.py +0 -0
  423. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_output_junit.py +0 -0
  424. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_parquet.py +0 -0
  425. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_postgres.py +0 -0
  426. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_quality.py +0 -0
  427. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_quality_id_and_tag_filter.py +0 -0
  428. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_quality_local_fallback.py +0 -0
  429. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_quality_percent_severity.py +0 -0
  430. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_redshift.py +0 -0
  431. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_row_filter.py +0 -0
  432. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_s3_csv.py +0 -0
  433. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_s3_delta.py +0 -0
  434. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_s3_json.py +0 -0
  435. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_s3_json_complex.py +0 -0
  436. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_s3_json_multiple_models.py +0 -0
  437. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_s3_json_remote.py +0 -0
  438. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_schema_evolution.py +0 -0
  439. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_server_not_found.py +0 -0
  440. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_snowflake.py +0 -0
  441. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_soda_connection_error.py +0 -0
  442. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_sqlserver.py +0 -0
  443. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_trino.py +0 -0
  444. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_test_variables.py +0 -0
  445. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_type_normalize.py +0 -0
  446. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_variables.py +0 -0
  447. {datacontract_cli-1.2.0 → datacontract_cli-1.2.1}/tests/test_vector_type.py +0 -0
@@ -1,5 +1,5 @@
1
1
  include datacontract/templates/style/output.css
2
- include datacontract/templates/excel/odcs-template.xlsx
2
+ include datacontract/templates/excel/*.xlsx
3
3
  recursive-include datacontract/templates/ **/*.html
4
4
  recursive-include datacontract/schemas/ **/*.json **/*.yaml
5
5
  recursive-include datacontract/editor_assets/ *
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datacontract-cli
3
- Version: 1.2.0
3
+ Version: 1.2.1
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
@@ -53,7 +53,7 @@ Requires-Dist: avro==1.12.2; extra == "avro"
53
53
  Provides-Extra: bigquery
54
54
  Requires-Dist: ibis-framework[bigquery]<13.0.0,>=10.0.0; extra == "bigquery"
55
55
  Provides-Extra: csv
56
- Requires-Dist: pandas>=2.0.0; extra == "csv"
56
+ Requires-Dist: datacontract-cli[duckdb]; extra == "csv"
57
57
  Provides-Extra: excel
58
58
  Requires-Dist: openpyxl<4.0.0,>=3.1.5; extra == "excel"
59
59
  Provides-Extra: dataframe
@@ -66,8 +66,8 @@ Requires-Dist: pyarrow-hotfix>=0.4; extra == "dataframe"
66
66
  Requires-Dist: rich>=12.4.4; extra == "dataframe"
67
67
  Provides-Extra: databricks
68
68
  Requires-Dist: ibis-framework[databricks]<13.0.0,>=10.0.0; extra == "databricks"
69
- Requires-Dist: databricks-sql-connector<4.5.0,>=3.7.0; extra == "databricks"
70
- Requires-Dist: databricks-sdk<0.136.0; extra == "databricks"
69
+ Requires-Dist: databricks-sql-connector<4.6.0,>=3.7.0; extra == "databricks"
70
+ Requires-Dist: databricks-sdk<0.140.0; extra == "databricks"
71
71
  Requires-Dist: packaging<27.0,>=21.3; extra == "databricks"
72
72
  Provides-Extra: databricks-runtime
73
73
  Requires-Dist: datacontract-cli[databricks]; extra == "databricks-runtime"
@@ -112,6 +112,13 @@ Requires-Dist: packaging<27.0,>=21.3; extra == "oracle"
112
112
  Provides-Extra: athena
113
113
  Requires-Dist: ibis-framework[athena]<13.0.0,>=10.0.0; extra == "athena"
114
114
  Requires-Dist: packaging<27.0,>=21.3; extra == "athena"
115
+ Provides-Extra: hana
116
+ Requires-Dist: hdbcli<3.0.0,>=2.20.0; extra == "hana"
117
+ Provides-Extra: exasol
118
+ Requires-Dist: ibis-framework[exasol]<13.0.0,>=10.0.0; extra == "exasol"
119
+ Requires-Dist: pyexasol>=1.1.0; extra == "exasol"
120
+ Requires-Dist: packaging<27.0,>=21.3; extra == "exasol"
121
+ Requires-Dist: sqlglot>=26.31.0; extra == "exasol"
115
122
  Provides-Extra: trino
116
123
  Requires-Dist: ibis-framework[trino]<13.0.0,>=10.0.0; extra == "trino"
117
124
  Requires-Dist: packaging<27.0,>=21.3; extra == "trino"
@@ -129,11 +136,11 @@ Provides-Extra: rdf
129
136
  Requires-Dist: rdflib==7.6.0; extra == "rdf"
130
137
  Provides-Extra: api
131
138
  Requires-Dist: fastapi<0.142.0,>=0.115.0; extra == "api"
132
- Requires-Dist: uvicorn<0.53.0,>=0.44.0; extra == "api"
139
+ Requires-Dist: uvicorn<0.54.0,>=0.44.0; extra == "api"
133
140
  Provides-Extra: protobuf
134
141
  Requires-Dist: proto-schema-parser<3.0,>=1.0; extra == "protobuf"
135
142
  Provides-Extra: all
136
- Requires-Dist: datacontract-cli[api,athena,avro,azure,bigquery,csv,databricks,dataframe,dbml,duckdb,excel,gcs,iceberg,impala,kafka,mysql,oracle,parquet,postgres,protobuf,rdf,redshift,s3,snowflake,sqlserver,trino]; extra == "all"
143
+ Requires-Dist: datacontract-cli[api,athena,avro,azure,bigquery,csv,databricks,dataframe,dbml,duckdb,exasol,excel,gcs,iceberg,impala,kafka,mysql,oracle,parquet,postgres,protobuf,rdf,redshift,s3,snowflake,sqlserver,trino]; extra == "all"
137
144
  Provides-Extra: dev
138
145
  Requires-Dist: datacontract-cli[all]; extra == "dev"
139
146
  Requires-Dist: httpx==0.28.1; extra == "dev"
@@ -146,10 +153,10 @@ Requires-Dist: pre-commit<4.7.0,>=3.7.1; extra == "dev"
146
153
  Requires-Dist: pytest; extra == "dev"
147
154
  Requires-Dist: pytest-cov; extra == "dev"
148
155
  Requires-Dist: pytest-xdist; extra == "dev"
149
- Requires-Dist: pymssql==2.4.0; extra == "dev"
156
+ Requires-Dist: pymssql==2.4.1; extra == "dev"
150
157
  Requires-Dist: psycopg2-binary<3.0,>=2.9; extra == "dev"
151
158
  Requires-Dist: mysql-connector-python<26.8.0,>=8.0.30; extra == "dev"
152
- Requires-Dist: ruff==0.16.6; extra == "dev"
159
+ Requires-Dist: ruff==0.16.8; extra == "dev"
153
160
  Requires-Dist: testcontainers[kafka,minio,mssql,mysql,postgres]==4.15.0; extra == "dev"
154
161
  Requires-Dist: trino==0.339.0; extra == "dev"
155
162
  Dynamic: license-file
@@ -412,7 +419,7 @@ Released images are signed with [cosign](https://docs.sigstore.dev/cosign/signin
412
419
  ## Optional Dependencies (Extras)
413
420
 
414
421
  The CLI tool defines several optional dependencies (also known as extras) that can be installed for using with specific servers types.
415
- With _all_, all server dependencies are included.
422
+ With _all_, all server dependencies except `hana` are included.
416
423
 
417
424
  ```bash
418
425
  uv tool install --python python3.11 --upgrade 'datacontract-cli[all]'
@@ -420,35 +427,35 @@ uv tool install --python python3.11 --upgrade 'datacontract-cli[all]'
420
427
 
421
428
  A list of available extras:
422
429
 
423
- | Dependency | Installation Command |
424
- |------------------------------------------|--------------------------------------------|
425
- | Amazon Athena | `pip install datacontract-cli[athena]` |
426
- | Avro Support | `pip install datacontract-cli[avro]` |
427
- | Azure Integration | `pip install datacontract-cli[azure]` |
428
- | Google BigQuery | `pip install datacontract-cli[bigquery]` |
429
- | CSV | `pip install datacontract-cli[csv]` |
430
- | Databricks Integration | `pip install datacontract-cli[databricks]` |
431
- | Databricks Runtime | `pip install datacontract-cli[databricks]` (also inside Databricks, using the cluster's own Spark session) |
432
- | DataFrame (Spark) | `pip install datacontract-cli[dataframe]` (PySpark not included — you supply the Spark session) |
433
- | DBML | `pip install datacontract-cli[dbml]` |
434
- | DuckDB (local/S3/GCS/Azure file testing) | `pip install datacontract-cli[duckdb]` |
435
- | Excel | `pip install datacontract-cli[excel]` |
436
- | GCS Integration | `pip install datacontract-cli[gcs]` |
437
- | Iceberg | `pip install datacontract-cli[iceberg]` |
438
- | Impala | `pip install datacontract-cli[impala]` |
439
- | Kafka Integration | `pip install datacontract-cli[kafka]` |
440
- | MySQL Integration | `pip install datacontract-cli[mysql]` |
441
- | Oracle | `pip install datacontract-cli[oracle]` |
442
- | Parquet | `pip install datacontract-cli[parquet]` |
443
- | PostgreSQL Integration | `pip install datacontract-cli[postgres]` |
444
- | protobuf | `pip install datacontract-cli[protobuf]` |
445
- | RDF | `pip install datacontract-cli[rdf]` |
446
- | Amazon Redshift | `pip install datacontract-cli[redshift]` |
447
- | S3 Integration | `pip install datacontract-cli[s3]` |
448
- | Snowflake Integration | `pip install datacontract-cli[snowflake]` |
449
- | Microsoft SQL Server | `pip install datacontract-cli[sqlserver]` |
450
- | Trino | `pip install datacontract-cli[trino]` |
451
- | API (run as web server) | `pip install datacontract-cli[api]` |
430
+ | Dependency | Installation command |
431
+ |---|---|
432
+ | API (run as web server) | `pip install datacontract-cli[api]` |
433
+ | Amazon Athena | `pip install datacontract-cli[athena]` |
434
+ | Avro | `pip install datacontract-cli[avro]` |
435
+ | Azure | `pip install datacontract-cli[azure]` |
436
+ | Google BigQuery | `pip install datacontract-cli[bigquery]` |
437
+ | Databricks | `pip install datacontract-cli[databricks]` (also inside a Databricks Runtime, using the cluster's own Spark session) |
438
+ | DataFrame (Spark) | `pip install datacontract-cli[dataframe]` (PySpark not included — you supply the Spark session) |
439
+ | DBML | `pip install datacontract-cli[dbml]` |
440
+ | DuckDB (local file, CSV import and API response testing) | `pip install datacontract-cli[duckdb]` |
441
+ | Exasol | `pip install datacontract-cli[exasol]` |
442
+ | Excel | `pip install datacontract-cli[excel]` |
443
+ | GCS | `pip install datacontract-cli[gcs]` |
444
+ | SAP HANA / Datasphere | `pip install datacontract-cli[hana]` (not part of `all`: `hdbcli` is proprietary) |
445
+ | Apache Iceberg (schema import and export, REST catalog testing) | `pip install datacontract-cli[iceberg]` |
446
+ | Impala | `pip install datacontract-cli[impala]` |
447
+ | Kafka | `pip install datacontract-cli[kafka]` |
448
+ | MySQL | `pip install datacontract-cli[mysql]` |
449
+ | Oracle | `pip install datacontract-cli[oracle]` |
450
+ | Parquet | `pip install datacontract-cli[parquet]` |
451
+ | PostgreSQL | `pip install datacontract-cli[postgres]` |
452
+ | Protobuf | `pip install datacontract-cli[protobuf]` |
453
+ | RDF | `pip install datacontract-cli[rdf]` |
454
+ | Amazon Redshift | `pip install datacontract-cli[redshift]` |
455
+ | S3 | `pip install datacontract-cli[s3]` |
456
+ | Snowflake | `pip install datacontract-cli[snowflake]` |
457
+ | Microsoft SQL Server | `pip install datacontract-cli[sqlserver]` |
458
+ | Trino | `pip install datacontract-cli[trino]` |
452
459
 
453
460
 
454
461
  ## Documentation
@@ -256,7 +256,7 @@ Released images are signed with [cosign](https://docs.sigstore.dev/cosign/signin
256
256
  ## Optional Dependencies (Extras)
257
257
 
258
258
  The CLI tool defines several optional dependencies (also known as extras) that can be installed for using with specific servers types.
259
- With _all_, all server dependencies are included.
259
+ With _all_, all server dependencies except `hana` are included.
260
260
 
261
261
  ```bash
262
262
  uv tool install --python python3.11 --upgrade 'datacontract-cli[all]'
@@ -264,35 +264,35 @@ uv tool install --python python3.11 --upgrade 'datacontract-cli[all]'
264
264
 
265
265
  A list of available extras:
266
266
 
267
- | Dependency | Installation Command |
268
- |------------------------------------------|--------------------------------------------|
269
- | Amazon Athena | `pip install datacontract-cli[athena]` |
270
- | Avro Support | `pip install datacontract-cli[avro]` |
271
- | Azure Integration | `pip install datacontract-cli[azure]` |
272
- | Google BigQuery | `pip install datacontract-cli[bigquery]` |
273
- | CSV | `pip install datacontract-cli[csv]` |
274
- | Databricks Integration | `pip install datacontract-cli[databricks]` |
275
- | Databricks Runtime | `pip install datacontract-cli[databricks]` (also inside Databricks, using the cluster's own Spark session) |
276
- | DataFrame (Spark) | `pip install datacontract-cli[dataframe]` (PySpark not included — you supply the Spark session) |
277
- | DBML | `pip install datacontract-cli[dbml]` |
278
- | DuckDB (local/S3/GCS/Azure file testing) | `pip install datacontract-cli[duckdb]` |
279
- | Excel | `pip install datacontract-cli[excel]` |
280
- | GCS Integration | `pip install datacontract-cli[gcs]` |
281
- | Iceberg | `pip install datacontract-cli[iceberg]` |
282
- | Impala | `pip install datacontract-cli[impala]` |
283
- | Kafka Integration | `pip install datacontract-cli[kafka]` |
284
- | MySQL Integration | `pip install datacontract-cli[mysql]` |
285
- | Oracle | `pip install datacontract-cli[oracle]` |
286
- | Parquet | `pip install datacontract-cli[parquet]` |
287
- | PostgreSQL Integration | `pip install datacontract-cli[postgres]` |
288
- | protobuf | `pip install datacontract-cli[protobuf]` |
289
- | RDF | `pip install datacontract-cli[rdf]` |
290
- | Amazon Redshift | `pip install datacontract-cli[redshift]` |
291
- | S3 Integration | `pip install datacontract-cli[s3]` |
292
- | Snowflake Integration | `pip install datacontract-cli[snowflake]` |
293
- | Microsoft SQL Server | `pip install datacontract-cli[sqlserver]` |
294
- | Trino | `pip install datacontract-cli[trino]` |
295
- | API (run as web server) | `pip install datacontract-cli[api]` |
267
+ | Dependency | Installation command |
268
+ |---|---|
269
+ | API (run as web server) | `pip install datacontract-cli[api]` |
270
+ | Amazon Athena | `pip install datacontract-cli[athena]` |
271
+ | Avro | `pip install datacontract-cli[avro]` |
272
+ | Azure | `pip install datacontract-cli[azure]` |
273
+ | Google BigQuery | `pip install datacontract-cli[bigquery]` |
274
+ | Databricks | `pip install datacontract-cli[databricks]` (also inside a Databricks Runtime, using the cluster's own Spark session) |
275
+ | DataFrame (Spark) | `pip install datacontract-cli[dataframe]` (PySpark not included — you supply the Spark session) |
276
+ | DBML | `pip install datacontract-cli[dbml]` |
277
+ | DuckDB (local file, CSV import and API response testing) | `pip install datacontract-cli[duckdb]` |
278
+ | Exasol | `pip install datacontract-cli[exasol]` |
279
+ | Excel | `pip install datacontract-cli[excel]` |
280
+ | GCS | `pip install datacontract-cli[gcs]` |
281
+ | SAP HANA / Datasphere | `pip install datacontract-cli[hana]` (not part of `all`: `hdbcli` is proprietary) |
282
+ | Apache Iceberg (schema import and export, REST catalog testing) | `pip install datacontract-cli[iceberg]` |
283
+ | Impala | `pip install datacontract-cli[impala]` |
284
+ | Kafka | `pip install datacontract-cli[kafka]` |
285
+ | MySQL | `pip install datacontract-cli[mysql]` |
286
+ | Oracle | `pip install datacontract-cli[oracle]` |
287
+ | Parquet | `pip install datacontract-cli[parquet]` |
288
+ | PostgreSQL | `pip install datacontract-cli[postgres]` |
289
+ | Protobuf | `pip install datacontract-cli[protobuf]` |
290
+ | RDF | `pip install datacontract-cli[rdf]` |
291
+ | Amazon Redshift | `pip install datacontract-cli[redshift]` |
292
+ | S3 | `pip install datacontract-cli[s3]` |
293
+ | Snowflake | `pip install datacontract-cli[snowflake]` |
294
+ | Microsoft SQL Server | `pip install datacontract-cli[sqlserver]` |
295
+ | Trino | `pip install datacontract-cli[trino]` |
296
296
 
297
297
 
298
298
  ## Documentation
@@ -2,14 +2,12 @@ import json
2
2
  import logging
3
3
  import os
4
4
  import secrets
5
- import tempfile
6
5
  from importlib import metadata
7
6
  from typing import Annotated, Optional
8
7
 
9
8
  import pydantic
10
- import yaml
11
9
  from fastapi import Body, Depends, FastAPI, HTTPException, Query, Request, status
12
- from fastapi.responses import PlainTextResponse
10
+ from fastapi.responses import JSONResponse, PlainTextResponse
13
11
  from fastapi.security.api_key import APIKeyHeader
14
12
  from pydantic import BaseModel, Field, ValidationError
15
13
 
@@ -20,6 +18,8 @@ from datacontract.model.changelog import ChangelogEntry
20
18
  from datacontract.model.exceptions import DataContractException, DefinitionResolutionError
21
19
  from datacontract.model.run import Check, ResultEnum, Run
22
20
 
21
+ logger = logging.getLogger(__name__)
22
+
23
23
  DATA_CONTRACT_EXAMPLE_PAYLOAD = """apiVersion: v3.2.0
24
24
  kind: DataContract
25
25
  id: orders
@@ -335,6 +335,25 @@ app = FastAPI(
335
335
  ],
336
336
  )
337
337
 
338
+
339
+ @app.exception_handler(pydantic.ValidationError)
340
+ def _validation_error(request: Request, e: pydantic.ValidationError):
341
+ return JSONResponse(status_code=422, content={"detail": f"Invalid data contract: {e}"})
342
+
343
+
344
+ @app.exception_handler(DataContractException)
345
+ def _data_contract_exception(request: Request, e: DataContractException):
346
+ return JSONResponse(status_code=422, content={"detail": f"Data Contract Validation Failure: {e}"})
347
+
348
+
349
+ @app.exception_handler(DefinitionResolutionError)
350
+ def _definition_resolution_error(request: Request, e: DefinitionResolutionError):
351
+ # The reason names the host that was contacted and what it answered.
352
+ # Omit for security reasons.
353
+ logger.warning("Definition resolution failed: %s", e)
354
+ return JSONResponse(status_code=422, content={"detail": f"Could not resolve authoritative definition '{e.url}'."})
355
+
356
+
338
357
  _fastapi_openapi = app.openapi
339
358
 
340
359
 
@@ -481,6 +500,7 @@ _ENVIRONMENT_CREDENTIAL_TARGETS: dict[str, tuple[str, str | None, tuple[str, ...
481
500
  "oracle": ("host", "oracle_host", ("oracle_password",)),
482
501
  "impala": ("host", "impala_host", ("impala_password",)),
483
502
  "trino": ("host", "trino_host", ("trino_password",)),
503
+ "exasol": ("host", "exasol_host", ("exasol_password",)),
484
504
  "redshift": ("host", "redshift_host", ("redshift_password",)),
485
505
  "sqlserver": ("host", "sqlserver_host", ("sqlserver_password",)),
486
506
  "snowflake": (
@@ -665,21 +685,21 @@ def _reject_request_platform_host_with_environment_key(config) -> None:
665
685
  def check_api_key(api_key_header: str | None):
666
686
  correct_api_key = os.getenv("DATACONTRACT_CLI_API_KEY")
667
687
  if correct_api_key is None or correct_api_key == "":
668
- logging.info("Environment variable DATACONTRACT_CLI_API_KEY is not set. Skip API key check.")
688
+ logger.info("Environment variable DATACONTRACT_CLI_API_KEY is not set. Skip API key check.")
669
689
  return
670
690
  if api_key_header is None or api_key_header == "":
671
- logging.info("The API key is missing.")
691
+ logger.warning("The API key is missing.")
672
692
  raise HTTPException(
673
693
  status_code=status.HTTP_401_UNAUTHORIZED,
674
694
  detail="Missing API key. Use Header 'x-api-key' to provide the API key.",
675
695
  )
676
- if not secrets.compare_digest(api_key_header, correct_api_key):
677
- logging.info("The provided API key is not correct.")
696
+ if not secrets.compare_digest(api_key_header.encode(), correct_api_key.encode()):
697
+ logger.warning("The provided API key is not correct.")
678
698
  raise HTTPException(
679
699
  status_code=status.HTTP_403_FORBIDDEN,
680
700
  detail="The provided API key is not correct.",
681
701
  )
682
- logging.info("Request authenticated with API key.")
702
+ logger.info("Request authenticated with API key.")
683
703
  pass
684
704
 
685
705
 
@@ -777,8 +797,7 @@ async def test(
777
797
  status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
778
798
  detail="Use either the filter or the filters parameter, not both.",
779
799
  )
780
- logging.info("Testing data contract...")
781
- logging.info(body)
800
+ logger.info("Testing data contract...")
782
801
  config = config_from_headers(request.headers)
783
802
  untrusted_contract = getattr(request.app.state, "untrusted_contracts", False)
784
803
  if untrusted_contract:
@@ -857,7 +876,10 @@ async def lint(
857
876
  ) -> LintResponse:
858
877
  check_api_key(api_key)
859
878
  data_contract = DataContract(
860
- data_contract_str=body, schema_location=_require_schema_url(schema), all_errors=all_errors
879
+ data_contract_str=body,
880
+ schema_location=_require_schema_url(schema),
881
+ all_errors=all_errors,
882
+ untrusted_contract=True,
861
883
  )
862
884
  lint_result = data_contract.lint()
863
885
  return LintResponse(result=lint_result.result, checks=lint_result.checks)
@@ -933,30 +955,10 @@ async def changelog_endpoint(
933
955
  ) -> ChangelogResponse:
934
956
  check_api_key(api_key)
935
957
 
936
- with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f1:
937
- f1.write(body.v1)
938
- v1_path = f1.name
939
- with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f2:
940
- f2.write(body.v2)
941
- v2_path = f2.name
942
-
943
- try:
944
- result = DataContract(data_contract_file=v1_path).changelog(DataContract(data_contract_file=v2_path))
945
- return ChangelogResponse(summary=result.summary, entries=result.entries)
946
- except yaml.YAMLError as e:
947
- raise HTTPException(status_code=422, detail=f"Invalid YAML: {e}")
948
- except pydantic.ValidationError as e:
949
- raise HTTPException(status_code=422, detail=f"Invalid data contract: {e}")
950
- except DefinitionResolutionError as e:
951
- # The reason names the host that was contacted and what it answered.
952
- # Omit for security reasons.
953
- logging.warning("Definition resolution failed: %s", e)
954
- raise HTTPException(status_code=422, detail=f"Could not resolve authoritative definition '{e.url}'.")
955
- except DataContractException as e:
956
- raise HTTPException(status_code=422, detail=f"Data Contract Validation Failure: {e}")
957
- finally:
958
- os.unlink(v1_path)
959
- os.unlink(v2_path)
958
+ result = DataContract(data_contract_str=body.v1, untrusted_contract=True).changelog(
959
+ DataContract(data_contract_str=body.v2, untrusted_contract=True)
960
+ )
961
+ return ChangelogResponse(summary=result.summary, entries=result.entries)
960
962
 
961
963
 
962
964
  @app.post(
@@ -986,25 +988,10 @@ def breaking_endpoint(
986
988
  ) -> BreakingChangesResponse:
987
989
  check_api_key(api_key)
988
990
 
989
- with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f1:
990
- f1.write(body.v1)
991
- v1_path = f1.name
992
- with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f2:
993
- f2.write(body.v2)
994
- v2_path = f2.name
995
-
996
- try:
997
- result = DataContract(data_contract_file=v1_path).breaking(DataContract(data_contract_file=v2_path))
998
- return BreakingChangesResponse(summary=result.summary, entries=result.entries, is_breaking=result.is_breaking)
999
- except yaml.YAMLError as e:
1000
- raise HTTPException(status_code=422, detail=f"Invalid YAML: {e}")
1001
- except pydantic.ValidationError as e:
1002
- raise HTTPException(status_code=422, detail=f"Invalid data contract: {e}")
1003
- except DataContractException as e:
1004
- raise HTTPException(status_code=422, detail=f"Data Contract Validation Failure: {e}")
1005
- finally:
1006
- os.unlink(v1_path)
1007
- os.unlink(v2_path)
991
+ result = DataContract(data_contract_str=body.v1, untrusted_contract=True).breaking(
992
+ DataContract(data_contract_str=body.v2, untrusted_contract=True)
993
+ )
994
+ return BreakingChangesResponse(summary=result.summary, entries=result.entries, is_breaking=result.is_breaking)
1008
995
 
1009
996
 
1010
997
  @app.post(
@@ -1107,21 +1094,9 @@ def export(
1107
1094
  ] = None,
1108
1095
  ):
1109
1096
  check_api_key(api_key)
1110
- try:
1111
- return DataContract(data_contract_str=body, server=server).export(
1112
- export_format=format,
1113
- model=model,
1114
- rdf_base=rdf_base,
1115
- sql_server_type=sql_server_type,
1116
- )
1117
- except yaml.YAMLError as e:
1118
- raise HTTPException(status_code=422, detail=f"Invalid YAML: {e}")
1119
- except pydantic.ValidationError as e:
1120
- raise HTTPException(status_code=422, detail=f"Invalid data contract: {e}")
1121
- except DefinitionResolutionError as e:
1122
- # The reason names the host that was contacted and what it answered.
1123
- # Omit for security reasons.
1124
- logging.warning("Definition resolution failed: %s", e)
1125
- raise HTTPException(status_code=422, detail=f"Could not resolve authoritative definition '{e.url}'.")
1126
- except DataContractException as e:
1127
- raise HTTPException(status_code=422, detail=f"Data Contract Validation Failure: {e}")
1097
+ return DataContract(data_contract_str=body, server=server, untrusted_contract=True).export(
1098
+ export_format=format,
1099
+ model=model,
1100
+ rdf_base=rdf_base,
1101
+ sql_server_type=sql_server_type,
1102
+ )
@@ -22,14 +22,16 @@ class BreakingChangeDetector:
22
22
 
23
23
  def detect(self, changelog: ChangelogResult) -> BreakingChangeResult:
24
24
  entries = [self._classify(entry) for entry in changelog.entries]
25
- # Nothing inside a newly added element can break a consumer: it did not exist before.
26
- added = {
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 = {
27
29
  entry.path
28
30
  for entry in entries
29
- if entry.change_type == ChangelogType.added
31
+ if entry.change_type in (ChangelogType.added, ChangelogType.removed)
30
32
  and (
31
33
  entry.path.startswith("schema.")
32
- and (len(entry.path.split(".")) == 2 or entry.path.split(".")[-2] == "properties")
34
+ and (len(entry.path.split(".")) == 2 or entry.path.split(".")[-2] in ("properties", "quality"))
33
35
  )
34
36
  }
35
37
  removed_enums = {
@@ -46,7 +48,7 @@ class BreakingChangeDetector:
46
48
  added_values[entry.path.rsplit(".enum.", 1)[0]].add(entry.new_value)
47
49
  for entry in entries:
48
50
  segments = entry.path.split(".")
49
- if any(".".join(segments[:i]) in added for i in range(1, len(segments))):
51
+ if any(".".join(segments[:i]) in added_or_removed for i in range(1, len(segments))):
50
52
  entry.level = BreakingChangeLevel.INFO
51
53
  if entry.rule_id == "enum-constraint-changed":
52
54
  if any(entry.path.startswith(path + ".") for path in removed_enums):
@@ -160,6 +160,50 @@ class EnumConstraintRule(BreakingChangeRule):
160
160
  return RuleEvaluation(self.rule_id, level, _change_message("allowed values", entry))
161
161
 
162
162
 
163
+ class QualityConstraintRule(BreakingChangeRule):
164
+ rule_id = "quality-constraint-changed"
165
+ _thresholds = (
166
+ ".mustBeLessThan",
167
+ ".mustBeLessOrEqualTo",
168
+ ".mustBeGreaterThan",
169
+ ".mustBeGreaterOrEqualTo",
170
+ )
171
+
172
+ def evaluate(self, entry: ChangelogEntry) -> RuleEvaluation | None:
173
+ if not entry.path.startswith("schema.") or ".quality." not in entry.path:
174
+ return None
175
+ rule_path = entry.path.rsplit(".quality.", 1)[1]
176
+ if rule_path.endswith(".arguments.validValues"):
177
+ # The diff emits one entry per list element.
178
+ level = BreakingChangeLevel.INFO if entry.type == ChangelogType.added else BreakingChangeLevel.ERROR
179
+ elif rule_path.endswith(".arguments.invalidValues"):
180
+ level = BreakingChangeLevel.INFO if entry.type == ChangelogType.removed else BreakingChangeLevel.ERROR
181
+ elif rule_path.endswith(self._thresholds):
182
+ old = _parse_number(entry.old_value)
183
+ new = _parse_number(entry.new_value)
184
+ if entry.type == ChangelogType.removed:
185
+ level = BreakingChangeLevel.INFO
186
+ elif old is None or new is None:
187
+ level = BreakingChangeLevel.WARNING
188
+ elif _is_tightening(entry.path, old, new):
189
+ level = BreakingChangeLevel.ERROR
190
+ else:
191
+ level = BreakingChangeLevel.INFO
192
+ elif "." not in rule_path:
193
+ # A new rule is a constraint existing data may not satisfy; a removed one is a relaxation.
194
+ level = BreakingChangeLevel.ERROR if entry.type == ChangelogType.added else BreakingChangeLevel.INFO
195
+ elif rule_path.endswith((".description", ".dimension", ".businessImpact", ".severity")):
196
+ level = BreakingChangeLevel.INFO
197
+ elif ".customProperties." in rule_path or ".authoritativeDefinitions." in rule_path or ".tags" in rule_path:
198
+ level = BreakingChangeLevel.INFO
199
+ else:
200
+ # What the rule checks changed (type, metric, query, other arguments, thresholds we cannot order).
201
+ level = BreakingChangeLevel.WARNING
202
+ name, _, field = rule_path.partition(".")
203
+ subject = f"{field} of quality rule '{name}'" if field else "quality rule"
204
+ return RuleEvaluation(self.rule_id, level, _change_message(subject, entry))
205
+
206
+
163
207
  class VectorShapeRule(BreakingChangeRule):
164
208
  rule_id = "vector-shape-changed"
165
209
 
@@ -206,9 +250,9 @@ def _parse_number(value: str | None) -> float | None:
206
250
 
207
251
 
208
252
  def _is_tightening(path: str, old: float, new: float) -> bool:
209
- if path.endswith((".minLength", ".minimum", ".exclusiveMinimum")):
253
+ if path.endswith((".minLength", ".minimum", ".exclusiveMinimum", ".mustBeGreaterThan", ".mustBeGreaterOrEqualTo")):
210
254
  return new > old
211
- if path.endswith((".maxLength", ".maximum", ".exclusiveMaximum")):
255
+ if path.endswith((".maxLength", ".maximum", ".exclusiveMaximum", ".mustBeLessThan", ".mustBeLessOrEqualTo")):
212
256
  return new < old
213
257
  return True
214
258
 
@@ -222,6 +266,7 @@ def _change_message(subject: str, entry: ChangelogEntry) -> str:
222
266
 
223
267
 
224
268
  DEFAULT_RULES: tuple[BreakingChangeRule, ...] = (
269
+ QualityConstraintRule(),
225
270
  RequiredChangedRule(),
226
271
  SchemaRemovedRule(),
227
272
  FieldRemovedRule(),
@@ -12,6 +12,8 @@ from datacontract.config import cli_config
12
12
  from datacontract.data_contract import DataContract
13
13
  from datacontract.export.html_exporter import get_version
14
14
 
15
+ logger = logging.getLogger(__name__)
16
+
15
17
 
16
18
  def _get_owner(odcs: OpenDataContractStandard) -> Optional[str]:
17
19
  """Get the owner from ODCS customProperties or team."""
@@ -25,7 +27,7 @@ def _get_owner(odcs: OpenDataContractStandard) -> Optional[str]:
25
27
 
26
28
 
27
29
  def create_data_contract_html(contracts, file: Path, path: Path, schema: str):
28
- logging.debug(f"Creating data contract html for file {file} and schema {schema}")
30
+ logger.debug(f"Creating data contract html for file {file} and schema {schema}")
29
31
  data_contract = DataContract(
30
32
  data_contract_file=f"{file.absolute()}", inline_references=True, schema_location=schema, config=cli_config()
31
33
  )
@@ -26,7 +26,19 @@ def diff(v1: dict, v2: dict) -> dict:
26
26
  n1 = normalize(v1)
27
27
  n2 = normalize(v2)
28
28
  result = DeepDiff(n1, n2, ignore_order=True, verbose_level=2)
29
- return json.loads(result.to_json())
29
+ result = json.loads(result.to_json())
30
+ # DeepDiff reports two dicts that share no key as one value change of the whole
31
+ # dict (e.g. the only schema renamed). Split it into per-key removals and additions.
32
+ for path, change in list(result.get("values_changed", {}).items()):
33
+ old, new = change.get("old_value"), change.get("new_value")
34
+ if not (isinstance(old, dict) and isinstance(new, dict)):
35
+ continue
36
+ del result["values_changed"][path]
37
+ for key, value in old.items():
38
+ result.setdefault("dictionary_item_removed", {})[f"{path}['{key}']"] = value
39
+ for key, value in new.items():
40
+ result.setdefault("dictionary_item_added", {})[f"{path}['{key}']"] = value
41
+ return result
30
42
 
31
43
 
32
44
  _CHANGE_TYPE_MAP = {
@@ -66,11 +66,12 @@ description.customProperties[] CustomProperty -> .property
66
66
  def _normalize_by(items: list[dict], key_field: str) -> dict:
67
67
  """Key a list of dicts by a named field, omitting the key field from the value.
68
68
 
69
- Falls back to the list index if the key field is absent on an item.
69
+ Falls back to the list index, as `[i]`, if the key field is absent on an item.
70
+ (Not `__pos_i__`: DeepDiff skips `__*__` keys as private by default.)
70
71
  """
71
72
  result = {}
72
73
  for i, item in enumerate(items):
73
- key = item.get(key_field, f"__pos_{i}__")
74
+ key = item.get(key_field, f"[{i}]")
74
75
  result[key] = {k: v for k, v in item.items() if k != key_field}
75
76
  return result
76
77
 
@@ -84,7 +85,7 @@ def _normalize_auth_defs(items: list[dict]) -> dict:
84
85
  """
85
86
  result = {}
86
87
  for i, item in enumerate(items):
87
- key = item.get("url") or item.get("id") or f"__pos_{i}__"
88
+ key = item.get("url") or item.get("id") or f"[{i}]"
88
89
  result[key] = item
89
90
  return result
90
91
 
@@ -96,7 +97,7 @@ def _normalize_keyed(items: list[dict], *keys: str) -> dict:
96
97
  """
97
98
  result = {}
98
99
  for i, item in enumerate(items):
99
- key = next((str(item[k]) for k in keys if item.get(k) is not None), None) or f"__pos_{i}__"
100
+ key = next((str(item[k]) for k in keys if item.get(k) is not None), None) or f"[{i}]"
100
101
  result[key] = item
101
102
  return result
102
103
 
@@ -126,10 +127,10 @@ def _normalize_relationships(items: list[dict], schema_level: bool = True) -> di
126
127
  elif schema_level:
127
128
  from_val = str(item.get("from", ""))
128
129
  to_val = str(item.get("to", ""))
129
- key = f"{from_val}:{to_val}" if (from_val or to_val) else f"__pos_{i}__"
130
+ key = f"{from_val}:{to_val}" if (from_val or to_val) else f"[{i}]"
130
131
  else:
131
132
  to_val = item.get("to")
132
- key = str(to_val) if to_val else f"__pos_{i}__"
133
+ key = str(to_val) if to_val else f"[{i}]"
133
134
  result[key] = item
134
135
  return result
135
136
 
@@ -138,7 +139,7 @@ def _normalize_quality(items: list[dict]) -> dict:
138
139
  """Key DataQuality items by name (with positional fallback)."""
139
140
  result = {}
140
141
  for i, item in enumerate(items):
141
- key = item.get("name") or f"__pos_{i}__"
142
+ key = item.get("name") or f"[{i}]"
142
143
  entry = {k: v for k, v in item.items() if k != "name"}
143
144
  if "customProperties" in entry and isinstance(entry["customProperties"], list):
144
145
  entry["customProperties"] = _normalize_by(entry["customProperties"], "property")