datacontract-cli 0.11.2__tar.gz → 0.11.3__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 (213) hide show
  1. {datacontract_cli-0.11.2/datacontract_cli.egg-info → datacontract_cli-0.11.3}/PKG-INFO +9 -10
  2. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/README.md +1 -2
  3. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/catalog/catalog.py +1 -1
  4. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/cli.py +5 -5
  5. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/data_contract_checks.py +1 -1
  6. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/duckdb_connection.py +70 -17
  7. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/bigquery_exporter.py +2 -2
  8. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/pydantic_exporter.py +15 -4
  9. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/init/init_template.py +1 -1
  10. datacontract_cli-0.11.3/datacontract/schemas/odcs-3.1.0.init.yaml +36 -0
  11. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3/datacontract_cli.egg-info}/PKG-INFO +9 -10
  12. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract_cli.egg-info/SOURCES.txt +2 -0
  13. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract_cli.egg-info/requires.txt +7 -7
  14. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/pyproject.toml +8 -8
  15. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_download_datacontract_file.py +18 -3
  16. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_pydantic.py +17 -1
  17. datacontract_cli-0.11.3/tests/test_test_schema_evolution.py +110 -0
  18. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/LICENSE +0 -0
  19. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/MANIFEST.in +0 -0
  20. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/__init__.py +0 -0
  21. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/api.py +0 -0
  22. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/data_contract.py +0 -0
  23. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/__init__.py +0 -0
  24. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/data_contract_test.py +0 -0
  25. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
  26. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
  27. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/fastjsonschema/check_jsonschema.py +0 -0
  28. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -0
  29. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/__init__.py +0 -0
  30. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/check_soda_execute.py +0 -0
  31. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/athena.py +0 -0
  32. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/bigquery.py +0 -0
  33. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/databricks.py +0 -0
  34. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/impala.py +0 -0
  35. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/kafka.py +0 -0
  36. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/oracle.py +0 -0
  37. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/postgres.py +0 -0
  38. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/snowflake.py +0 -0
  39. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/sqlserver.py +0 -0
  40. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/trino.py +0 -0
  41. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/__init__.py +0 -0
  42. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/avro_exporter.py +0 -0
  43. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/avro_idl_exporter.py +0 -0
  44. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/custom_exporter.py +0 -0
  45. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/data_caterer_exporter.py +0 -0
  46. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/dbml_exporter.py +0 -0
  47. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/dbt_exporter.py +0 -0
  48. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/dcs_exporter.py +0 -0
  49. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/dqx_exporter.py +0 -0
  50. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/duckdb_type_converter.py +0 -0
  51. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/excel_exporter.py +0 -0
  52. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/exporter.py +0 -0
  53. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/exporter_factory.py +0 -0
  54. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/go_exporter.py +0 -0
  55. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/great_expectations_exporter.py +0 -0
  56. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/html_exporter.py +0 -0
  57. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/iceberg_exporter.py +0 -0
  58. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/jsonschema_exporter.py +0 -0
  59. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/markdown_exporter.py +0 -0
  60. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/mermaid_exporter.py +0 -0
  61. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/odcs_export_helper.py +0 -0
  62. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/odcs_v3_exporter.py +0 -0
  63. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/pandas_type_converter.py +0 -0
  64. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/protobuf_exporter.py +0 -0
  65. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/rdf_exporter.py +0 -0
  66. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/sodacl_exporter.py +0 -0
  67. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/spark_exporter.py +0 -0
  68. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/sql_exporter.py +0 -0
  69. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/sql_type_converter.py +0 -0
  70. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/export/sqlalchemy_exporter.py +0 -0
  71. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/avro_importer.py +0 -0
  72. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/bigquery_importer.py +0 -0
  73. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/csv_importer.py +0 -0
  74. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/dbml_importer.py +0 -0
  75. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/dbt_importer.py +0 -0
  76. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/dcs_importer.py +0 -0
  77. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/excel_importer.py +0 -0
  78. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/glue_importer.py +0 -0
  79. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/iceberg_importer.py +0 -0
  80. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/importer.py +0 -0
  81. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/importer_factory.py +0 -0
  82. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/json_importer.py +0 -0
  83. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/jsonschema_importer.py +0 -0
  84. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/odcs_helper.py +0 -0
  85. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/odcs_importer.py +0 -0
  86. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/parquet_importer.py +0 -0
  87. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/protobuf_importer.py +0 -0
  88. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/spark_importer.py +0 -0
  89. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/sql_importer.py +0 -0
  90. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/imports/unity_importer.py +0 -0
  91. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/integration/entropy_data.py +0 -0
  92. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/lint/files.py +0 -0
  93. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/lint/resolve.py +0 -0
  94. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/lint/resources.py +0 -0
  95. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/lint/schema.py +0 -0
  96. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/lint/urls.py +0 -0
  97. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/model/exceptions.py +0 -0
  98. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/model/odcs.py +0 -0
  99. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/model/run.py +0 -0
  100. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/output/__init__.py +0 -0
  101. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/output/junit_test_results.py +0 -0
  102. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/output/output_format.py +0 -0
  103. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/output/test_results_writer.py +0 -0
  104. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/py.typed +0 -0
  105. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
  106. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
  107. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
  108. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
  109. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/schemas/datacontract-1.2.1.init.yaml +0 -0
  110. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/schemas/datacontract-1.2.1.schema.json +0 -0
  111. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/schemas/odcs-3.0.1.schema.json +0 -0
  112. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/schemas/odcs-3.0.2.schema.json +0 -0
  113. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/schemas/odcs-3.1.0.schema.json +0 -0
  114. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/templates/datacontract.html +0 -0
  115. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/templates/datacontract_odcs.html +0 -0
  116. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/templates/index.html +0 -0
  117. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/templates/partials/datacontract_information.html +0 -0
  118. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
  119. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/templates/partials/datacontract_terms.html +0 -0
  120. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/templates/partials/definition.html +0 -0
  121. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/templates/partials/example.html +0 -0
  122. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/templates/partials/model_field.html +0 -0
  123. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/templates/partials/quality.html +0 -0
  124. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/templates/partials/server.html +0 -0
  125. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract/templates/style/output.css +0 -0
  126. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract_cli.egg-info/dependency_links.txt +0 -0
  127. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract_cli.egg-info/entry_points.txt +0 -0
  128. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/datacontract_cli.egg-info/top_level.txt +0 -0
  129. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/setup.cfg +0 -0
  130. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_api.py +0 -0
  131. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_catalog.py +0 -0
  132. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_cli.py +0 -0
  133. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_data_contract_checks.py +0 -0
  134. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_data_contract_specification.py +0 -0
  135. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_description_linter.py +0 -0
  136. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_duckdb_json.py +0 -0
  137. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_avro.py +0 -0
  138. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_avro_idl.py +0 -0
  139. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_bigquery.py +0 -0
  140. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_complex_data_contract.py +0 -0
  141. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_custom.py +0 -0
  142. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_custom_exporter.py +0 -0
  143. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_data_caterer.py +0 -0
  144. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_dbml.py +0 -0
  145. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_dbt_models.py +0 -0
  146. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_dbt_sources.py +0 -0
  147. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_dbt_staging_sql.py +0 -0
  148. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_dqx.py +0 -0
  149. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_excel.py +0 -0
  150. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_go.py +0 -0
  151. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_great_expectations.py +0 -0
  152. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_html.py +0 -0
  153. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_iceberg.py +0 -0
  154. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_jsonschema.py +0 -0
  155. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_markdown.py +0 -0
  156. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_mermaid.py +0 -0
  157. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_odcs_v3.py +0 -0
  158. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_protobuf.py +0 -0
  159. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_rdf.py +0 -0
  160. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_sodacl.py +0 -0
  161. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_spark.py +0 -0
  162. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_sql.py +0 -0
  163. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_sql_query.py +0 -0
  164. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_export_sqlalchemy.py +0 -0
  165. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_avro.py +0 -0
  166. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_bigquery.py +0 -0
  167. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_csv.py +0 -0
  168. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_dbml.py +0 -0
  169. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_dbt.py +0 -0
  170. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_excel.py +0 -0
  171. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_glue.py +0 -0
  172. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_iceberg.py +0 -0
  173. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_json.py +0 -0
  174. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_jsonschema.py +0 -0
  175. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_odcs_v3.py +0 -0
  176. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_parquet.py +0 -0
  177. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_protobuf.py +0 -0
  178. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_spark.py +0 -0
  179. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_sql_oracle.py +0 -0
  180. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_sql_postgres.py +0 -0
  181. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_sql_sqlserver.py +0 -0
  182. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_import_unity_file.py +0 -0
  183. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_integration_entropydata.py +0 -0
  184. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_lint.py +0 -0
  185. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_resolve.py +0 -0
  186. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_roundtrip_jsonschema.py +0 -0
  187. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_api.py +0 -0
  188. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_athena_iceberg.py +0 -0
  189. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_azure_remote.py +0 -0
  190. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_bigquery.py +0 -0
  191. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_databricks.py +0 -0
  192. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_dataframe.py +0 -0
  193. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_delta.py +0 -0
  194. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_gcs_csv_remote.py +0 -0
  195. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_gcs_json_remote.py +0 -0
  196. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_kafka.py +0 -0
  197. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_kafka_remote.py +0 -0
  198. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_local_json.py +0 -0
  199. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_local_json_nd.py +0 -0
  200. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_oracle.py +0 -0
  201. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_output_junit.py +0 -0
  202. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_parquet.py +0 -0
  203. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_postgres.py +0 -0
  204. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_quality.py +0 -0
  205. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_s3_csv.py +0 -0
  206. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_s3_delta.py +0 -0
  207. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_s3_json.py +0 -0
  208. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_s3_json_complex.py +0 -0
  209. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_s3_json_multiple_models.py +0 -0
  210. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_s3_json_remote.py +0 -0
  211. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_snowflake.py +0 -0
  212. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_sqlserver.py +0 -0
  213. {datacontract_cli-0.11.2 → datacontract_cli-0.11.3}/tests/test_test_trino.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datacontract-cli
