datacontract-cli 0.9.6.post2__tar.gz → 0.9.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of datacontract-cli might be problematic. Click here for more details.

Files changed (132) hide show
  1. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/PKG-INFO +207 -35
  2. datacontract-cli-0.9.6.post2/datacontract_cli.egg-info/PKG-INFO → datacontract-cli-0.9.8/README.md +191 -65
  3. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/breaking/breaking.py +139 -63
  4. datacontract-cli-0.9.8/datacontract/breaking/breaking_rules.py +94 -0
  5. datacontract-cli-0.9.8/datacontract/cli.py +325 -0
  6. datacontract-cli-0.9.8/datacontract/data_contract.py +488 -0
  7. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +5 -1
  8. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +9 -8
  9. datacontract-cli-0.9.8/datacontract/engines/datacontract/check_that_datacontract_str_is_valid.py +48 -0
  10. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/fastjsonschema/check_jsonschema.py +31 -25
  11. datacontract-cli-0.9.8/datacontract/engines/fastjsonschema/s3/s3_read_files.py +24 -0
  12. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/soda/check_soda_execute.py +46 -35
  13. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/soda/connections/bigquery.py +5 -3
  14. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/soda/connections/dask.py +0 -1
  15. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/soda/connections/databricks.py +2 -2
  16. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/soda/connections/duckdb.py +4 -4
  17. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/soda/connections/kafka.py +36 -17
  18. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/soda/connections/postgres.py +3 -3
  19. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/soda/connections/snowflake.py +4 -4
  20. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/export/avro_converter.py +3 -7
  21. datacontract-cli-0.9.8/datacontract/export/avro_idl_converter.py +280 -0
  22. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/export/dbt_converter.py +55 -80
  23. datacontract-cli-0.9.8/datacontract/export/great_expectations_converter.py +141 -0
  24. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/export/jsonschema_converter.py +3 -1
  25. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/export/odcs_converter.py +10 -12
  26. datacontract-cli-0.9.8/datacontract/export/protobuf_converter.py +99 -0
  27. datacontract-cli-0.9.8/datacontract/export/pydantic_converter.py +140 -0
  28. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/export/rdf_converter.py +35 -12
  29. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/export/sodacl_converter.py +24 -24
  30. datacontract-cli-0.9.8/datacontract/export/sql_converter.py +93 -0
  31. datacontract-cli-0.9.8/datacontract/export/sql_type_converter.py +131 -0
  32. datacontract-cli-0.9.8/datacontract/export/terraform_converter.py +71 -0
  33. datacontract-cli-0.9.8/datacontract/imports/avro_importer.py +106 -0
  34. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/imports/sql_importer.py +0 -2
  35. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/init/download_datacontract_file.py +2 -2
  36. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/integration/publish_datamesh_manager.py +4 -9
  37. datacontract-cli-0.9.8/datacontract/integration/publish_opentelemetry.py +107 -0
  38. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/lint/files.py +2 -2
  39. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/lint/lint.py +46 -31
  40. datacontract-cli-0.9.8/datacontract/lint/linters/description_linter.py +34 -0
  41. datacontract-cli-0.9.8/datacontract/lint/linters/example_model_linter.py +91 -0
  42. datacontract-cli-0.9.8/datacontract/lint/linters/field_pattern_linter.py +34 -0
  43. datacontract-cli-0.9.8/datacontract/lint/linters/field_reference_linter.py +38 -0
  44. datacontract-cli-0.9.8/datacontract/lint/linters/notice_period_linter.py +55 -0
  45. datacontract-cli-0.9.8/datacontract/lint/linters/primary_field_linter.py +28 -0
  46. datacontract-cli-0.9.8/datacontract/lint/linters/quality_schema_linter.py +52 -0
  47. datacontract-cli-0.9.8/datacontract/lint/linters/valid_constraints_linter.py +99 -0
  48. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/lint/resolve.py +53 -8
  49. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/lint/schema.py +2 -3
  50. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/lint/urls.py +4 -5
  51. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/model/breaking_change.py +27 -5
  52. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/model/data_contract_specification.py +45 -25
  53. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/model/exceptions.py +13 -2
  54. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/model/run.py +1 -1
  55. datacontract-cli-0.9.8/datacontract/web.py +14 -0
  56. datacontract-cli-0.9.6.post2/README.md → datacontract-cli-0.9.8/datacontract_cli.egg-info/PKG-INFO +237 -24
  57. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract_cli.egg-info/SOURCES.txt +36 -1
  58. datacontract-cli-0.9.8/datacontract_cli.egg-info/requires.txt +33 -0
  59. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/pyproject.toml +21 -11
  60. datacontract-cli-0.9.8/tests/test_breaking.py +224 -0
  61. datacontract-cli-0.9.8/tests/test_changelog.py +948 -0
  62. datacontract-cli-0.9.8/tests/test_description_linter.py +0 -0
  63. datacontract-cli-0.9.8/tests/test_documentation_linter.py +48 -0
  64. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_download_datacontract_file.py +5 -11
  65. datacontract-cli-0.9.8/tests/test_example_model_linter.py +82 -0
  66. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_bigquery.py +6 -2
  67. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_databricks.py +6 -3
  68. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_examples_csv.py +1 -2
  69. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_examples_inline.py +1 -3
  70. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_examples_json.py +1 -3
  71. datacontract-cli-0.9.8/tests/test_examples_examples_missing.py +23 -0
  72. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_kafka.py +4 -3
  73. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_kafka_remote.py +9 -5
  74. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_local_json.py +0 -2
  75. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_parquet.py +2 -2
  76. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_postgres.py +4 -2
  77. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_s3_csv.py +6 -6
  78. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_s3_json.py +6 -17
  79. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_s3_json_complex.py +5 -5
  80. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_s3_json_multiple_models.py +5 -5
  81. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_s3_json_remote.py +8 -5
  82. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_export_avro.py +2 -6
  83. datacontract-cli-0.9.8/tests/test_export_avro_idl.py +143 -0
  84. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_export_dbt_models.py +3 -8
  85. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_export_dbt_sources.py +4 -8
  86. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_export_dbt_staging_sql.py +12 -9
  87. datacontract-cli-0.9.8/tests/test_export_great_expectations.py +222 -0
  88. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_export_jsonschema.py +4 -8
  89. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_export_odcs.py +2 -6
  90. datacontract-cli-0.9.8/tests/test_export_protobuf.py +59 -0
  91. datacontract-cli-0.9.8/tests/test_export_pydantic.py +115 -0
  92. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_export_rdf.py +13 -21
  93. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_export_sodacl.py +4 -5
  94. datacontract-cli-0.9.8/tests/test_export_sql.py +70 -0
  95. datacontract-cli-0.9.8/tests/test_export_sql_query.py +46 -0
  96. datacontract-cli-0.9.8/tests/test_export_terraform.py +36 -0
  97. datacontract-cli-0.9.8/tests/test_field_constraint_linter.py +68 -0
  98. datacontract-cli-0.9.8/tests/test_field_pattern_linter.py +42 -0
  99. datacontract-cli-0.9.8/tests/test_field_reference_linter.py +56 -0
  100. datacontract-cli-0.9.8/tests/test_import_avro.py +77 -0
  101. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_import_sql.py +15 -9
  102. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_integration_datameshmanager.py +0 -1
  103. datacontract-cli-0.9.8/tests/test_integration_opentelemetry.py +76 -0
  104. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_lint.py +13 -4
  105. datacontract-cli-0.9.8/tests/test_notice_period_linter.py +47 -0
  106. datacontract-cli-0.9.8/tests/test_primary_field_linter.py +38 -0
  107. datacontract-cli-0.9.8/tests/test_quality_schema_linter.py +35 -0
  108. datacontract-cli-0.9.8/tests/test_schema.py +54 -0
  109. datacontract-cli-0.9.8/tests/test_web.py +17 -0
  110. datacontract-cli-0.9.6.post2/datacontract/breaking/breaking_rules.py +0 -77
  111. datacontract-cli-0.9.6.post2/datacontract/cli.py +0 -232
  112. datacontract-cli-0.9.6.post2/datacontract/data_contract.py +0 -250
  113. datacontract-cli-0.9.6.post2/datacontract/engines/datacontract/check_that_datacontract_str_is_valid.py +0 -44
  114. datacontract-cli-0.9.6.post2/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -22
  115. datacontract-cli-0.9.6.post2/datacontract/lint/linters/example_model_linter.py +0 -67
  116. datacontract-cli-0.9.6.post2/datacontract/web.py +0 -17
  117. datacontract-cli-0.9.6.post2/datacontract_cli.egg-info/requires.txt +0 -28
  118. datacontract-cli-0.9.6.post2/tests/test_breaking.py +0 -366
  119. datacontract-cli-0.9.6.post2/tests/test_linters.py +0 -108
  120. datacontract-cli-0.9.6.post2/tests/test_schema.py +0 -54
  121. datacontract-cli-0.9.6.post2/tests/test_web.py +0 -36
  122. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/LICENSE +0 -0
  123. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/__init__.py +0 -0
  124. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/__init__.py +0 -0
  125. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/engines/soda/__init__.py +0 -0
  126. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract/lint/linters/__init__.py +0 -0
  127. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract_cli.egg-info/dependency_links.txt +0 -0
  128. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract_cli.egg-info/entry_points.txt +0 -0
  129. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/datacontract_cli.egg-info/top_level.txt +0 -0
  130. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/setup.cfg +0 -0
  131. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_cli.py +0 -0
  132. {datacontract-cli-0.9.6.post2 → datacontract-cli-0.9.8}/tests/test_examples_snowflake.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: datacontract-cli