3
- Version: 0.11.2
3
+ Version: 0.11.3
4
4
  Summary: The datacontract CLI is an open source command-line tool for working with Data Contracts. It uses data contract YAML files to lint the data contract, connect to data sources and execute schema and quality tests, detect breaking changes, and export to different formats. The tool is written in Python. It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a Python library.
5
5
  Author-email: Jochen Christ <jochen.christ@innoq.com>, Stefan Negele <stefan.negele@innoq.com>, Simon Harrer <simon.harrer@innoq.com>
6
6
  License-Expression: MIT
@@ -16,7 +16,7 @@ Requires-Dist: pydantic<2.13.0,>=2.8.2
16
16
  Requires-Dist: pyyaml~=6.0.1
17
17
  Requires-Dist: requests<2.33,>=2.31
18
18
  Requires-Dist: fastjsonschema<2.22.0,>=2.19.1
19
- Requires-Dist: fastparquet<2025.0.0,>=2024.5.0
19
+ Requires-Dist: fastparquet<2026.0.0,>=2024.5.0
20
20
  Requires-Dist: numpy<2.0.0,>=1.26.4
21
21
  Requires-Dist: python-multipart<1.0.0,>=0.0.20
22
22
  Requires-Dist: rich<15.0,>=13.7
@@ -29,7 +29,7 @@ Requires-Dist: boto3<2.0.0,>=1.34.41
29
29
  Requires-Dist: Jinja2<4.0.0,>=3.1.5
30
30
  Requires-Dist: jinja_partials<1.0.0,>=0.2.1
31
31
  Requires-Dist: datacontract-specification<2.0.0,>=1.2.3
32
- Requires-Dist: open-data-contract-standard<4.0.0,>=3.1.0
32
+ Requires-Dist: open-data-contract-standard<4.0.0,>=3.1.2
33
33
  Provides-Extra: avro
34
34
  Requires-Dist: avro==1.12.1; extra == "avro"
35
35
  Provides-Extra: bigquery
@@ -43,18 +43,18 @@ Requires-Dist: soda-core-spark-df<3.6.0,>=3.3.20; extra == "databricks"
43
43
  Requires-Dist: soda-core-spark[databricks]<3.6.0,>=3.3.20; extra == "databricks"
44
44
  Requires-Dist: databricks-sql-connector<4.3.0,>=3.7.0; extra == "databricks"
45
45
  Requires-Dist: databricks-sdk<0.74.0; extra == "databricks"
46
- Requires-Dist: pyspark<4.0.0,>=3.5.5; extra == "databricks"
46
+ Requires-Dist: pyspark<5.0.0,>=3.5.5; extra == "databricks"
47
47
  Provides-Extra: iceberg
48
48
  Requires-Dist: pyiceberg==0.10.0; extra == "iceberg"
49
49
  Provides-Extra: kafka
50
50
  Requires-Dist: datacontract-cli[avro]; extra == "kafka"
51
51
  Requires-Dist: soda-core-spark-df<3.6.0,>=3.3.20; extra == "kafka"
52
- Requires-Dist: pyspark<4.0.0,>=3.5.5; extra == "kafka"
52
+ Requires-Dist: pyspark<5.0.0,>=3.5.5; extra == "kafka"
53
53
  Provides-Extra: postgres
54
54
  Requires-Dist: soda-core-postgres<3.6.0,>=3.3.20; extra == "postgres"
55
55
  Provides-Extra: s3
56
56
  Requires-Dist: s3fs<2026.0.0,>=2025.2.0; extra == "s3"
57
- Requires-Dist: aiobotocore<2.26.0,>=2.17.0; extra == "s3"
57
+ Requires-Dist: aiobotocore<3.2.0,>=2.17.0; extra == "s3"
58
58
  Provides-Extra: snowflake
59
59
  Requires-Dist: snowflake-connector-python[pandas]<4.2,>=3.6; extra == "snowflake"
60
60
  Requires-Dist: soda-core-snowflake<3.6.0,>=3.3.20; extra == "snowflake"
@@ -73,10 +73,10 @@ Requires-Dist: pydbml>=1.1.1; extra == "dbml"
73
73
  Provides-Extra: parquet
74
74
  Requires-Dist: pyarrow>=18.1.0; extra == "parquet"
75
75
  Provides-Extra: rdf
76
- Requires-Dist: rdflib==7.0.0; extra == "rdf"
76
+ Requires-Dist: rdflib==7.5.0; extra == "rdf"
77
77
  Provides-Extra: api
78
78
  Requires-Dist: fastapi==0.121.2; extra == "api"
79
- Requires-Dist: uvicorn==0.38.0; extra == "api"
79
+ Requires-Dist: uvicorn==0.40.0; extra == "api"
80
80
  Provides-Extra: protobuf
81
81
  Requires-Dist: grpcio-tools>=1.53; extra == "protobuf"
82
82
  Provides-Extra: all
@@ -657,8 +657,7 @@ datacontract.yaml
657
657
  servers:
658
658
  production:
659
659
  type: azure
660
- storageAccount: datameshdatabricksdemo
661
- location: abfss://dataproducts/inventory_events/*.parquet
660
+ location: abfss://datameshdatabricksdemo.dfs.core.windows.net/inventory_events/*.parquet
662
661
  format: parquet
663
662
  ```
664
663
 
@@ -558,8 +558,7 @@ datacontract.yaml
558
558
  servers:
559
559
  production:
560
560
  type: azure
561
- storageAccount: datameshdatabricksdemo
562
- location: abfss://dataproducts/inventory_events/*.parquet
561
+ location: abfss://datameshdatabricksdemo.dfs.core.windows.net/inventory_events/*.parquet
563
562
  format: parquet
564
563
  ```
565
564
 
@@ -14,7 +14,7 @@ from datacontract.export.html_exporter import get_version
14
14
 
15
15
  def _get_owner(odcs: OpenDataContractStandard) -> Optional[str]:
16
16
  """Get the owner from ODCS customProperties or team."""
17
- if odcs.team and odcs.team.name:
17
+ if odcs.team and hasattr(odcs.team, "name") and odcs.team.name:
18
18
  return odcs.team.name
19
19
  if odcs.customProperties:
20
20
  for prop in odcs.customProperties:
@@ -67,7 +67,7 @@ def common(
67
67
  pass
68
68
 
69
69
 
70
- @app.command()
70
+ @app.command(name="init")
71
71
  def init(
72
72
  location: Annotated[
73
73
  str, typer.Argument(help="The location of the data contract file to create.")
@@ -90,7 +90,7 @@ def init(
90
90
  console.print("📄 data contract written to " + location)
91
91
 
92
92
 
93
- @app.command()
93
+ @app.command(name="lint")
94
94
  def lint(
95
95
  location: Annotated[
96
96
  str,
@@ -125,7 +125,7 @@ def enable_debug_logging(debug: bool):
125
125
  )
126
126
 
127
127
 
128
- @app.command()
128
+ @app.command(name="test")
129
129
  def test(
130
130
  location: Annotated[
131
131
  str,
@@ -187,7 +187,7 @@ def test(
187
187
  write_test_result(run, console, output_format, output, data_contract)
188
188
 
189
189
 
190
- @app.command()
190
+ @app.command(name="export")
191
191
  def export(
192
192
  format: Annotated[ExportFormat, typer.Option(help="The export format.")],
193
193
  output: Annotated[
@@ -467,7 +467,7 @@ def _get_uvicorn_arguments(port: int, host: str, context: typer.Context) -> dict
467
467
  return default_args | dict(zip(trimmed_keys, context.args[1::2]))
468
468
 
469
469
 
470
- @app.command(context_settings={"allow_extra_args": True, "ignore_unknown_options": True})
470
+ @app.command(name="api", context_settings={"allow_extra_args": True, "ignore_unknown_options": True})
471
471
  def api(
472
472
  ctx: Annotated[typer.Context, typer.Option(help="Extra arguments to pass to uvicorn.run().")],
473
473
  port: Annotated[int, typer.Option(help="Bind socket to this port.")] = 4242,
@@ -161,7 +161,7 @@ def to_schema_name(schema_object: SchemaObject, server_type: str) -> str:
161
161
  # Use physicalName if set (ODCS standard way to specify actual table name)
162
162
  if schema_object.physicalName:
163
163
  return schema_object.physicalName
164
-
164
+
165
165
  return schema_object.name
166
166
 
167
167
 
@@ -1,10 +1,12 @@
1
1
  import os
2
+ import re
2
3
  from typing import Any, List, Optional
3
4
 
4
5
  import duckdb
5
6
  from open_data_contract_standard.model import OpenDataContractStandard, SchemaObject, SchemaProperty, Server
6
7
 
7
8
  from datacontract.export.duckdb_type_converter import convert_to_duckdb_csv_type, convert_to_duckdb_json_type
9
+ from datacontract.export.sql_type_converter import convert_to_duckdb
8
10
  from datacontract.model.run import Run
9
11
 
10
12
 
@@ -57,20 +59,9 @@ def get_duckdb_connection(
57
59
  )
58
60
  add_nested_views(con, model_name, schema_obj.properties)
59
61
  elif server.format == "parquet":
60
- con.sql(f"""
61
- CREATE VIEW "{model_name}" AS SELECT * FROM read_parquet('{model_path}', hive_partitioning=1);
62
- """)
62
+ create_view_with_schema_union(con, schema_obj, model_path, "read_parquet", to_parquet_types)
63
63
  elif server.format == "csv":
64
- columns = to_csv_types(schema_obj)
65
- run.log_info("Using columns: " + str(columns))
66
- if columns is None:
67
- con.sql(
68
- f"""CREATE VIEW "{model_name}" AS SELECT * FROM read_csv('{model_path}', hive_partitioning=1);"""
69
- )
70
- else:
71
- con.sql(
72
- f"""CREATE VIEW "{model_name}" AS SELECT * FROM read_csv('{model_path}', hive_partitioning=1, columns={columns});"""
73
- )
64
+ create_view_with_schema_union(con, schema_obj, model_path, "read_csv", to_csv_types)
74
65
  elif server.format == "delta":
75
66
  con.sql("update extensions;") # Make sure we have the latest delta extension
76
67
  con.sql(f"""CREATE VIEW "{model_name}" AS SELECT * FROM delta_scan('{model_path}');""")
@@ -80,6 +71,34 @@ def get_duckdb_connection(
80
71
  return con
81
72
 
82
73
 
74
+ def create_view_with_schema_union(con, schema_obj: SchemaObject, model_path: str, read_function: str, type_converter):
75
+ """Create a view by unioning empty schema table with data files using union_by_name"""
76
+ converted_types = type_converter(schema_obj)
77
+ model_name = schema_obj.name
78
+ if converted_types:
79
+ # Create empty table with contract schema
80
+ columns_def = [f'"{col_name}" {col_type}' for col_name, col_type in converted_types.items()]
81
+ create_empty_table = f"""CREATE TABLE "{model_name}" ({', '.join(columns_def)});"""
82
+ con.sql(create_empty_table)
83
+
84
+ # Read columns existing in both current data contract and data
85
+ intersecting_columns = con.sql(f"""SELECT column_name
86
+ FROM (DESCRIBE SELECT * FROM {read_function}('{model_path}', union_by_name=true, hive_partitioning=1))
87
+ INTERSECT SELECT column_name
88
+ FROM information_schema.columns
89
+ WHERE table_name = '{model_name}'""").fetchall()
90
+ selected_columns = ', '.join([column[0] for column in intersecting_columns])
91
+
92
+ # Insert data into table by name, but only columns existing in contract and data
93
+ insert_data_sql = f"""INSERT INTO {model_name} BY NAME
94
+ (SELECT {selected_columns} FROM {read_function}('{model_path}', union_by_name=true, hive_partitioning=1));"""
95
+ con.sql(insert_data_sql)
96
+ else:
97
+ # Fallback
98
+ con.sql(
99
+ f"""CREATE VIEW "{model_name}" AS SELECT * FROM {read_function}('{model_path}', union_by_name=true, hive_partitioning=1);"""
100
+ )
101
+
83
102
  def to_csv_types(schema_obj: SchemaObject) -> dict[Any, str | None] | None:
84
103
  if schema_obj is None:
85
104
  return None
@@ -89,6 +108,15 @@ def to_csv_types(schema_obj: SchemaObject) -> dict[Any, str | None] | None:
89
108
  columns[prop.name] = convert_to_duckdb_csv_type(prop)
90
109
  return columns
91
110
 
111
+ def to_parquet_types(schema_obj: SchemaObject) -> dict[Any, str | None] | None:
112
+ """Get proper SQL types for Parquet (preserves decimals, etc.)"""
113
+ if schema_obj is None:
114
+ return None
115
+ columns = {}
116
+ if schema_obj.properties:
117
+ for prop in schema_obj.properties:
118
+ columns[prop.name] = convert_to_duckdb(prop)
119
+ return columns
92
120
 
93
121
  def to_json_types(schema_obj: SchemaObject) -> dict[Any, str | None] | None:
94
122
  if schema_obj is None:
@@ -140,7 +168,7 @@ def add_nested_views(con: duckdb.DuckDBPyConnection, model_name: str, properties
140
168
  add_nested_views(con, nested_model_name, prop.properties)
141
169
 
142
170
 
143
- def setup_s3_connection(con, server):
171
+ def setup_s3_connection(con, server: Server):
144
172
  s3_region = os.getenv("DATACONTRACT_S3_REGION")
145
173
  s3_access_key_id = os.getenv("DATACONTRACT_S3_ACCESS_KEY_ID")
146
174
  s3_secret_access_key = os.getenv("DATACONTRACT_S3_SECRET_ACCESS_KEY")
@@ -184,7 +212,7 @@ def setup_s3_connection(con, server):
184
212
  """)
185
213
 
186
214
 
187
- def setup_gcs_connection(con, server):
215
+ def setup_gcs_connection(con, server: Server):
188
216
  key_id = os.getenv("DATACONTRACT_GCS_KEY_ID")
189
217
  secret = os.getenv("DATACONTRACT_GCS_SECRET")
190
218
 
@@ -202,11 +230,14 @@ def setup_gcs_connection(con, server):
202
230
  """)
203
231
 
204
232
 
205
- def setup_azure_connection(con, server):
233
+ def setup_azure_connection(con, server: Server):
206
234
  tenant_id = os.getenv("DATACONTRACT_AZURE_TENANT_ID")
207
235
  client_id = os.getenv("DATACONTRACT_AZURE_CLIENT_ID")
208
236
  client_secret = os.getenv("DATACONTRACT_AZURE_CLIENT_SECRET")
209
- storage_account = server.storageAccount
237
+ storage_account = (
238
+ to_azure_storage_account(server.location) if server.type == "azure" and "://" in server.location
239
+ else None
240
+ )
210
241
 
211
242
  if tenant_id is None:
212
243
  raise ValueError("Error: Environment variable DATACONTRACT_AZURE_TENANT_ID is not set")
@@ -239,3 +270,25 @@ def setup_azure_connection(con, server):
239
270
  CLIENT_SECRET '{client_secret}'
240
271
  );
241
272
  """)
273
+
274
+ def to_azure_storage_account(location: str) -> str | None:
275
+ """
276
+ Converts a storage location string to extract the storage account name.
277
+ ODCS v3.0 has no explicit field for the storage account. It uses the location field, which is a URI.
278
+ This function parses a storage location string to identify and return the
279
+ storage account name. It handles two primary patterns:
280
+ 1. Protocol://containerName@storageAccountName
281
+ 2. Protocol://storageAccountName
282
+ :param location: The storage location string to parse, typically following
283
+ the format protocol://containerName@storageAccountName. or
284
+ protocol://storageAccountName.
285
+ :return: The extracted storage account name if found, otherwise None
286
+ """
287
+ # to catch protocol://containerName@storageAccountName. pattern from location
288
+ match = re.search(r"(?<=@)([^.]*)", location, re.IGNORECASE)
289
+ if match:
290
+ return match.group()
291
+ else:
292
+ # to catch protocol://storageAccountName. pattern from location
293
+ match = re.search(r"(?<=//)(?!@)([^.]*)", location, re.IGNORECASE)
294
+ return match.group() if match else None
@@ -113,8 +113,8 @@ def map_type_to_bigquery(prop: SchemaProperty) -> str:
113
113
  # If physicalType is already a BigQuery type, return it directly
114
114
  if prop.physicalType:
115
115
  bq_types = {
116
- "STRING", "BYTES", "INT64", "INTEGER", "FLOAT64", "FLOAT", "NUMERIC",
117
- "BIGNUMERIC", "BOOL", "BOOLEAN", "TIMESTAMP", "DATE", "TIME", "DATETIME",
116
+ "STRING", "BYTES", "INT64", "INTEGER", "FLOAT64", "NUMERIC",
117
+ "BIGNUMERIC", "BOOL", "TIMESTAMP", "DATE", "TIME", "DATETIME",
118
118
  "GEOGRAPHY", "JSON", "RECORD", "STRUCT", "ARRAY"
119
119
  }
120
120
  if prop.physicalType.upper() in bq_types or prop.physicalType.upper().startswith(("STRUCT<", "ARRAY<", "RANGE<")):
@@ -19,9 +19,9 @@ def _get_description_str(description) -> str | None:
19
19
  if isinstance(description, str):
20
20
  return description
21
21
  # It's a Description object - get purpose or other meaningful field
22
- if hasattr(description, 'purpose') and description.purpose:
22
+ if hasattr(description, "purpose") and description.purpose:
23
23
  return description.purpose
24
- if hasattr(description, 'usage') and description.usage:
24
+ if hasattr(description, "usage") and description.usage:
25
25
  return description.usage
26
26
  return None
27
27
 
@@ -41,6 +41,7 @@ def to_pydantic_model_str(contract: OpenDataContractStandard) -> str:
41
41
  ast.Name("datetime", ctx=ast.Load()),
42
42
  ast.Name("typing", ctx=ast.Load()),
43
43
  ast.Name("pydantic", ctx=ast.Load()),
44
+ ast.Name("decimal", ctx=ast.Load()),
44
45
  ]
45
46
  ),
46
47
  *documentation,
@@ -76,14 +77,23 @@ def _get_type(prop: SchemaProperty) -> Optional[str]:
76
77
  return prop.logicalType
77
78
 
78
79
 
80
+ def _get_physical_type(prop: SchemaProperty) -> Optional[str]:
81
+ """Get the physical type from a schema property."""
82
+ return prop.physicalType.lower() if prop.physicalType else None
83
+
84
+
79
85
  def constant_field_annotation(
80
86
  field_name: str, prop: SchemaProperty
81
87
  ) -> tuple[type_annotation_type, typing.Optional[ast.ClassDef]]:
82
88
  prop_type = _get_type(prop)
89
+ physical_type = _get_physical_type(prop)
90
+
83
91
  match prop_type:
84
92
  case "string":
85
93
  return (ast.Name("str", ctx=ast.Load()), None)
86
94
  case "number":
95
+ if physical_type == "decimal":
96
+ return (ast.Attribute(value=ast.Name(id="decimal", ctx=ast.Load()), attr="Decimal"), None)
87
97
  # Either integer or float in specification,
88
98
  # so we use float.
89
99
  return (ast.Name("float", ctx=ast.Load()), None)
@@ -103,7 +113,6 @@ def constant_field_annotation(
103
113
  return (ast.Name(field_name.capitalize(), ctx=ast.Load()), classdef)
104
114
  case _:
105
115
  # Check physical type for more specific mappings
106
- physical_type = prop.physicalType.lower() if prop.physicalType else None
107
116
  if physical_type:
108
117
  if physical_type in ["text", "varchar", "char", "nvarchar"]:
109
118
  return (ast.Name("str", ctx=ast.Load()), None)
@@ -115,8 +124,10 @@ def constant_field_annotation(
115
124
  return (ast.Name("float", ctx=ast.Load()), None)
116
125
  elif physical_type in ["double", "float64"]:
117
126
  return (ast.Name("float", ctx=ast.Load()), None)
118
- elif physical_type in ["decimal", "numeric", "number"]:
127
+ elif physical_type in ["numeric", "number"]:
119
128
  return (ast.Name("float", ctx=ast.Load()), None)
129
+ elif physical_type == "decimal":
130
+ return (ast.Attribute(value=ast.Name(id="decimal", ctx=ast.Load()), attr="Decimal"), None)
120
131
  elif physical_type in ["timestamp", "datetime", "timestamp_tz", "timestamp_ntz"]:
121
132
  return (ast.Attribute(value=ast.Name(id="datetime", ctx=ast.Load()), attr="datetime"), None)
122
133
  elif physical_type == "date":
@@ -3,7 +3,7 @@ import logging
3
3
 
4
4
  import requests
5
5
 
6
- DEFAULT_DATA_CONTRACT_INIT_TEMPLATE = "datacontract-1.2.1.init.yaml"
6
+ DEFAULT_DATA_CONTRACT_INIT_TEMPLATE = "odcs-3.1.0.init.yaml"
7
7
 
8
8
 
9
9
  def get_init_template(location: str = None) -> str:
@@ -0,0 +1,36 @@
1
+ apiVersion: v3.1.0
2
+ kind: DataContract
3
+ id: my-data-contract-id
4
+ name: My Data Contract
5
+ version: 1.0.0
6
+ status: draft
7
+
8
+ #team:
9
+ # name: Owner
10
+ #
11
+ #description:
12
+ # purpose: Purpose of the dataset.
13
+ # usage: Intended usage of the dataset.
14
+ # limitations: Limitations of the dataset.
15
+ #
16
+ #schema:
17
+ # - name: my_table
18
+ # description: Description of the table
19
+ # properties:
20
+ # - name: my_field
21
+ # logicalType: string
22
+ # description: Description of the field
23
+ #
24
+ #servers:
25
+ # - server: production
26
+ # type: postgres
27
+ # host: localhost
28
+ # port: 5432
29
+ # database: my_database
30
+ # schema: public
31
+ #
32
+ #slaProperties:
33
+ # - property: latency
34
+ # value: 1h
35
+ # - property: availability
36
+ # value: 99.9%
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datacontract-cli
3
- Version: 0.11.2
3
+ Version: 0.11.3
4
4
  Summary: The datacontract CLI is an open source command-line tool for working with Data Contracts. It uses data contract YAML files to lint the data contract, connect to data sources and execute schema and quality tests, detect breaking changes, and export to different formats. The tool is written in Python. It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a Python library.
5
5
  Author-email: Jochen Christ <jochen.christ@innoq.com>, Stefan Negele <stefan.negele@innoq.com>, Simon Harrer <simon.harrer@innoq.com>
6
6
  License-Expression: MIT
@@ -16,7 +16,7 @@ Requires-Dist: pydantic<2.13.0,>=2.8.2
16
16
  Requires-Dist: pyyaml~=6.0.1
17
17
  Requires-Dist: requests<2.33,>=2.31
18
18
  Requires-Dist: fastjsonschema<2.22.0,>=2.19.1
19
- Requires-Dist: fastparquet<2025.0.0,>=2024.5.0
19
+ Requires-Dist: fastparquet<2026.0.0,>=2024.5.0
20
20
  Requires-Dist: numpy<2.0.0,>=1.26.4
21
21
  Requires-Dist: python-multipart<1.0.0,>=0.0.20
22
22
  Requires-Dist: rich<15.0,>=13.7
@@ -29,7 +29,7 @@ Requires-Dist: boto3<2.0.0,>=1.34.41
29
29
  Requires-Dist: Jinja2<4.0.0,>=3.1.5
30
30
  Requires-Dist: jinja_partials<1.0.0,>=0.2.1
31
31
  Requires-Dist: datacontract-specification<2.0.0,>=1.2.3
32
- Requires-Dist: open-data-contract-standard<4.0.0,>=3.1.0
32
+ Requires-Dist: open-data-contract-standard<4.0.0,>=3.1.2
33
33
  Provides-Extra: avro
34
34
  Requires-Dist: avro==1.12.1; extra == "avro"
35
35
  Provides-Extra: bigquery
@@ -43,18 +43,18 @@ Requires-Dist: soda-core-spark-df<3.6.0,>=3.3.20; extra == "databricks"
43
43
  Requires-Dist: soda-core-spark[databricks]<3.6.0,>=3.3.20; extra == "databricks"
44
44
  Requires-Dist: databricks-sql-connector<4.3.0,>=3.7.0; extra == "databricks"
45
45
  Requires-Dist: databricks-sdk<0.74.0; extra == "databricks"
46
- Requires-Dist: pyspark<4.0.0,>=3.5.5; extra == "databricks"
46
+ Requires-Dist: pyspark<5.0.0,>=3.5.5; extra == "databricks"
47
47
  Provides-Extra: iceberg
48
48
  Requires-Dist: pyiceberg==0.10.0; extra == "iceberg"
49
49
  Provides-Extra: kafka
50
50
  Requires-Dist: datacontract-cli[avro]; extra == "kafka"
51
51
  Requires-Dist: soda-core-spark-df<3.6.0,>=3.3.20; extra == "kafka"
52
- Requires-Dist: pyspark<4.0.0,>=3.5.5; extra == "kafka"
52
+ Requires-Dist: pyspark<5.0.0,>=3.5.5; extra == "kafka"
53
53
  Provides-Extra: postgres
54
54
  Requires-Dist: soda-core-postgres<3.6.0,>=3.3.20; extra == "postgres"
55
55
  Provides-Extra: s3
56
56
  Requires-Dist: s3fs<2026.0.0,>=2025.2.0; extra == "s3"
57
- Requires-Dist: aiobotocore<2.26.0,>=2.17.0; extra == "s3"
57
+ Requires-Dist: aiobotocore<3.2.0,>=2.17.0; extra == "s3"
58
58
  Provides-Extra: snowflake
59
59
  Requires-Dist: snowflake-connector-python[pandas]<4.2,>=3.6; extra == "snowflake"
60
60
  Requires-Dist: soda-core-snowflake<3.6.0,>=3.3.20; extra == "snowflake"
@@ -73,10 +73,10 @@ Requires-Dist: pydbml>=1.1.1; extra == "dbml"
73
73
  Provides-Extra: parquet
74
74
  Requires-Dist: pyarrow>=18.1.0; extra == "parquet"
75
75
  Provides-Extra: rdf
76
- Requires-Dist: rdflib==7.0.0; extra == "rdf"
76
+ Requires-Dist: rdflib==7.5.0; extra == "rdf"
77
77
  Provides-Extra: api
78
78
  Requires-Dist: fastapi==0.121.2; extra == "api"
79
- Requires-Dist: uvicorn==0.38.0; extra == "api"
79
+ Requires-Dist: uvicorn==0.40.0; extra == "api"
80
80
  Provides-Extra: protobuf
81
81
  Requires-Dist: grpcio-tools>=1.53; extra == "protobuf"
82
82
  Provides-Extra: all
@@ -657,8 +657,7 @@ datacontract.yaml
657
657
  servers:
658
658
  production:
659
659
  type: azure
660
- storageAccount: datameshdatabricksdemo
661
- location: abfss://dataproducts/inventory_events/*.parquet
660
+ location: abfss://datameshdatabricksdemo.dfs.core.windows.net/inventory_events/*.parquet
662
661
  format: parquet
663
662
  ```
664
663
 
@@ -102,6 +102,7 @@ datacontract/schemas/datacontract-1.2.1.init.yaml
102
102
  datacontract/schemas/datacontract-1.2.1.schema.json
103
103
  datacontract/schemas/odcs-3.0.1.schema.json
104
104
  datacontract/schemas/odcs-3.0.2.schema.json
105
+ datacontract/schemas/odcs-3.1.0.init.yaml
105
106
  datacontract/schemas/odcs-3.1.0.schema.json
106
107
  datacontract/templates/datacontract.html
107
108
  datacontract/templates/datacontract_odcs.html
@@ -204,6 +205,7 @@ tests/test_test_s3_json.py
204
205
  tests/test_test_s3_json_complex.py
205
206
  tests/test_test_s3_json_multiple_models.py
206
207
  tests/test_test_s3_json_remote.py
208
+ tests/test_test_schema_evolution.py
207
209
  tests/test_test_snowflake.py
208
210
  tests/test_test_sqlserver.py
209
211
  tests/test_test_trino.py
@@ -3,7 +3,7 @@ pydantic<2.13.0,>=2.8.2
3
3
  pyyaml~=6.0.1
4
4
  requests<2.33,>=2.31
5
5
  fastjsonschema<2.22.0,>=2.19.1
6
- fastparquet<2025.0.0,>=2024.5.0
6
+ fastparquet<2026.0.0,>=2024.5.0
7
7
  numpy<2.0.0,>=1.26.4
8
8
  python-multipart<1.0.0,>=0.0.20
9
9
  rich<15.0,>=13.7
@@ -16,14 +16,14 @@ boto3<2.0.0,>=1.34.41
16
16
  Jinja2<4.0.0,>=3.1.5
17
17
  jinja_partials<1.0.0,>=0.2.1
18
18
  datacontract-specification<2.0.0,>=1.2.3
19
- open-data-contract-standard<4.0.0,>=3.1.0
19
+ open-data-contract-standard<4.0.0,>=3.1.2
20
20
 
21
21
  [all]
22
22
  datacontract-cli[api,athena,bigquery,csv,databricks,dbml,dbt,excel,iceberg,kafka,oracle,parquet,postgres,protobuf,rdf,s3,snowflake,sqlserver,trino]
23
23
 
24
24
  [api]
25
25
  fastapi==0.121.2
26
- uvicorn==0.38.0
26
+ uvicorn==0.40.0
27
27
 
28
28
  [athena]
29
29
  soda-core-athena<3.6.0,>=3.3.20
@@ -42,7 +42,7 @@ soda-core-spark-df<3.6.0,>=3.3.20
42
42
  soda-core-spark[databricks]<3.6.0,>=3.3.20
43
43
  databricks-sql-connector<4.3.0,>=3.7.0
44
44
  databricks-sdk<0.74.0
45
- pyspark<4.0.0,>=3.5.5
45
+ pyspark<5.0.0,>=3.5.5
46
46
 
47
47
  [dbml]
48
48
  pydbml>=1.1.1
@@ -74,7 +74,7 @@ pyiceberg==0.10.0
74
74
  [kafka]
75
75
  datacontract-cli[avro]
76
76
  soda-core-spark-df<3.6.0,>=3.3.20
77
- pyspark<4.0.0,>=3.5.5
77
+ pyspark<5.0.0,>=3.5.5
78
78
 
79
79
  [oracle]
80
80
  soda-core-oracle<3.6.0,>=3.3.20
@@ -89,11 +89,11 @@ soda-core-postgres<3.6.0,>=3.3.20
89
89
  grpcio-tools>=1.53
90
90
 
91
91
  [rdf]
92
- rdflib==7.0.0
92
+ rdflib==7.5.0
93
93
 
94
94
  [s3]
95
95
  s3fs<2026.0.0,>=2025.2.0
96
- aiobotocore<2.26.0,>=2.17.0
96
+ aiobotocore<3.2.0,>=2.17.0
97
97
 
98
98
  [snowflake]
99
99
  snowflake-connector-python[pandas]<4.2,>=3.6
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "datacontract-cli"
3
- version = "0.11.2"
3
+ version = "0.11.3"
4
4
  description = "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
  license = "MIT"
6
6
  readme = "README.md"
@@ -20,7 +20,7 @@ dependencies = [
20
20
  "pyyaml~=6.0.1",
21
21
  "requests>=2.31,<2.33",
22
22
  "fastjsonschema>=2.19.1,<2.22.0",
23
- "fastparquet>=2024.5.0,<2025.0.0",
23
+ "fastparquet>=2024.5.0,<2026.0.0",
24
24
  "numpy>=1.26.4,<2.0.0", # transitive dependency, needs to be <2.0.0 https://github.com/datacontract/datacontract-cli/issues/575
25
25
  "python-multipart>=0.0.20,<1.0.0",
26
26
  "rich>=13.7,<15.0",
@@ -34,7 +34,7 @@ dependencies = [
34
34
  "Jinja2>=3.1.5,<4.0.0",
35
35
  "jinja_partials>=0.2.1,<1.0.0",
36
36
  "datacontract-specification>=1.2.3,<2.0.0",
37
- "open-data-contract-standard>=3.1.0,<4.0.0",
37
+ "open-data-contract-standard>=3.1.2,<4.0.0",
38
38
  ]
39
39
 
40
40
  [project.optional-dependencies]
@@ -61,7 +61,7 @@ databricks = [
61
61
  "soda-core-spark[databricks]>=3.3.20,<3.6.0",
62
62
  "databricks-sql-connector>=3.7.0,<4.3.0",
63
63
  "databricks-sdk<0.74.0",
64
- "pyspark>=3.5.5,<4.0.0",
64
+ "pyspark>=3.5.5,<5.0.0",
65
65
  ]
66
66
 
67
67
  iceberg = [
@@ -71,7 +71,7 @@ iceberg = [
71
71
  kafka = [
72
72
  "datacontract-cli[avro]",
73
73
  "soda-core-spark-df>=3.3.20,<3.6.0",
74
- "pyspark>=3.5.5,<4.0.0",
74
+ "pyspark>=3.5.5,<5.0.0",
75
75
  ]
76
76
 
77
77
  postgres = [
@@ -80,7 +80,7 @@ postgres = [
80
80
 
81
81
  s3 = [
82
82
  "s3fs>=2025.2.0,<2026.0.0",
83
- "aiobotocore>=2.17.0,<2.26.0",
83
+ "aiobotocore>=2.17.0,<3.2.0",
84
84
  ]
85
85
 
86
86
  snowflake = [
@@ -117,12 +117,12 @@ parquet = [
117
117
  ]
118
118
 
119
119
  rdf = [
120
- "rdflib==7.0.0",
120
+ "rdflib==7.5.0",
121
121
  ]
122
122
 
123
123
  api = [
124
124
  "fastapi==0.121.2",
125
- "uvicorn==0.38.0",
125
+ "uvicorn==0.40.0",
126
126
  ]
127
127
 
128
128
  protobuf = [