3
- Version: 0.9.6.post2
3
+ Version: 0.9.8
4
4
  Summary: Test data contracts
5
5
  Author-email: Jochen Christ <jochen.christ@innoq.com>, Stefan Negele <stefan.negele@innoq.com>
6
6
  Project-URL: Homepage, https://cli.datacontract.com
@@ -11,7 +11,7 @@ Classifier: Operating System :: OS Independent
11
11
  Requires-Python: >=3.10
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: typer[all]~=0.9.0
14
+ Requires-Dist: typer[all]<0.13,>=0.9
15
15
  Requires-Dist: pydantic<2.7.0,>=2.5.3
16
16
  Requires-Dist: pyyaml~=6.0.1
17
17
  Requires-Dist: requests~=2.31.0
@@ -19,22 +19,27 @@ Requires-Dist: fastapi==0.110.0
19
19
  Requires-Dist: fastparquet==2024.2.0
20
20
  Requires-Dist: python-multipart==0.0.9
21
21
  Requires-Dist: rich~=13.7.0
22
- Requires-Dist: simple-ddl-parser==1.0.3
23
- Requires-Dist: soda-core-bigquery~=3.2.1
24
- Requires-Dist: soda-core-duckdb~=3.2.1
25
- Requires-Dist: soda-core-postgres~=3.2.1
26
- Requires-Dist: soda-core-snowflake~=3.2.1
27
- Requires-Dist: soda-core-spark[databricks]~=3.2.1
28
- Requires-Dist: soda-core-spark-df~=3.2.1
22
+ Requires-Dist: simple-ddl-parser==1.0.4
23
+ Requires-Dist: soda-core-bigquery<3.4.0,>=3.3.1
24
+ Requires-Dist: soda-core-duckdb<3.4.0,>=3.3.1
25
+ Requires-Dist: soda-core-postgres<3.4.0,>=3.3.1
26
+ Requires-Dist: soda-core-snowflake<3.4.0,>=3.3.1
27
+ Requires-Dist: soda-core-spark[databricks]<3.4.0,>=3.3.1
28
+ Requires-Dist: soda-core-spark-df<3.4.0,>=3.3.1
29
29
  Requires-Dist: snowflake-connector-python[pandas]<3.8,>=3.6
30
- Requires-Dist: duckdb==0.10.0
30
+ Requires-Dist: duckdb==0.10.1
31
31
  Requires-Dist: fastjsonschema~=2.19.1
32
32
  Requires-Dist: python-dotenv~=1.0.0
33
- Requires-Dist: s3fs==2024.2.0
33
+ Requires-Dist: s3fs==2024.3.1
34
34
  Requires-Dist: rdflib==7.0.0
35
+ Requires-Dist: avro==1.11.3
36
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc~=1.16.0
37
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http~=1.16.0
35
38
  Provides-Extra: dev
36
39
  Requires-Dist: httpx==0.27.0; extra == "dev"
40
+ Requires-Dist: ruff; extra == "dev"
37
41
  Requires-Dist: pytest; extra == "dev"
42
+ Requires-Dist: testcontainers<4.0; extra == "dev"
38
43
  Requires-Dist: testcontainers-minio; extra == "dev"
39
44
  Requires-Dist: testcontainers-postgres; extra == "dev"
40
45
  Requires-Dist: testcontainers-kafka; extra == "dev"
@@ -52,6 +57,16 @@ Requires-Dist: testcontainers-kafka; extra == "dev"
52
57
  The `datacontract` CLI is an open source command-line tool for working with [Data Contracts](https://datacontract.com/).
53
58
  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.
54
59
 
60
+ ![Main features of the Data Contract CLI](datacontractcli.png)
61
+
62
+ <div align="center">
63
+ <a href="https://www.youtube.com/watch?v=B1dixhgO2vQ">
64
+ <img
65
+ src="https://img.youtube.com/vi/B1dixhgO2vQ/0.jpg"
66
+ alt="Demo of Data Contract CLI"
67
+ style="width:100%;">
68
+ </a>
69
+ </div>
55
70
 
56
71
  ## Getting started
57
72
 
@@ -123,20 +138,20 @@ $ datacontract test --examples datacontract.yaml
123
138
  # find differences between to data contracts (Coming Soon)
124
139
  $ datacontract diff datacontract-v1.yaml datacontract-v2.yaml
125
140
 
126
- # fail pipeline on breaking changes (Coming Soon)
141
+ # find differences between to data contracts categorized into error, warning, and info.
142
+ $ datacontract changelog datacontract-v1.yaml datacontract-v2.yaml
143
+
144
+ # fail pipeline on breaking changes. Uses changelog internally and showing only error and warning.
127
145
  $ datacontract breaking datacontract-v1.yaml datacontract-v2.yaml
128
146
 
129
- # export model as jsonschema
147
+ # export model as jsonschema (other formats: avro, dbt, dbt-sources, dbt-staging-sql, jsonschema, odcs, rdf, sql (coming soon), sodacl, terraform)
130
148
  $ datacontract export --format jsonschema datacontract.yaml
131
149
 
132
- # export model as dbt
133
- $ datacontract export --format dbt datacontract.yaml
134
-
135
150
  # import sql
136
151
  $ datacontract import --format sql --source my_ddl.sql
137
152
 
138
- # import protobuf as model (Coming Soon)
139
- $ datacontract import --format protobuf --source my_protobuf_file.proto datacontract.yaml
153
+ # import avro
154
+ $ datacontract import --format avro --source avro_schema.avsc
140
155
  ```
141
156
 
142
157
  ## Programmatic (Python)
@@ -150,7 +165,15 @@ if not run.has_passed():
150
165
  # Abort pipeline, alert, or take corrective actions...
151
166
  ```
152
167
 
153
- ## Scenario: Integration with Data Mesh Manager
168
+ ## Integrations
169
+
170
+
171
+ | Integration | Option | Description |
172
+ |-------------------|------------------------------|-------------------------------------------------------------------------------------------------------|
173
+ | Data Mesh Manager | `--publish` | Push full results to the [Data Mesh Manager API](https://api.datamesh-manager.com/swagger/index.html) |
174
+ | OpenTelemetry | `--publish-to-opentelemetry` | Push result as gauge metrics (logs are planned) |
175
+
176
+ ### Integration with Data Mesh Manager
154
177
 
155
178
  If you use [Data Mesh Manager](https://datamesh-manager.com/), you can use the data contract URL and append the `--publish` option to send and display the test results. Set an environment variable for your API key.
156
179
 
@@ -160,9 +183,34 @@ $ EXPORT DATAMESH_MANAGER_API_KEY=xxx
160
183
  $ datacontract test https://demo.datamesh-manager.com/demo279750347121/datacontracts/4df9d6ee-e55d-4088-9598-b635b2fdcbbc/datacontract.yaml --server production --publish
161
184
  ```
162
185
 
186
+ ### Integration with OpenTelemetry
163
187
 
188
+ If you use OpenTelemetry, you can use the data contract URL and append the `--publish-to-opentelemetry` option to send the test results to your OLTP-compatible instance, e.g., Prometheus.
164
189
 
190
+ The metric name is "datacontract.cli.test.result" and it uses the following encoding for the result:
165
191
 
192
+ | datacontract.cli.test.result | Description |
193
+ |-------|---------------------------------------|
194
+ | 0 | test run passed, no warnings |
195
+ | 1 | test run has warnings |
196
+ | 2 | test run failed |
197
+ | 3 | test run not possible due to an error |
198
+ | 4 | test status unknown |
199
+
200
+
201
+ ```bash
202
+ # Fetch current data contract, execute tests on production, and publish result to open telemetry
203
+ $ EXPORT OTEL_SERVICE_NAME=datacontract-cli
204
+ $ EXPORT OTEL_EXPORTER_OTLP_ENDPOINT=https://YOUR_ID.apm.westeurope.azure.elastic-cloud.com:443
205
+ $ EXPORT OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer%20secret # Optional, when using SaaS Products
206
+ $ EXPORT OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf # Optional, default is http/protobuf - use value grpc to use the gRPC protocol instead
207
+ # Send to OpenTelemetry
208
+ $ datacontract test https://demo.datamesh-manager.com/demo279750347121/datacontracts/4df9d6ee-e55d-4088-9598-b635b2fdcbbc/datacontract.yaml --server production --publish-to-opentelemetry
209
+ ```
210
+
211
+ Current limitations:
212
+ - currently, only ConsoleExporter and OTLP Exporter
213
+ - Metrics only, no logs yet (but loosely planned)
166
214
 
167
215
  ## Installation
168
216
 
@@ -451,20 +499,36 @@ datacontract export --format dbt
451
499
 
452
500
  Available export options:
453
501
 
454
- | Type | Description | Status |
455
- |--------------------|---------------------------------------------------------|--------|
456
- | `jsonschema` | Export to JSON Schema | ✅ |
457
- | `odcs` | Export to Open Data Contract Standard (ODCS) | ✅ |
458
- | `sodacl` | Export to SodaCL quality checks in YAML format | ✅ |
459
- | `dbt` | Export to dbt models in YAML format | ✅ |
460
- | `dbt-sources` | Export to dbt sources in YAML format | ✅ |
461
- | `dbt-staging-sql` | Export to dbt staging SQL models | ✅ |
462
- | `rdf` | Export data contract to RDF representation in N3 format | ✅ |
463
- | `avro` | Export to AVRO models | ✅ |
464
- | `pydantic` | Export to pydantic models | TBD |
465
- | `sql` | Export to SQL DDL | TBD |
466
- | `protobuf` | Export to Protobuf | TBD |
467
- | Missing something? | Please create an issue on GitHub | TBD |
502
+ | Type | Description | Status |
503
+ |----------------------|---------------------------------------------------------|--------|
504
+ | `jsonschema` | Export to JSON Schema | ✅ |
505
+ | `odcs` | Export to Open Data Contract Standard (ODCS) | ✅ |
506
+ | `sodacl` | Export to SodaCL quality checks in YAML format | ✅ |
507
+ | `dbt` | Export to dbt models in YAML format | ✅ |
508
+ | `dbt-sources` | Export to dbt sources in YAML format | ✅ |
509
+ | `dbt-staging-sql` | Export to dbt staging SQL models | ✅ |
510
+ | `rdf` | Export data contract to RDF representation in N3 format | ✅ |
511
+ | `avro` | Export to AVRO models | ✅ |
512
+ | `protobuf` | Export to Protobuf | |
513
+ | `terraform` | Export to terraform resources | |
514
+ | `sql` | Export to SQL DDL | |
515
+ | `sql-query` | Export to SQL Query | |
516
+ | `great-expectations` | Export to Great Expectations Suites in JSON Format | ✅ |
517
+ | `bigquery` | Export to BigQuery Schemas | TBD |
518
+ | `pydantic` | Export to pydantic models | TBD |
519
+ | `html` | Export to HTML page | TBD |
520
+ | Missing something? | Please create an issue on GitHub | TBD |
521
+
522
+ #### Great Expectations
523
+ The export function transforms a specified data contract into a comprehensive Great Expectations JSON suite.
524
+ If the contract includes multiple models, you need to specify the names of the model you wish to export.
525
+ ```shell
526
+ datacontract export datacontract.yaml --format great-expectations --model orders
527
+ ```
528
+ The export creates a list of expectations by utilizing:
529
+
530
+ - The data from the Model definition with a fixed mapping
531
+ - The expectations provided in the quality field for each model (find here the expectations gallery https://greatexpectations.io/expectations/)
468
532
 
469
533
  #### RDF
470
534
 
@@ -502,13 +566,120 @@ Available import options:
502
566
  | Type | Description | Status |
503
567
  |--------------------|------------------------------------------------|---------|
504
568
  | `sql` | Import from SQL DDL | ✅ |
569
+ | `avro` | Import from AVRO schemas | ✅ |
505
570
  | `protobuf` | Import from Protobuf schemas | TBD |
506
- | `avro` | Import from AVRO schemas | TBD |
507
571
  | `jsonschema` | Import from JSON Schemas | TBD |
572
+ | `bigquery` | Import from BigQuery Schemas | TBD |
508
573
  | `dbt` | Import from dbt models | TBD |
509
574
  | `odcs` | Import from Open Data Contract Standard (ODCS) | TBD |
510
575
  | Missing something? | Please create an issue on GitHub | TBD |
511
576
 
577
+ ## Best Practices
578
+
579
+ We share best practices in using the Data Contract CLI.
580
+
581
+ ### Data-first Approach
582
+
583
+ Create a data contract based on the actual data. This is the fastest way to get started and to get feedback from the data consumers.
584
+
585
+ 1. Use an existing physical schema (e.g., SQL DDL) as a starting point to define your logical data model in the contract. Double check right after the import whether the actual data meets the imported logical data model. Just to be sure.
586
+ ```bash
587
+ $ datacontract import --format sql ddl.sql
588
+ $ datacontract test
589
+ ```
590
+
591
+ 2. Add examples to the `datacontract.yaml`. If you can, use actual data and anonymize. Make sure that the examples match the imported logical data model.
592
+ ```bash
593
+ $ datacontract test --examples
594
+ ```
595
+
596
+
597
+ 3. Add quality checks and additional type constraints one by one to the contract and make sure the examples and the actual data still adheres to the contract. Check against examples for a very fast feedback loop.
598
+ ```bash
599
+ $ datacontract test --examples
600
+ $ datacontract test
601
+ ```
602
+
603
+ 4. Make sure that all the best practices for a `datacontract.yaml` are met using the linter. You probably forgot to document some fields and add the terms and conditions.
604
+ ```bash
605
+ $ datacontract lint
606
+ ```
607
+
608
+ 5. Set up a CI pipeline that executes daily and reports the results to the [Data Mesh Manager](https://datamesh-manager.com). Or to some place else. You can even publish to any opentelemetry compatible system.
609
+ ```bash
610
+ $ datacontract test --publish https://api.datamesh-manager.com/api/runs
611
+ ```
612
+
613
+ ### Contract-First
614
+
615
+ Create a data contract based on the requirements from use cases.
616
+
617
+ 1. Start with a `datacontract.yaml` template.
618
+ ```bash
619
+ $ datacontract init
620
+ ```
621
+
622
+ 2. Add examples to the `datacontract.yaml`. Do not start with the data model, although you are probably tempted to do that. Examples are the fastest way to get feedback from everybody and not loose someone in the discussion.
623
+
624
+ 3. Create the model based on the examples. Test the model against the examples to double-check whether the model matches the examples.
625
+ ```bash
626
+ $ datacontract test --examples
627
+ ```
628
+
629
+ 4. Add quality checks and additional type constraints one by one to the contract and make sure the examples and the actual data still adheres to the contract. Check against examples for a very fast feedback loop.
630
+ ```bash
631
+ $ datacontract test --examples
632
+ ```
633
+
634
+ 5. Fill in the terms, descriptions, etc. Make sure you follow all best practices for a `datacontract.yaml` using the linter.
635
+ ```bash
636
+ $ datacontract lint
637
+ ```
638
+
639
+ 6. Set up a CI pipeline that lints and tests the examples so you make sure that any changes later do not decrease the quality of the contract.
640
+ ```bash
641
+ $ datacontract lint
642
+ $ datacontract test --examples
643
+ ```
644
+
645
+ 7. Use the export function to start building the providing data product as well as the integration into the consuming data products.
646
+ ```bash
647
+ # data provider
648
+ $ datacontract export --format dbt
649
+ # data consumer
650
+ $ datacontract export --format dbt-sources
651
+ $ datacontract export --format dbt-staging-sql
652
+ ```
653
+
654
+ ### Schema Evolution
655
+
656
+ #### Non-breaking Changes
657
+ Examples: adding models or fields
658
+
659
+ - Add the models or fields in the datacontract.yaml
660
+ - Increment the minor version of the datacontract.yaml on any change. Simply edit the datacontract.yaml for this.
661
+ - You need a policy that these changes are non-breaking. That means that one cannot use the star expression in SQL to query a table under contract. Make the consequences known.
662
+ - Fail the build in the Pull Request if a datacontract.yaml accidentially adds a breaking change even despite only a minor version change
663
+ ```bash
664
+ $ datacontract breaking datacontract-from-pr.yaml datacontract-from-main.yaml
665
+ ```
666
+ - Create a changelog of this minor change.
667
+ ```bash
668
+ $ datacontract changelog datacontract-from-pr.yaml datacontract-from-main.yaml
669
+ ```
670
+ #### Breaking Changes
671
+ Examples: Removing or renaming models and fields.
672
+
673
+ - Remove or rename models and fields in the datacontract.yaml, and any other change that might be part of this new major version of this data contract.
674
+ - Increment the major version of the datacontract.yaml for this and create a new file for the major version. The reason being, that one needs to offer an upgrade path for the data consumers from the old to the new major version.
675
+ - As data consumers need to migrate, try to reduce the frequency of major versions by making multiple breaking changes together if possible.
676
+ - Be aware of the notice period in the data contract as this is the minimum amount of time you have to offer both the old and the new version for a migration path.
677
+ - Do not fear making breaking changes with data contracts. It's okay to do them in this controlled way. Really!
678
+ - Create a changelog of this major change.
679
+ ```bash
680
+ $ datacontract changelog datacontract-from-pr.yaml datacontract-from-main.yaml
681
+ ```
682
+
512
683
  ## Development Setup
513
684
 
514
685
  Python base interpreter should be 3.11.x (unless working on 3.12 release candidate).
@@ -521,7 +692,8 @@ source venv/bin/activate
521
692
  # Install Requirements
522
693
  pip install --upgrade pip setuptools wheel
523
694
  pip install -e '.[dev]'
524
- cd tests/
695
+ ruff check --fix
696
+ ruff format --check
525
697
  pytest
526
698
  ```
527
699
 
@@ -1,44 +1,3 @@
1
- Metadata-Version: 2.1
2
- Name: datacontract-cli
3
- Version: 0.9.6.post2
4
- Summary: Test data contracts
5
- Author-email: Jochen Christ <jochen.christ@innoq.com>, Stefan Negele <stefan.negele@innoq.com>
6
- Project-URL: Homepage, https://cli.datacontract.com
7
- Project-URL: Issues, https://github.com/datacontract/cli/issues
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.10
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
- Requires-Dist: typer[all]~=0.9.0
15
- Requires-Dist: pydantic<2.7.0,>=2.5.3
16
- Requires-Dist: pyyaml~=6.0.1
17
- Requires-Dist: requests~=2.31.0
18
- Requires-Dist: fastapi==0.110.0
19
- Requires-Dist: fastparquet==2024.2.0
20
- Requires-Dist: python-multipart==0.0.9
21
- Requires-Dist: rich~=13.7.0
22
- Requires-Dist: simple-ddl-parser==1.0.3
23
- Requires-Dist: soda-core-bigquery~=3.2.1
24
- Requires-Dist: soda-core-duckdb~=3.2.1
25
- Requires-Dist: soda-core-postgres~=3.2.1
26
- Requires-Dist: soda-core-snowflake~=3.2.1
27
- Requires-Dist: soda-core-spark[databricks]~=3.2.1
28
- Requires-Dist: soda-core-spark-df~=3.2.1
29
- Requires-Dist: snowflake-connector-python[pandas]<3.8,>=3.6
30
- Requires-Dist: duckdb==0.10.0
31
- Requires-Dist: fastjsonschema~=2.19.1
32
- Requires-Dist: python-dotenv~=1.0.0
33
- Requires-Dist: s3fs==2024.2.0
34
- Requires-Dist: rdflib==7.0.0
35
- Provides-Extra: dev
36
- Requires-Dist: httpx==0.27.0; extra == "dev"
37
- Requires-Dist: pytest; extra == "dev"
38
- Requires-Dist: testcontainers-minio; extra == "dev"
39
- Requires-Dist: testcontainers-postgres; extra == "dev"
40
- Requires-Dist: testcontainers-kafka; extra == "dev"
41
-
42
1
  # Data Contract CLI
43
2
 
44
3
  <p>
@@ -52,6 +11,16 @@ Requires-Dist: testcontainers-kafka; extra == "dev"
52
11
  The `datacontract` CLI is an open source command-line tool for working with [Data Contracts](https://datacontract.com/).
53
12
  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.
54
13
 
14
+ ![Main features of the Data Contract CLI](datacontractcli.png)
15
+
16
+ <div align="center">
17
+ <a href="https://www.youtube.com/watch?v=B1dixhgO2vQ">
18
+ <img
19
+ src="https://img.youtube.com/vi/B1dixhgO2vQ/0.jpg"
20
+ alt="Demo of Data Contract CLI"
21
+ style="width:100%;">
22
+ </a>
23
+ </div>
55
24
 
56
25
  ## Getting started
57
26
 
@@ -123,20 +92,20 @@ $ datacontract test --examples datacontract.yaml
123
92
  # find differences between to data contracts (Coming Soon)
124
93
  $ datacontract diff datacontract-v1.yaml datacontract-v2.yaml
125
94
 
126
- # fail pipeline on breaking changes (Coming Soon)
95
+ # find differences between to data contracts categorized into error, warning, and info.
96
+ $ datacontract changelog datacontract-v1.yaml datacontract-v2.yaml
97
+
98
+ # fail pipeline on breaking changes. Uses changelog internally and showing only error and warning.
127
99
  $ datacontract breaking datacontract-v1.yaml datacontract-v2.yaml
128
100
 
129
- # export model as jsonschema
101
+ # export model as jsonschema (other formats: avro, dbt, dbt-sources, dbt-staging-sql, jsonschema, odcs, rdf, sql (coming soon), sodacl, terraform)
130
102
  $ datacontract export --format jsonschema datacontract.yaml
131
103
 
132
- # export model as dbt
133
- $ datacontract export --format dbt datacontract.yaml
134
-
135
104
  # import sql
136
105
  $ datacontract import --format sql --source my_ddl.sql
137
106
 
138
- # import protobuf as model (Coming Soon)
139
- $ datacontract import --format protobuf --source my_protobuf_file.proto datacontract.yaml
107
+ # import avro
108
+ $ datacontract import --format avro --source avro_schema.avsc
140
109
  ```
141
110
 
142
111
  ## Programmatic (Python)
@@ -150,7 +119,15 @@ if not run.has_passed():
150
119
  # Abort pipeline, alert, or take corrective actions...
151
120
  ```
152
121
 
153
- ## Scenario: Integration with Data Mesh Manager
122
+ ## Integrations
123
+
124
+
125
+ | Integration | Option | Description |
126
+ |-------------------|------------------------------|-------------------------------------------------------------------------------------------------------|
127
+ | Data Mesh Manager | `--publish` | Push full results to the [Data Mesh Manager API](https://api.datamesh-manager.com/swagger/index.html) |
128
+ | OpenTelemetry | `--publish-to-opentelemetry` | Push result as gauge metrics (logs are planned) |
129
+
130
+ ### Integration with Data Mesh Manager
154
131
 
155
132
  If you use [Data Mesh Manager](https://datamesh-manager.com/), you can use the data contract URL and append the `--publish` option to send and display the test results. Set an environment variable for your API key.
156
133
 
@@ -160,10 +137,35 @@ $ EXPORT DATAMESH_MANAGER_API_KEY=xxx
160
137
  $ datacontract test https://demo.datamesh-manager.com/demo279750347121/datacontracts/4df9d6ee-e55d-4088-9598-b635b2fdcbbc/datacontract.yaml --server production --publish
161
138
  ```
162
139
 
140
+ ### Integration with OpenTelemetry
141
+
142
+ If you use OpenTelemetry, you can use the data contract URL and append the `--publish-to-opentelemetry` option to send the test results to your OLTP-compatible instance, e.g., Prometheus.
163
143
 
144
+ The metric name is "datacontract.cli.test.result" and it uses the following encoding for the result:
164
145
 
146
+ | datacontract.cli.test.result | Description |
147
+ |-------|---------------------------------------|
148
+ | 0 | test run passed, no warnings |
149
+ | 1 | test run has warnings |
150
+ | 2 | test run failed |
151
+ | 3 | test run not possible due to an error |
152
+ | 4 | test status unknown |
165
153
 
166
154
 
155
+ ```bash
156
+ # Fetch current data contract, execute tests on production, and publish result to open telemetry
157
+ $ EXPORT OTEL_SERVICE_NAME=datacontract-cli
158
+ $ EXPORT OTEL_EXPORTER_OTLP_ENDPOINT=https://YOUR_ID.apm.westeurope.azure.elastic-cloud.com:443
159
+ $ EXPORT OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer%20secret # Optional, when using SaaS Products
160
+ $ EXPORT OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf # Optional, default is http/protobuf - use value grpc to use the gRPC protocol instead
161
+ # Send to OpenTelemetry
162
+ $ datacontract test https://demo.datamesh-manager.com/demo279750347121/datacontracts/4df9d6ee-e55d-4088-9598-b635b2fdcbbc/datacontract.yaml --server production --publish-to-opentelemetry
163
+ ```
164
+
165
+ Current limitations:
166
+ - currently, only ConsoleExporter and OTLP Exporter
167
+ - Metrics only, no logs yet (but loosely planned)
168
+
167
169
  ## Installation
168
170
 
169
171
  Choose the most appropriate installation method for your needs:
@@ -451,20 +453,36 @@ datacontract export --format dbt
451
453
 
452
454
  Available export options:
453
455
 
454
- | Type | Description | Status |
455
- |--------------------|---------------------------------------------------------|--------|
456
- | `jsonschema` | Export to JSON Schema | ✅ |
457
- | `odcs` | Export to Open Data Contract Standard (ODCS) | ✅ |
458
- | `sodacl` | Export to SodaCL quality checks in YAML format | ✅ |
459
- | `dbt` | Export to dbt models in YAML format | ✅ |
460
- | `dbt-sources` | Export to dbt sources in YAML format | ✅ |
461
- | `dbt-staging-sql` | Export to dbt staging SQL models | ✅ |
462
- | `rdf` | Export data contract to RDF representation in N3 format | ✅ |
463
- | `avro` | Export to AVRO models | ✅ |
464
- | `pydantic` | Export to pydantic models | TBD |
465
- | `sql` | Export to SQL DDL | TBD |
466
- | `protobuf` | Export to Protobuf | TBD |
467
- | Missing something? | Please create an issue on GitHub | TBD |
456
+ | Type | Description | Status |
457
+ |----------------------|---------------------------------------------------------|--------|
458
+ | `jsonschema` | Export to JSON Schema | ✅ |
459
+ | `odcs` | Export to Open Data Contract Standard (ODCS) | ✅ |
460
+ | `sodacl` | Export to SodaCL quality checks in YAML format | ✅ |
461
+ | `dbt` | Export to dbt models in YAML format | ✅ |
462
+ | `dbt-sources` | Export to dbt sources in YAML format | ✅ |
463
+ | `dbt-staging-sql` | Export to dbt staging SQL models | ✅ |
464
+ | `rdf` | Export data contract to RDF representation in N3 format | ✅ |
465
+ | `avro` | Export to AVRO models | ✅ |
466
+ | `protobuf` | Export to Protobuf | |
467
+ | `terraform` | Export to terraform resources | |
468
+ | `sql` | Export to SQL DDL | |
469
+ | `sql-query` | Export to SQL Query | |
470
+ | `great-expectations` | Export to Great Expectations Suites in JSON Format | ✅ |
471
+ | `bigquery` | Export to BigQuery Schemas | TBD |
472
+ | `pydantic` | Export to pydantic models | TBD |
473
+ | `html` | Export to HTML page | TBD |
474
+ | Missing something? | Please create an issue on GitHub | TBD |
475
+
476
+ #### Great Expectations
477
+ The export function transforms a specified data contract into a comprehensive Great Expectations JSON suite.
478
+ If the contract includes multiple models, you need to specify the names of the model you wish to export.
479
+ ```shell
480
+ datacontract export datacontract.yaml --format great-expectations --model orders
481
+ ```
482
+ The export creates a list of expectations by utilizing:
483
+
484
+ - The data from the Model definition with a fixed mapping
485
+ - The expectations provided in the quality field for each model (find here the expectations gallery https://greatexpectations.io/expectations/)
468
486
 
469
487
  #### RDF
470
488
 
@@ -502,13 +520,120 @@ Available import options:
502
520
  | Type | Description | Status |
503
521
  |--------------------|------------------------------------------------|---------|
504
522
  | `sql` | Import from SQL DDL | ✅ |
523
+ | `avro` | Import from AVRO schemas | ✅ |
505
524
  | `protobuf` | Import from Protobuf schemas | TBD |
506
- | `avro` | Import from AVRO schemas | TBD |
507
525
  | `jsonschema` | Import from JSON Schemas | TBD |
526
+ | `bigquery` | Import from BigQuery Schemas | TBD |
508
527
  | `dbt` | Import from dbt models | TBD |
509
528
  | `odcs` | Import from Open Data Contract Standard (ODCS) | TBD |
510
529
  | Missing something? | Please create an issue on GitHub | TBD |
511
530
 
531
+ ## Best Practices
532
+
533
+ We share best practices in using the Data Contract CLI.
534
+
535
+ ### Data-first Approach
536
+
537
+ Create a data contract based on the actual data. This is the fastest way to get started and to get feedback from the data consumers.
538
+
539
+ 1. Use an existing physical schema (e.g., SQL DDL) as a starting point to define your logical data model in the contract. Double check right after the import whether the actual data meets the imported logical data model. Just to be sure.
540
+ ```bash
541
+ $ datacontract import --format sql ddl.sql
542
+ $ datacontract test
543
+ ```
544
+
545
+ 2. Add examples to the `datacontract.yaml`. If you can, use actual data and anonymize. Make sure that the examples match the imported logical data model.
546
+ ```bash
547
+ $ datacontract test --examples
548
+ ```
549
+
550
+
551
+ 3. Add quality checks and additional type constraints one by one to the contract and make sure the examples and the actual data still adheres to the contract. Check against examples for a very fast feedback loop.
552
+ ```bash
553
+ $ datacontract test --examples
554
+ $ datacontract test
555
+ ```
556
+
557
+ 4. Make sure that all the best practices for a `datacontract.yaml` are met using the linter. You probably forgot to document some fields and add the terms and conditions.
558
+ ```bash
559
+ $ datacontract lint
560
+ ```
561
+
562
+ 5. Set up a CI pipeline that executes daily and reports the results to the [Data Mesh Manager](https://datamesh-manager.com). Or to some place else. You can even publish to any opentelemetry compatible system.
563
+ ```bash
564
+ $ datacontract test --publish https://api.datamesh-manager.com/api/runs
565
+ ```
566
+
567
+ ### Contract-First
568
+
569
+ Create a data contract based on the requirements from use cases.
570
+
571
+ 1. Start with a `datacontract.yaml` template.
572
+ ```bash
573
+ $ datacontract init
574
+ ```
575
+
576
+ 2. Add examples to the `datacontract.yaml`. Do not start with the data model, although you are probably tempted to do that. Examples are the fastest way to get feedback from everybody and not loose someone in the discussion.
577
+
578
+ 3. Create the model based on the examples. Test the model against the examples to double-check whether the model matches the examples.
579
+ ```bash
580
+ $ datacontract test --examples
581
+ ```
582
+
583
+ 4. Add quality checks and additional type constraints one by one to the contract and make sure the examples and the actual data still adheres to the contract. Check against examples for a very fast feedback loop.
584
+ ```bash
585
+ $ datacontract test --examples
586
+ ```
587
+
588
+ 5. Fill in the terms, descriptions, etc. Make sure you follow all best practices for a `datacontract.yaml` using the linter.
589
+ ```bash
590
+ $ datacontract lint
591
+ ```
592
+
593
+ 6. Set up a CI pipeline that lints and tests the examples so you make sure that any changes later do not decrease the quality of the contract.
594
+ ```bash
595
+ $ datacontract lint
596
+ $ datacontract test --examples
597
+ ```
598
+
599
+ 7. Use the export function to start building the providing data product as well as the integration into the consuming data products.
600
+ ```bash
601
+ # data provider
602
+ $ datacontract export --format dbt
603
+ # data consumer
604
+ $ datacontract export --format dbt-sources
605
+ $ datacontract export --format dbt-staging-sql
606
+ ```
607
+
608
+ ### Schema Evolution
609
+
610
+ #### Non-breaking Changes
611
+ Examples: adding models or fields
612
+
613
+ - Add the models or fields in the datacontract.yaml
614
+ - Increment the minor version of the datacontract.yaml on any change. Simply edit the datacontract.yaml for this.
615
+ - You need a policy that these changes are non-breaking. That means that one cannot use the star expression in SQL to query a table under contract. Make the consequences known.
616
+ - Fail the build in the Pull Request if a datacontract.yaml accidentially adds a breaking change even despite only a minor version change
617
+ ```bash
618
+ $ datacontract breaking datacontract-from-pr.yaml datacontract-from-main.yaml
619
+ ```
620
+ - Create a changelog of this minor change.
621
+ ```bash
622
+ $ datacontract changelog datacontract-from-pr.yaml datacontract-from-main.yaml
623
+ ```
624
+ #### Breaking Changes
625
+ Examples: Removing or renaming models and fields.
626
+
627
+ - Remove or rename models and fields in the datacontract.yaml, and any other change that might be part of this new major version of this data contract.
628
+ - Increment the major version of the datacontract.yaml for this and create a new file for the major version. The reason being, that one needs to offer an upgrade path for the data consumers from the old to the new major version.
629
+ - As data consumers need to migrate, try to reduce the frequency of major versions by making multiple breaking changes together if possible.
630
+ - Be aware of the notice period in the data contract as this is the minimum amount of time you have to offer both the old and the new version for a migration path.
631
+ - Do not fear making breaking changes with data contracts. It's okay to do them in this controlled way. Really!
632
+ - Create a changelog of this major change.
633
+ ```bash
634
+ $ datacontract changelog datacontract-from-pr.yaml datacontract-from-main.yaml
635
+ ```
636
+
512
637
  ## Development Setup
513
638
 
514
639
  Python base interpreter should be 3.11.x (unless working on 3.12 release candidate).
@@ -521,7 +646,8 @@ source venv/bin/activate
521
646
  # Install Requirements
522
647
  pip install --upgrade pip setuptools wheel
523
648
  pip install -e '.[dev]'
524
- cd tests/
649
+ ruff check --fix
650
+ ruff format --check
525
651
  pytest
526
652
  ```
527
653