datacontract-cli 1.1.3__tar.gz → 1.2.0__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 (511) hide show
  1. {datacontract_cli-1.1.3/datacontract_cli.egg-info → datacontract_cli-1.2.0}/PKG-INFO +8 -7
  2. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/api.py +1 -1
  3. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/breaking/detector.py +28 -1
  4. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/breaking/rules.py +39 -0
  5. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/changelog/normalize.py +70 -5
  6. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_import.py +31 -5
  7. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/config/settings.py +60 -17
  8. datacontract_cli-1.2.0/datacontract/config/variables.py +133 -0
  9. datacontract_cli-1.2.0/datacontract/editor_assets/VERSION +1 -0
  10. datacontract_cli-1.2.0/datacontract/editor_assets/assets/editor.worker-4.7.0.js +33 -0
  11. datacontract_cli-1.2.0/datacontract/editor_assets/assets/yaml.worker-4.7.0.js +452 -0
  12. datacontract_cli-1.2.0/datacontract/editor_assets/datacontract-editor.css +2 -0
  13. datacontract_cli-1.2.0/datacontract/editor_assets/datacontract-editor.es.js +84438 -0
  14. datacontract_cli-1.2.0/datacontract/editor_assets/index.html +81 -0
  15. datacontract_cli-1.2.0/datacontract/editor_assets/monaco-4.7.0.js +114821 -0
  16. datacontract_cli-1.2.0/datacontract/editor_assets/robots.txt +17 -0
  17. datacontract_cli-1.2.0/datacontract/editor_assets/rolldown-runtime-DY7j01NX.js +30 -0
  18. datacontract_cli-1.2.0/datacontract/editor_assets/sitemap.xml +17 -0
  19. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/checks/create_checks.py +30 -15
  20. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/checks/type_normalize.py +76 -6
  21. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/data_contract_test.py +44 -0
  22. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/fastjsonschema/check_jsonschema.py +1 -1
  23. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/connections/connect.py +25 -5
  24. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/connections/duckdb_connection.py +44 -6
  25. datacontract_cli-1.2.0/datacontract/engines/ibis/connections/iceberg.py +216 -0
  26. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/connections/kafka.py +15 -3
  27. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/dtype_category.py +17 -15
  28. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/ibis_check_execute.py +20 -3
  29. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/snowflake_structured_types.py +9 -4
  30. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/avro_exporter.py +36 -50
  31. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/avro_idl_exporter.py +36 -0
  32. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/bigquery_exporter.py +6 -1
  33. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/data_caterer_exporter.py +2 -28
  34. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/dcs_exporter.py +22 -2
  35. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/exporter.py +6 -1
  36. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/go_exporter.py +15 -0
  37. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/great_expectations_exporter.py +17 -33
  38. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/iceberg_exporter.py +14 -30
  39. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/jsonschema_exporter.py +20 -26
  40. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/protobuf_exporter.py +29 -4
  41. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/pydantic_exporter.py +30 -0
  42. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/rdf_exporter.py +44 -9
  43. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/sodacl_check_builder.py +3 -2
  44. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/spark_exporter.py +14 -20
  45. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/sql_type_converter.py +86 -16
  46. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/sqlalchemy_exporter.py +5 -0
  47. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/avro_importer.py +9 -7
  48. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/dcs_importer.py +15 -26
  49. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/excel_importer.py +23 -5
  50. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/glue_importer.py +5 -2
  51. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/iceberg_importer.py +71 -22
  52. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/jsonschema_importer.py +2 -12
  53. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/odcs_helper.py +83 -4
  54. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/parquet_importer.py +17 -1
  55. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/postgres_importer.py +4 -1
  56. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/protobuf_importer.py +2 -1
  57. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/snowflake_importer.py +4 -1
  58. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/spark_importer.py +7 -1
  59. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/spark_type_json.py +12 -1
  60. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/sql_importer.py +32 -5
  61. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/unity_importer.py +17 -9
  62. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/init/init_template.py +1 -1
  63. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/integration/dbt_test_mapping.py +3 -28
  64. datacontract_cli-1.2.0/datacontract/lint/constraints.py +50 -0
  65. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/lint/resolve.py +13 -2
  66. datacontract_cli-1.2.0/datacontract/model/enum_values.py +60 -0
  67. datacontract_cli-1.2.0/datacontract/model/map_type.py +74 -0
  68. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/model/server.py +25 -0
  69. datacontract_cli-1.2.0/datacontract/model/vector_type.py +110 -0
  70. datacontract_cli-1.1.3/datacontract/schemas/odcs-3.1.0.init.yaml → datacontract_cli-1.2.0/datacontract/schemas/odcs-3.2.0.init.yaml +1 -1
  71. datacontract_cli-1.2.0/datacontract/schemas/odcs-3.2.0.schema.json +4118 -0
  72. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/datacontract_odcs.html +1 -0
  73. datacontract_cli-1.2.0/datacontract/templates/macros/context.html +64 -0
  74. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/macros/schema.html +41 -0
  75. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/macros/server.html +11 -1
  76. datacontract_cli-1.2.0/datacontract/templates/partials_odcs/context.html +16 -0
  77. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/custom_properties.html +3 -0
  78. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/schema.html +17 -0
  79. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/sla.html +30 -0
  80. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0/datacontract_cli.egg-info}/PKG-INFO +8 -7
  81. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract_cli.egg-info/SOURCES.txt +26 -87
  82. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract_cli.egg-info/requires.txt +7 -6
  83. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/pyproject.toml +9 -7
  84. datacontract_cli-1.2.0/tests/test_breaking_odcs_3_2.py +94 -0
  85. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_config_file.py +7 -0
  86. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_create_checks_nested_type.py +21 -9
  87. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_dtype_category.py +13 -5
  88. datacontract_cli-1.2.0/tests/test_enum_values.py +177 -0
  89. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_odcs_v3.py +10 -0
  90. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_rdf.py +37 -30
  91. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_athena.py +1 -1
  92. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_avro.py +53 -18
  93. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_csv.py +1 -1
  94. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_excel.py +10 -1
  95. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_iceberg.py +53 -18
  96. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_mysql.py +1 -1
  97. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_parquet.py +11 -2
  98. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_postgres.py +1 -1
  99. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_powerbi.py +1 -1
  100. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_redshift.py +1 -1
  101. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_snowflake.py +1 -1
  102. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_spark_type_json.py +1 -1
  103. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_sql_oracle.py +2 -2
  104. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_sql_postgres.py +2 -2
  105. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_sql_snowflake.py +1 -1
  106. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_sql_sqlserver.py +1 -1
  107. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_lint.py +10 -0
  108. datacontract_cli-1.2.0/tests/test_lint_odcs_3_2_constraints.py +94 -0
  109. datacontract_cli-1.2.0/tests/test_map_type.py +313 -0
  110. datacontract_cli-1.2.0/tests/test_metadata_fields.py +128 -0
  111. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_roundtrip_pydantic_model.py +4 -31
  112. datacontract_cli-1.2.0/tests/test_servers_3_2_0.py +143 -0
  113. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_snowflake_structured_types.py +11 -4
  114. datacontract_cli-1.2.0/tests/test_test_iceberg.py +347 -0
  115. datacontract_cli-1.2.0/tests/test_test_iceberg_rest.py +187 -0
  116. datacontract_cli-1.2.0/tests/test_test_iceberg_s3tables.py +164 -0
  117. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_parquet.py +1 -1
  118. datacontract_cli-1.2.0/tests/test_test_variables.py +159 -0
  119. datacontract_cli-1.2.0/tests/test_variables.py +157 -0
  120. datacontract_cli-1.2.0/tests/test_vector_type.py +338 -0
  121. datacontract_cli-1.1.3/datacontract/editor_assets/VERSION +0 -1
  122. datacontract_cli-1.1.3/datacontract/editor_assets/abap-Bs8kvjsq.js +0 -1398
  123. datacontract_cli-1.1.3/datacontract/editor_assets/apex-Dspwrl5m.js +0 -326
  124. datacontract_cli-1.1.3/datacontract/editor_assets/assets/editor.worker-4.7.0.js +0 -9037
  125. datacontract_cli-1.1.3/datacontract/editor_assets/assets/yaml.worker-4.7.0.js +0 -26455
  126. datacontract_cli-1.1.3/datacontract/editor_assets/azcli-k1BiOau1.js +0 -68
  127. datacontract_cli-1.1.3/datacontract/editor_assets/bat-BIP72KWc.js +0 -100
  128. datacontract_cli-1.1.3/datacontract/editor_assets/bicep-VhQeYhS3.js +0 -102
  129. datacontract_cli-1.1.3/datacontract/editor_assets/cameligo-DnuAXtHg.js +0 -174
  130. datacontract_cli-1.1.3/datacontract/editor_assets/clojure-BAuDPsal.js +0 -761
  131. datacontract_cli-1.1.3/datacontract/editor_assets/coffee-BV06qSnj.js +0 -232
  132. datacontract_cli-1.1.3/datacontract/editor_assets/cpp-Cz8Jeyrf.js +0 -389
  133. datacontract_cli-1.1.3/datacontract/editor_assets/csharp-F6hhlXFb.js +0 -326
  134. datacontract_cli-1.1.3/datacontract/editor_assets/csp-KzlEHCyI.js +0 -53
  135. datacontract_cli-1.1.3/datacontract/editor_assets/css-e4FKntZ3.js +0 -187
  136. datacontract_cli-1.1.3/datacontract/editor_assets/cssMode-BNkTa2xp.js +0 -1618
  137. datacontract_cli-1.1.3/datacontract/editor_assets/cypher-CpvDGKRr.js +0 -263
  138. datacontract_cli-1.1.3/datacontract/editor_assets/dart-DdHeFWR0.js +0 -281
  139. datacontract_cli-1.1.3/datacontract/editor_assets/datacontract-editor.css +0 -1
  140. datacontract_cli-1.1.3/datacontract/editor_assets/datacontract-editor.es.js +0 -78027
  141. datacontract_cli-1.1.3/datacontract/editor_assets/dockerfile-aoNXDcio.js +0 -130
  142. datacontract_cli-1.1.3/datacontract/editor_assets/ecl-C4Q0DYuA.js +0 -456
  143. datacontract_cli-1.1.3/datacontract/editor_assets/elixir-C9X42b0T.js +0 -569
  144. datacontract_cli-1.1.3/datacontract/editor_assets/flow9-Bff42pfB.js +0 -142
  145. datacontract_cli-1.1.3/datacontract/editor_assets/freemarker2-Dyfzmb5A.js +0 -989
  146. datacontract_cli-1.1.3/datacontract/editor_assets/fsharp-C6vPAsHG.js +0 -217
  147. datacontract_cli-1.1.3/datacontract/editor_assets/go-DEr8zx9f.js +0 -218
  148. datacontract_cli-1.1.3/datacontract/editor_assets/graphql-BiNBBRFh.js +0 -151
  149. datacontract_cli-1.1.3/datacontract/editor_assets/handlebars-BtDNI-uC.js +0 -419
  150. datacontract_cli-1.1.3/datacontract/editor_assets/hcl-2T9lKuFg.js +0 -183
  151. datacontract_cli-1.1.3/datacontract/editor_assets/html-Cn4TGw_o.js +0 -308
  152. datacontract_cli-1.1.3/datacontract/editor_assets/htmlMode-Bf84vbo2.js +0 -1628
  153. datacontract_cli-1.1.3/datacontract/editor_assets/index.html +0 -31
  154. datacontract_cli-1.1.3/datacontract/editor_assets/ini-CZGtssYM.js +0 -71
  155. datacontract_cli-1.1.3/datacontract/editor_assets/java-B260NeH3.js +0 -232
  156. datacontract_cli-1.1.3/datacontract/editor_assets/javascript-B86Kac07.js +0 -70
  157. datacontract_cli-1.1.3/datacontract/editor_assets/jsonMode-Ckgg5lAE.js +0 -2051
  158. datacontract_cli-1.1.3/datacontract/editor_assets/julia-kuNLM9c5.js +0 -511
  159. datacontract_cli-1.1.3/datacontract/editor_assets/kotlin-Bz6kAefA.js +0 -253
  160. datacontract_cli-1.1.3/datacontract/editor_assets/less-AZUtS89I.js +0 -162
  161. datacontract_cli-1.1.3/datacontract/editor_assets/lexon-BcmgnyRb.js +0 -157
  162. datacontract_cli-1.1.3/datacontract/editor_assets/liquid-D0NPwuu_.js +0 -240
  163. datacontract_cli-1.1.3/datacontract/editor_assets/lua-Dz1RbATg.js +0 -162
  164. datacontract_cli-1.1.3/datacontract/editor_assets/m3-CIMooLFn.js +0 -210
  165. datacontract_cli-1.1.3/datacontract/editor_assets/markdown-C1BsCK9P.js +0 -229
  166. datacontract_cli-1.1.3/datacontract/editor_assets/mdx-QFRSBtVQ.js +0 -165
  167. datacontract_cli-1.1.3/datacontract/editor_assets/mips-BovsnfLQ.js +0 -198
  168. datacontract_cli-1.1.3/datacontract/editor_assets/monaco-4.7.0.js +0 -125918
  169. datacontract_cli-1.1.3/datacontract/editor_assets/msdax-CiRB2ZB-.js +0 -375
  170. datacontract_cli-1.1.3/datacontract/editor_assets/mysql-BwdpPE19.js +0 -878
  171. datacontract_cli-1.1.3/datacontract/editor_assets/objective-c-D4nfHfso.js +0 -183
  172. datacontract_cli-1.1.3/datacontract/editor_assets/pascal--j5-PYtz.js +0 -251
  173. datacontract_cli-1.1.3/datacontract/editor_assets/pascaligo-C7TcJxNL.js +0 -164
  174. datacontract_cli-1.1.3/datacontract/editor_assets/perl-BzEWqUb5.js +0 -626
  175. datacontract_cli-1.1.3/datacontract/editor_assets/pgsql-B_KZ0mGX.js +0 -851
  176. datacontract_cli-1.1.3/datacontract/editor_assets/php-A19QHzQV.js +0 -500
  177. datacontract_cli-1.1.3/datacontract/editor_assets/pla-COeKY1hA.js +0 -137
  178. datacontract_cli-1.1.3/datacontract/editor_assets/postiats-BfMp7zJL.js +0 -907
  179. datacontract_cli-1.1.3/datacontract/editor_assets/powerquery-B0TS_5Gb.js +0 -890
  180. datacontract_cli-1.1.3/datacontract/editor_assets/powershell-5jSbKdYB.js +0 -239
  181. datacontract_cli-1.1.3/datacontract/editor_assets/protobuf-YgnOutn3.js +0 -420
  182. datacontract_cli-1.1.3/datacontract/editor_assets/pug-DLej6kn5.js +0 -402
  183. datacontract_cli-1.1.3/datacontract/editor_assets/python-C8RW9B6A.js +0 -301
  184. datacontract_cli-1.1.3/datacontract/editor_assets/qsharp-AhjqtSHB.js +0 -301
  185. datacontract_cli-1.1.3/datacontract/editor_assets/r-D-F4P80w.js +0 -243
  186. datacontract_cli-1.1.3/datacontract/editor_assets/razor-CLZqdY_r.js +0 -550
  187. datacontract_cli-1.1.3/datacontract/editor_assets/redis-hwwIlMnV.js +0 -302
  188. datacontract_cli-1.1.3/datacontract/editor_assets/redshift-Bcm_kjEG.js +0 -809
  189. datacontract_cli-1.1.3/datacontract/editor_assets/restructuredtext-CrdzfPP-.js +0 -174
  190. datacontract_cli-1.1.3/datacontract/editor_assets/ruby-QC2UNm1s.js +0 -511
  191. datacontract_cli-1.1.3/datacontract/editor_assets/rust-5aqiQ3L5.js +0 -343
  192. datacontract_cli-1.1.3/datacontract/editor_assets/sb-B1g1ZfLJ.js +0 -115
  193. datacontract_cli-1.1.3/datacontract/editor_assets/scala-C2U4R5Gb.js +0 -370
  194. datacontract_cli-1.1.3/datacontract/editor_assets/scheme-DeFRbslr.js +0 -108
  195. datacontract_cli-1.1.3/datacontract/editor_assets/scss-RSTCiCmI.js +0 -262
  196. datacontract_cli-1.1.3/datacontract/editor_assets/shell-BpF-iNu8.js +0 -221
  197. datacontract_cli-1.1.3/datacontract/editor_assets/solidity-C00r2mbQ.js +0 -1367
  198. datacontract_cli-1.1.3/datacontract/editor_assets/sophia-DVW5ZKDB.js +0 -199
  199. datacontract_cli-1.1.3/datacontract/editor_assets/sparql-B0nmpxeX.js +0 -201
  200. datacontract_cli-1.1.3/datacontract/editor_assets/sql-CJwKPERn.js +0 -853
  201. datacontract_cli-1.1.3/datacontract/editor_assets/st-DPlKG5DT.js +0 -416
  202. datacontract_cli-1.1.3/datacontract/editor_assets/swift-YZBAbVHV.js +0 -309
  203. datacontract_cli-1.1.3/datacontract/editor_assets/systemverilog-CDQSaH63.js +0 -576
  204. datacontract_cli-1.1.3/datacontract/editor_assets/tcl-Dlu8sp6Q.js +0 -232
  205. datacontract_cli-1.1.3/datacontract/editor_assets/tsMode-yleMwhPq.js +0 -933
  206. datacontract_cli-1.1.3/datacontract/editor_assets/twig-C5TO7-kw.js +0 -392
  207. datacontract_cli-1.1.3/datacontract/editor_assets/typescript-CJBeebKU.js +0 -343
  208. datacontract_cli-1.1.3/datacontract/editor_assets/typespec-BsmjDEu7.js +0 -117
  209. datacontract_cli-1.1.3/datacontract/editor_assets/vb-ChHvIDrk.js +0 -372
  210. datacontract_cli-1.1.3/datacontract/editor_assets/wgsl-XEp1ju8c.js +0 -439
  211. datacontract_cli-1.1.3/datacontract/editor_assets/xml-vC-NMVX1.js +0 -95
  212. datacontract_cli-1.1.3/datacontract/editor_assets/yaml-Dlf2VF-T.js +0 -206
  213. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/LICENSE +0 -0
  214. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/MANIFEST.in +0 -0
  215. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/README.md +0 -0
  216. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/__init__.py +0 -0
  217. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/breaking/__init__.py +0 -0
  218. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/catalog/catalog.py +0 -0
  219. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/changelog/__init__.py +0 -0
  220. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/changelog/changelog.py +0 -0
  221. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/cli.py +0 -0
  222. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_api.py +0 -0
  223. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_breaking.py +0 -0
  224. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_catalog.py +0 -0
  225. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_changelog.py +0 -0
  226. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_ci.py +0 -0
  227. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_dbt.py +0 -0
  228. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_edit.py +0 -0
  229. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_export.py +0 -0
  230. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_init.py +0 -0
  231. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_lint.py +0 -0
  232. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_publish.py +0 -0
  233. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/command_test.py +0 -0
  234. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/config/__init__.py +0 -0
  235. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/config/cli_context.py +0 -0
  236. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/data_contract.py +0 -0
  237. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/editor_assets/logo_fuchsia_v2.svg +0 -0
  238. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/editor_assets/odcs.svg +0 -0
  239. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/__init__.py +0 -0
  240. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/checks/__init__.py +0 -0
  241. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/checks/check_filter.py +0 -0
  242. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/checks/check_spec.py +0 -0
  243. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/checks/dimensions.py +0 -0
  244. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/checks/physical_type_match.py +0 -0
  245. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/checks/sql_guard.py +0 -0
  246. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/datacontract/check_azure_blob_file.py +0 -0
  247. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
  248. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
  249. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -0
  250. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/__init__.py +0 -0
  251. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/connections/__init__.py +0 -0
  252. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/connections/aws_credentials.py +0 -0
  253. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/connections/databricks_patch.py +0 -0
  254. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/connections/oracle_patch.py +0 -0
  255. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/connections/redshift_credentials.py +0 -0
  256. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/connections/redshift_patch.py +0 -0
  257. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/engines/ibis/native_type.py +0 -0
  258. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/__init__.py +0 -0
  259. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/custom_exporter.py +0 -0
  260. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/dbml_exporter.py +0 -0
  261. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/dbt_exporter.py +0 -0
  262. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/dqx_exporter.py +0 -0
  263. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/duckdb_type_converter.py +0 -0
  264. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/excel_exporter.py +0 -0
  265. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/exporter_factory.py +0 -0
  266. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/html_exporter.py +0 -0
  267. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/markdown_exporter.py +0 -0
  268. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/mermaid_exporter.py +0 -0
  269. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/odcs_v3_exporter.py +0 -0
  270. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/pandas_type_converter.py +0 -0
  271. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/sodacl_exporter.py +0 -0
  272. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/export/sql_exporter.py +0 -0
  273. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/athena_importer.py +0 -0
  274. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/bigquery_importer.py +0 -0
  275. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/csv_importer.py +0 -0
  276. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/dbml_importer.py +0 -0
  277. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/dbt_importer.py +0 -0
  278. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/importer.py +0 -0
  279. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/importer_factory.py +0 -0
  280. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/json_importer.py +0 -0
  281. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/mysql_importer.py +0 -0
  282. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/object_storage_importer.py +0 -0
  283. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/odcs_importer.py +0 -0
  284. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/oracle_importer.py +0 -0
  285. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/powerbi_importer.py +0 -0
  286. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/pydantic_importer.py +0 -0
  287. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/redshift_importer.py +0 -0
  288. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/sqlserver_importer.py +0 -0
  289. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/imports/trino_importer.py +0 -0
  290. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/integration/dbt_sync.py +0 -0
  291. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/integration/entropy_data.py +0 -0
  292. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/lint/files.py +0 -0
  293. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/lint/resources.py +0 -0
  294. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/lint/s3.py +0 -0
  295. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/lint/schema.py +0 -0
  296. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/lint/urls.py +0 -0
  297. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/model/breaking.py +0 -0
  298. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/model/changelog.py +0 -0
  299. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/model/exceptions.py +0 -0
  300. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/model/odcs.py +0 -0
  301. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/model/run.py +0 -0
  302. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/output/__init__.py +0 -0
  303. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/output/ci_output.py +0 -0
  304. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/output/json_test_results.py +0 -0
  305. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/output/junit_test_results.py +0 -0
  306. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/output/output_format.py +0 -0
  307. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/output/test_results_writer.py +0 -0
  308. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/output/text_breaking_results.py +0 -0
  309. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/output/text_changelog_results.py +0 -0
  310. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/py.typed +0 -0
  311. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
  312. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
  313. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
  314. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
  315. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/schemas/datacontract-1.2.1.init.yaml +0 -0
  316. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/schemas/datacontract-1.2.1.schema.json +0 -0
  317. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/schemas/odcs-3.0.1.schema.json +0 -0
  318. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/schemas/odcs-3.0.2.schema.json +0 -0
  319. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/schemas/odcs-3.1.0.schema.json +0 -0
  320. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/datacontract.html +0 -0
  321. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/excel/odcs-template.xlsx +0 -0
  322. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/index.html +0 -0
  323. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/macros/authoritative_definitions.html +0 -0
  324. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/macros/support.html +0 -0
  325. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials/datacontract_information.html +0 -0
  326. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
  327. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials/datacontract_terms.html +0 -0
  328. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials/definition.html +0 -0
  329. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials/example.html +0 -0
  330. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials/model_field.html +0 -0
  331. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials/quality.html +0 -0
  332. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials/server.html +0 -0
  333. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/diagram.html +0 -0
  334. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/dialog_yaml.html +0 -0
  335. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/footer.html +0 -0
  336. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/fundamentals.html +0 -0
  337. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/header.html +0 -0
  338. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/pricing.html +0 -0
  339. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/roles.html +0 -0
  340. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/servers.html +0 -0
  341. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/support.html +0 -0
  342. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/team.html +0 -0
  343. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/term_of_use.html +0 -0
  344. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/partials_odcs/title.html +0 -0
  345. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract/templates/style/output.css +0 -0
  346. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract_cli.egg-info/dependency_links.txt +0 -0
  347. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract_cli.egg-info/entry_points.txt +0 -0
  348. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/datacontract_cli.egg-info/top_level.txt +0 -0
  349. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/setup.cfg +0 -0
  350. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_api.py +0 -0
  351. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_api_openapi.py +0 -0
  352. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_breaking.py +0 -0
  353. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_catalog.py +0 -0
  354. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_changelog.py +0 -0
  355. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_changelog_engine.py +0 -0
  356. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_changelog_normalize.py +0 -0
  357. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_changelog_output_text.py +0 -0
  358. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_check_quality_provenance.py +0 -0
  359. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_ci_output.py +0 -0
  360. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_cli.py +0 -0
  361. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_command_api.py +0 -0
  362. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_config.py +0 -0
  363. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_config_require.py +0 -0
  364. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_config_threading.py +0 -0
  365. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_connect_athena.py +0 -0
  366. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_connect_bigquery.py +0 -0
  367. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_connect_databricks.py +0 -0
  368. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_connect_impala.py +0 -0
  369. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_connect_mysql.py +0 -0
  370. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_connect_oracle.py +0 -0
  371. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_connect_postgres.py +0 -0
  372. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_connect_redshift.py +0 -0
  373. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_connect_s3_credentials.py +0 -0
  374. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_connect_snowflake.py +0 -0
  375. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_connect_sqlserver.py +0 -0
  376. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_connect_trino.py +0 -0
  377. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_create_checks_array_items.py +0 -0
  378. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_create_checks_physical_type.py +0 -0
  379. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_create_checks_primary_key.py +0 -0
  380. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_create_checks_retention_period.py +0 -0
  381. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_create_checks_servicelevel.py +0 -0
  382. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_create_checks_sql_placeholders.py +0 -0
  383. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_data_contract.py +0 -0
  384. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_data_contract_checks.py +0 -0
  385. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_data_contract_specification.py +0 -0
  386. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_dbt_sync.py +0 -0
  387. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_dbt_test_mapping.py +0 -0
  388. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_description_linter.py +0 -0
  389. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_docs_commands.py +0 -0
  390. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_docs_config_options.py +0 -0
  391. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_docs_ordering.py +0 -0
  392. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_download_datacontract_file.py +0 -0
  393. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_duckdb_json.py +0 -0
  394. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_edit.py +0 -0
  395. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_avro.py +0 -0
  396. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_avro_idl.py +0 -0
  397. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_bigquery.py +0 -0
  398. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_complex_data_contract.py +0 -0
  399. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_custom.py +0 -0
  400. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_custom_exporter.py +0 -0
  401. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_custom_model.py +0 -0
  402. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_data_caterer.py +0 -0
  403. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_dbml.py +0 -0
  404. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_dbt_models.py +0 -0
  405. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_dbt_sources.py +0 -0
  406. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_dbt_staging_sql.py +0 -0
  407. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_dcs.py +0 -0
  408. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_dqx.py +0 -0
  409. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_excel.py +0 -0
  410. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_go.py +0 -0
  411. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_great_expectations.py +0 -0
  412. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_html.py +0 -0
  413. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_iceberg.py +0 -0
  414. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_jsonschema.py +0 -0
  415. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_large_contract.py +0 -0
  416. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_markdown.py +0 -0
  417. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_mermaid.py +0 -0
  418. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_protobuf.py +0 -0
  419. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_pydantic.py +0 -0
  420. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_sodacl.py +0 -0
  421. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_spark.py +0 -0
  422. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_sql.py +0 -0
  423. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_sql_clickhouse.py +0 -0
  424. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_sql_query.py +0 -0
  425. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_export_sqlalchemy.py +0 -0
  426. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_ibis_mssql_pattern.py +0 -0
  427. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_ibis_mssql_schema.py +0 -0
  428. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_ibis_oracle_schema.py +0 -0
  429. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_bigquery.py +0 -0
  430. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_dbml.py +0 -0
  431. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_dbt.py +0 -0
  432. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_glue.py +0 -0
  433. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_json.py +0 -0
  434. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_jsonschema.py +0 -0
  435. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_object_storage.py +0 -0
  436. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_odcs_v3.py +0 -0
  437. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_oracle.py +0 -0
  438. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_protobuf.py +0 -0
  439. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_pydantic_model.py +0 -0
  440. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_sqlserver.py +0 -0
  441. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_trino.py +0 -0
  442. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_import_unity_file.py +0 -0
  443. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_install_extras.py +0 -0
  444. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_integration_entropydata.py +0 -0
  445. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_lint_urls.py +0 -0
  446. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_native_type_schema_scope.py +0 -0
  447. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_oracle_patch.py +0 -0
  448. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_physical_type_match.py +0 -0
  449. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_publish_test_results.py +0 -0
  450. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_publish_test_results_payload.py +0 -0
  451. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_quality_sql_dialects.py +0 -0
  452. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_redshift_credentials.py +0 -0
  453. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_redshift_patch.py +0 -0
  454. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_resolve.py +0 -0
  455. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_resolve_definitions.py +0 -0
  456. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_resolve_local_definitions.py +0 -0
  457. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_roundtrip_jsonschema.py +0 -0
  458. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_run_check_deprecated_fields.py +0 -0
  459. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_run_check_engine.py +0 -0
  460. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_server_overrides.py +0 -0
  461. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_server_type_mssql.py +0 -0
  462. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_server_type_synonyms.py +0 -0
  463. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_sql_type_converter_physicaltype.py +0 -0
  464. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_api.py +0 -0
  465. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_array_items.py +0 -0
  466. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_athena_iceberg.py +0 -0
  467. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_azure_blob_file.py +0 -0
  468. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_azure_remote.py +0 -0
  469. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_bigquery.py +0 -0
  470. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_checks_filter.py +0 -0
  471. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_databricks.py +0 -0
  472. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_delta.py +0 -0
  473. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_diagnostics.py +0 -0
  474. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_dimension_filter.py +0 -0
  475. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_dry_run.py +0 -0
  476. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_duckdb.py +0 -0
  477. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_failed_samples.py +0 -0
  478. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_gcs_csv_remote.py +0 -0
  479. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_gcs_json_remote.py +0 -0
  480. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_kafka.py +0 -0
  481. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_kafka_decoding.py +0 -0
  482. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_kafka_remote.py +0 -0
  483. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_local_json.py +0 -0
  484. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_local_json_nd.py +0 -0
  485. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_metadata_only.py +0 -0
  486. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_mysql.py +0 -0
  487. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_oracle.py +0 -0
  488. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_oracle_xe.py +0 -0
  489. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_output_json.py +0 -0
  490. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_output_junit.py +0 -0
  491. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_postgres.py +0 -0
  492. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_quality.py +0 -0
  493. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_quality_id_and_tag_filter.py +0 -0
  494. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_quality_local_fallback.py +0 -0
  495. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_quality_percent_severity.py +0 -0
  496. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_redshift.py +0 -0
  497. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_row_filter.py +0 -0
  498. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_s3_csv.py +0 -0
  499. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_s3_delta.py +0 -0
  500. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_s3_json.py +0 -0
  501. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_s3_json_complex.py +0 -0
  502. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_s3_json_multiple_models.py +0 -0
  503. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_s3_json_remote.py +0 -0
  504. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_schema_evolution.py +0 -0
  505. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_server_not_found.py +0 -0
  506. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_snowflake.py +0 -0
  507. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_soda_connection_error.py +0 -0
  508. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_sqlserver.py +0 -0
  509. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_test_trino.py +0 -0
  510. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_type_normalize.py +0 -0
  511. {datacontract_cli-1.1.3 → datacontract_cli-1.2.0}/tests/test_untrusted_contract.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datacontract-cli
3
- Version: 1.1.3
3
+ Version: 1.2.0
4
4
  Summary: The datacontract CLI is an open source command-line tool for working with Data Contracts. It uses data contract YAML files to lint the data contract, connect to data sources and execute schema and quality tests, detect breaking changes, and export to different formats. The tool is written in Python. It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a Python library.
5
5
  Author-email: Jochen Christ <jochen.christ@entropy-data.com>, Stefan Negele <stefan.negele@innoq.com>, Simon Harrer <simon.harrer@entropy-data.com>
6
6
  License-Expression: MIT
@@ -40,13 +40,13 @@ Requires-Dist: jsonschema<5.0.0,>=4.23.0
40
40
  Requires-Dist: pytz>=2024.1
41
41
  Requires-Dist: python-multipart<1.0.0,>=0.0.20
42
42
  Requires-Dist: rich<16.0,>=13.7
43
- Requires-Dist: sqlglot<31.0.0,>=26.6.0
43
+ Requires-Dist: sqlglot<30.18,>=26.6.0
44
44
  Requires-Dist: python-dotenv<2.0.0,>=1.0.0
45
45
  Requires-Dist: boto3<2.0.0,>=1.34.41
46
46
  Requires-Dist: Jinja2<4.0.0,>=3.1.5
47
47
  Requires-Dist: jinja_partials<1.0.0,>=0.2.1
48
48
  Requires-Dist: datacontract-specification<2.0.0,>=1.2.3
49
- Requires-Dist: open-data-contract-standard<3.2.0,>=3.1.2
49
+ Requires-Dist: open-data-contract-standard<3.3.0,>=3.2.0
50
50
  Requires-Dist: deepdiff<10.0.0,>=6.0.0
51
51
  Provides-Extra: avro
52
52
  Requires-Dist: avro==1.12.2; extra == "avro"
@@ -67,12 +67,13 @@ Requires-Dist: rich>=12.4.4; extra == "dataframe"
67
67
  Provides-Extra: databricks
68
68
  Requires-Dist: ibis-framework[databricks]<13.0.0,>=10.0.0; extra == "databricks"
69
69
  Requires-Dist: databricks-sql-connector<4.5.0,>=3.7.0; extra == "databricks"
70
- Requires-Dist: databricks-sdk<0.134.0; extra == "databricks"
70
+ Requires-Dist: databricks-sdk<0.136.0; extra == "databricks"
71
71
  Requires-Dist: packaging<27.0,>=21.3; extra == "databricks"
72
72
  Provides-Extra: databricks-runtime
73
73
  Requires-Dist: datacontract-cli[databricks]; extra == "databricks-runtime"
74
74
  Provides-Extra: iceberg
75
- Requires-Dist: pyiceberg==0.11.1; extra == "iceberg"
75
+ Requires-Dist: pyiceberg[pyarrow,rest-sigv4]==0.12.0; extra == "iceberg"
76
+ Requires-Dist: datacontract-cli[duckdb]; extra == "iceberg"
76
77
  Provides-Extra: kafka
77
78
  Requires-Dist: datacontract-cli[duckdb,parquet]; extra == "kafka"
78
79
  Requires-Dist: confluent-kafka<3.0.0,>=2.6.0; extra == "kafka"
@@ -145,10 +146,10 @@ Requires-Dist: pre-commit<4.7.0,>=3.7.1; extra == "dev"
145
146
  Requires-Dist: pytest; extra == "dev"
146
147
  Requires-Dist: pytest-cov; extra == "dev"
147
148
  Requires-Dist: pytest-xdist; extra == "dev"
148
- Requires-Dist: pymssql==2.3.13; extra == "dev"
149
+ Requires-Dist: pymssql==2.4.0; extra == "dev"
149
150
  Requires-Dist: psycopg2-binary<3.0,>=2.9; extra == "dev"
150
151
  Requires-Dist: mysql-connector-python<26.8.0,>=8.0.30; extra == "dev"
151
- Requires-Dist: ruff==0.16.5; extra == "dev"
152
+ Requires-Dist: ruff==0.16.6; extra == "dev"
152
153
  Requires-Dist: testcontainers[kafka,minio,mssql,mysql,postgres]==4.15.0; extra == "dev"
153
154
  Requires-Dist: trino==0.339.0; extra == "dev"
154
155
  Dynamic: license-file
@@ -20,7 +20,7 @@ from datacontract.model.changelog import ChangelogEntry
20
20
  from datacontract.model.exceptions import DataContractException, DefinitionResolutionError
21
21
  from datacontract.model.run import Check, ResultEnum, Run
22
22
 
23
- DATA_CONTRACT_EXAMPLE_PAYLOAD = """apiVersion: v3.1.0
23
+ DATA_CONTRACT_EXAMPLE_PAYLOAD = """apiVersion: v3.2.0
24
24
  kind: DataContract
25
25
  id: orders
26
26
  name: Orders
@@ -23,11 +23,38 @@ class BreakingChangeDetector:
23
23
  def detect(self, changelog: ChangelogResult) -> BreakingChangeResult:
24
24
  entries = [self._classify(entry) for entry in changelog.entries]
25
25
  # Nothing inside a newly added element can break a consumer: it did not exist before.
26
- added = {entry.path for entry in entries if entry.change_type == ChangelogType.added}
26
+ added = {
27
+ entry.path
28
+ for entry in entries
29
+ if entry.change_type == ChangelogType.added
30
+ and (
31
+ entry.path.startswith("schema.")
32
+ and (len(entry.path.split(".")) == 2 or entry.path.split(".")[-2] == "properties")
33
+ )
34
+ }
35
+ removed_enums = {
36
+ entry.path
37
+ for entry in entries
38
+ if entry.change_type == ChangelogType.removed and entry.path.endswith(".enum")
39
+ }
40
+ # Stable IDs may change or swap without changing the set of allowed
41
+ # values. Match removed/updated values against additions in the same enum.
42
+ added_values = defaultdict(set)
43
+ for entry in entries:
44
+ if entry.rule_id == "enum-constraint-changed" and entry.path.endswith(".value"):
45
+ if entry.change_type in (ChangelogType.added, ChangelogType.updated):
46
+ added_values[entry.path.rsplit(".enum.", 1)[0]].add(entry.new_value)
27
47
  for entry in entries:
28
48
  segments = entry.path.split(".")
29
49
  if any(".".join(segments[:i]) in added for i in range(1, len(segments))):
30
50
  entry.level = BreakingChangeLevel.INFO
51
+ if entry.rule_id == "enum-constraint-changed":
52
+ if any(entry.path.startswith(path + ".") for path in removed_enums):
53
+ entry.level = BreakingChangeLevel.INFO
54
+ elif entry.path.endswith(".value") and entry.old_value in added_values.get(
55
+ entry.path.rsplit(".enum.", 1)[0], set()
56
+ ):
57
+ entry.level = BreakingChangeLevel.INFO
31
58
  entries_by_prefix = defaultdict(list)
32
59
  for entry in entries:
33
60
  prefix = ""
@@ -140,6 +140,43 @@ class MetadataFallbackRule(BreakingChangeRule):
140
140
  return RuleEvaluation(self.rule_id, BreakingChangeLevel.INFO, _change_message("contract", entry))
141
141
 
142
142
 
143
+ class EnumConstraintRule(BreakingChangeRule):
144
+ rule_id = "enum-constraint-changed"
145
+
146
+ def evaluate(self, entry: ChangelogEntry) -> RuleEvaluation | None:
147
+ if not entry.path.startswith("schema.") or ".properties." not in entry.path:
148
+ return None
149
+ if entry.path.endswith(".enum"):
150
+ level = BreakingChangeLevel.ERROR if entry.type == ChangelogType.added else BreakingChangeLevel.INFO
151
+ elif (
152
+ ".enum." in entry.path
153
+ and entry.path.endswith(".value")
154
+ and ".customProperties." not in entry.path.rsplit(".enum.", 1)[1]
155
+ and ".authoritativeDefinitions." not in entry.path.rsplit(".enum.", 1)[1]
156
+ ):
157
+ level = BreakingChangeLevel.INFO if entry.type == ChangelogType.added else BreakingChangeLevel.ERROR
158
+ else:
159
+ return None
160
+ return RuleEvaluation(self.rule_id, level, _change_message("allowed values", entry))
161
+
162
+
163
+ class VectorShapeRule(BreakingChangeRule):
164
+ rule_id = "vector-shape-changed"
165
+
166
+ def evaluate(self, entry: ChangelogEntry) -> RuleEvaluation | None:
167
+ if not entry.path.startswith("schema.") or not entry.path.endswith(
168
+ (".logicalTypeOptions.dimensions", ".logicalTypeOptions.elementType")
169
+ ):
170
+ return None
171
+ if entry.path.endswith(".elementType"):
172
+ old = entry.old_value or "float32"
173
+ new = entry.new_value or "float32"
174
+ level = BreakingChangeLevel.INFO if old == new else BreakingChangeLevel.ERROR
175
+ else:
176
+ level = BreakingChangeLevel.WARNING if entry.type == ChangelogType.removed else BreakingChangeLevel.ERROR
177
+ return RuleEvaluation(self.rule_id, level, _change_message("vector shape", entry))
178
+
179
+
143
180
  def _is_schema_property_path(segments: list[str]) -> bool:
144
181
  return len(segments) >= 3 and segments[0] == "schema" and segments[-2] == "properties"
145
182
 
@@ -192,5 +229,7 @@ DEFAULT_RULES: tuple[BreakingChangeRule, ...] = (
192
229
  UniqueConstraintRule(),
193
230
  KeyConstraintRule(),
194
231
  ValidationConstraintRule(),
232
+ EnumConstraintRule(),
233
+ VectorShapeRule(),
195
234
  MetadataFallbackRule(),
196
235
  )
@@ -44,6 +44,13 @@ Current hardcoded natural keys:
44
44
  schema[] SchemaObject -> .name (required: [name])
45
45
  schema[].properties[] SchemaProperty -> .name (required: [name], recursive)
46
46
  slaProperties[] SLAProperty -> .property
47
+ slaProperties[].customProperties[] CustomProperty -> .property
48
+ slaProperties[].authoritativeDefinitions[] AuthoritativeDefinition -> .url
49
+ schema[].properties[].enum[] EnumValue -> .value (or .id)
50
+ schema[]/properties[].synonyms[] Synonym -> .synonym (or .id)
51
+ schema[]/properties[].relationships[] Relationship -> .id, else from:to
52
+ context.verifiedStatements[] VerifiedStatement -> .question (or .id)
53
+ context.constraints[] Constraint -> .constraint (or .id)
47
54
  servers[] Server -> .server
48
55
  servers[].roles[] Role -> .role
49
56
  servers[].customProperties[] CustomProperty -> .property
@@ -82,15 +89,41 @@ def _normalize_auth_defs(items: list[dict]) -> dict:
82
89
  return result
83
90
 
84
91
 
92
+ def _normalize_keyed(items: list[dict], *keys: str) -> dict:
93
+ """Key a list of dicts by the first of ``keys`` an item carries, keeping the key in the value.
94
+
95
+ Falls back to the list index if none of the key fields is present.
96
+ """
97
+ result = {}
98
+ for i, item in enumerate(items):
99
+ key = next((str(item[k]) for k in keys if item.get(k) is not None), None) or f"__pos_{i}__"
100
+ result[key] = item
101
+ return result
102
+
103
+
104
+ def _normalize_context(context) -> object:
105
+ """Key the lists of a context block; a plain-string context is returned unchanged."""
106
+ if not isinstance(context, dict):
107
+ return context
108
+ entry = dict(context)
109
+ if isinstance(entry.get("verifiedStatements"), list):
110
+ entry["verifiedStatements"] = _normalize_keyed(entry["verifiedStatements"], "id", "question")
111
+ if isinstance(entry.get("constraints"), list):
112
+ entry["constraints"] = _normalize_keyed(entry["constraints"], "id", "constraint")
113
+ return entry
114
+
115
+
85
116
  def _normalize_relationships(items: list[dict], schema_level: bool = True) -> dict:
86
- """Key relationships by a stable composite key.
117
+ """Key relationships by their id (ODCS v3.2.0), else by a stable composite key.
87
118
 
88
119
  Schema-level: from:to composite. Property-level: to only.
89
120
  Falls back to positional index if key fields are absent.
90
121
  """
91
122
  result = {}
92
123
  for i, item in enumerate(items):
93
- if schema_level:
124
+ if item.get("id"):
125
+ key = str(item["id"])
126
+ elif schema_level:
94
127
  from_val = str(item.get("from", ""))
95
128
  to_val = str(item.get("to", ""))
96
129
  key = f"{from_val}:{to_val}" if (from_val or to_val) else f"__pos_{i}__"
@@ -125,6 +158,12 @@ def _normalize_schema_fields(entry: dict, *, schema_level: bool) -> dict:
125
158
  entry["authoritativeDefinitions"] = _normalize_auth_defs(entry["authoritativeDefinitions"])
126
159
  if "relationships" in entry and isinstance(entry["relationships"], list):
127
160
  entry["relationships"] = _normalize_relationships(entry["relationships"], schema_level=schema_level)
161
+ if "synonyms" in entry and isinstance(entry["synonyms"], list):
162
+ entry["synonyms"] = _normalize_keyed(entry["synonyms"], "id", "synonym")
163
+ if "enum" in entry and isinstance(entry["enum"], list):
164
+ entry["enum"] = _normalize_keyed(entry["enum"], "id", "value")
165
+ if "context" in entry:
166
+ entry["context"] = _normalize_context(entry["context"])
128
167
  return entry
129
168
 
130
169
 
@@ -134,13 +173,30 @@ def _normalize_properties(properties: list[dict]) -> dict:
134
173
  for prop in properties:
135
174
  key = prop.get("name", prop.get("id", str(prop)))
136
175
  entry = {k: v for k, v in prop.items() if k != "name"}
137
- if "properties" in entry and isinstance(entry["properties"], list):
138
- entry["properties"] = _normalize_properties(entry["properties"])
176
+ entry = _normalize_property_children(entry)
139
177
  entry = _normalize_schema_fields(entry, schema_level=False)
140
178
  result[key] = entry
141
179
  return result
142
180
 
143
181
 
182
+ def _normalize_property_children(entry: dict) -> dict:
183
+ """Recurse into the nested property definitions of a property: properties, items, map key and value."""
184
+ if "properties" in entry and isinstance(entry["properties"], list):
185
+ entry["properties"] = _normalize_properties(entry["properties"])
186
+ if isinstance(entry.get("items"), dict):
187
+ entry["items"] = _normalize_schema_fields(
188
+ _normalize_property_children(dict(entry["items"])), schema_level=False
189
+ )
190
+ if isinstance(entry.get("map"), dict):
191
+ entry["map"] = {
192
+ side: _normalize_schema_fields(_normalize_property_children(dict(definition)), schema_level=False)
193
+ if isinstance(definition, dict)
194
+ else definition
195
+ for side, definition in entry["map"].items()
196
+ }
197
+ return entry
198
+
199
+
144
200
  def normalize(contract: dict) -> dict:
145
201
  """Convert named lists to dicts keyed by their natural key field.
146
202
 
@@ -161,7 +217,16 @@ def normalize(contract: dict) -> dict:
161
217
  out["schema"] = normalized_schema
162
218
 
163
219
  if "slaProperties" in out and isinstance(out["slaProperties"], list):
164
- out["slaProperties"] = _normalize_by(out["slaProperties"], "property")
220
+ sla_properties = _normalize_by(out["slaProperties"], "property")
221
+ for entry in sla_properties.values():
222
+ if isinstance(entry.get("customProperties"), list):
223
+ entry["customProperties"] = _normalize_by(entry["customProperties"], "property")
224
+ if isinstance(entry.get("authoritativeDefinitions"), list):
225
+ entry["authoritativeDefinitions"] = _normalize_auth_defs(entry["authoritativeDefinitions"])
226
+ out["slaProperties"] = sla_properties
227
+
228
+ if "context" in out:
229
+ out["context"] = _normalize_context(out["context"])
165
230
 
166
231
  if "servers" in out and isinstance(out["servers"], list):
167
232
  normalized_servers = {}
@@ -461,13 +461,29 @@ def import_spark(
461
461
 
462
462
  @import_app.command(
463
463
  name="iceberg",
464
- epilog="Example: datacontract import iceberg --source schema.json --table orders --output datacontract.yaml",
464
+ epilog="Examples: datacontract import iceberg --source schema.json --table orders --output datacontract.yaml; "
465
+ "datacontract import iceberg --catalog-url https://polaris.example.com/api/catalog --namespace sales --table orders",
465
466
  )
466
467
  def import_iceberg(
467
- source: Annotated[Optional[str], typer.Option(help="Path to the Iceberg schema JSON file.")] = None,
468
+ source: Annotated[
469
+ Optional[str], typer.Option(help="Path to the Iceberg schema JSON file. Omit to read from a REST catalog.")
470
+ ] = None,
468
471
  table: Annotated[
469
472
  Optional[str],
470
- typer.Option(help="Table name to assign to the model created from the Iceberg schema."),
473
+ typer.Option(
474
+ help="Table name to assign to the model created from the Iceberg schema, or the table to load from the catalog."
475
+ ),
476
+ ] = None,
477
+ catalog_url: Annotated[
478
+ Optional[str],
479
+ typer.Option(help="REST catalog endpoint to load the table from (DATACONTRACT_ICEBERG_CATALOG_URL)."),
480
+ ] = None,
481
+ catalog: Annotated[Optional[str], typer.Option(help="Name of the catalog (DATACONTRACT_ICEBERG_CATALOG).")] = None,
482
+ namespace: Annotated[
483
+ Optional[str], typer.Option(help="Namespace of the table in the catalog (DATACONTRACT_ICEBERG_NAMESPACE).")
484
+ ] = None,
485
+ warehouse: Annotated[
486
+ Optional[str], typer.Option(help="Warehouse passed to the catalog (DATACONTRACT_ICEBERG_WAREHOUSE).")
471
487
  ] = None,
472
488
  output: output_option = None,
473
489
  schema: schema_option = None,
@@ -475,10 +491,20 @@ def import_iceberg(
475
491
  id: id_option = None,
476
492
  debug: debug_option = None,
477
493
  ):
478
- """Import a data contract from an Iceberg schema."""
494
+ """Import a data contract from an Iceberg schema file or a REST catalog."""
479
495
  enable_debug_logging(debug)
480
496
  result = DataContract.import_from_source(
481
- config=cli_config(), format="iceberg", source=source, schema=schema, iceberg_table=table, owner=owner, id=id
497
+ config=cli_config(),
498
+ format="iceberg",
499
+ source=source,
500
+ schema=schema,
501
+ iceberg_table=table,
502
+ iceberg_catalog_url=catalog_url,
503
+ iceberg_catalog=catalog,
504
+ iceberg_namespace=namespace,
505
+ iceberg_warehouse=warehouse,
506
+ owner=owner,
507
+ id=id,
482
508
  )
483
509
  _write_result(result, output)
484
510
 
@@ -4,7 +4,6 @@ from __future__ import annotations
4
4
 
5
5
  import logging
6
6
  import os
7
- import re
8
7
  from pathlib import Path
9
8
 
10
9
  from pydantic import Field, SecretStr
@@ -33,6 +32,7 @@ SERVER_OVERRIDE_OPTIONS = {
33
32
  "athena_catalog": "catalog",
34
33
  "athena_schema": "schema",
35
34
  "athena_staging_dir": "stagingDir",
35
+ "athena_workgroup": "workgroup",
36
36
  "bigquery_project": "project",
37
37
  "bigquery_dataset": "dataset",
38
38
  "databricks_server_hostname": "host",
@@ -40,6 +40,10 @@ SERVER_OVERRIDE_OPTIONS = {
40
40
  "databricks_schema": "schema",
41
41
  "duckdb_database": "database",
42
42
  "duckdb_schema": "schema",
43
+ "iceberg_catalog_url": "catalogUrl",
44
+ "iceberg_catalog": "catalog",
45
+ "iceberg_namespace": "namespace",
46
+ "iceberg_warehouse": "warehouse",
43
47
  "impala_host": "host",
44
48
  "impala_port": "port",
45
49
  "impala_database": "database",
@@ -104,6 +108,7 @@ class Config(BaseSettings):
104
108
  athena_catalog: str | None = None
105
109
  athena_schema: str | None = None
106
110
  athena_staging_dir: str | None = None
111
+ athena_workgroup: str | None = None
107
112
 
108
113
  # azure
109
114
  azure_connection_string: SecretStr | None = None
@@ -141,6 +146,19 @@ class Config(BaseSettings):
141
146
  gcs_key_id: str | None = None
142
147
  gcs_secret: SecretStr | None = None
143
148
 
149
+ # iceberg (REST catalog by default; data files use the s3_* options)
150
+ iceberg_catalog_type: str | None = None
151
+ iceberg_credential: SecretStr | None = None
152
+ iceberg_token: SecretStr | None = None
153
+ iceberg_s3_endpoint: str | None = None
154
+ iceberg_signing_name: str | None = None
155
+ iceberg_properties: str | None = None
156
+ # overrides for the contract's servers block
157
+ iceberg_catalog_url: str | None = None
158
+ iceberg_catalog: str | None = None
159
+ iceberg_namespace: str | None = None
160
+ iceberg_warehouse: str | None = None
161
+
144
162
  # impala
145
163
  impala_username: str | None = None
146
164
  impala_password: SecretStr | None = None
@@ -309,9 +327,10 @@ class Config(BaseSettings):
309
327
 
310
328
  Nested keys join with ``_`` to form the field name (``snowflake.username``
311
329
  → ``snowflake_username``); top-level scalars address the general options
312
- (``max_errors``). ``${VAR}`` references in string values are replaced with
313
- the environment variable's value at load time, so files can be committed
314
- without holding secrets. Unknown option names raise a ValueError.
330
+ (``max_errors``). ``${VAR}`` and ``${VAR:-default}`` references in string
331
+ values are replaced with the environment variable's value at load time,
332
+ so files can be committed without holding secrets. Unknown option names
333
+ raise a ValueError.
315
334
  """
316
335
  import yaml
317
336
 
@@ -469,6 +488,9 @@ class Config(BaseSettings):
469
488
  def get_athena_staging_dir(self, required: bool = False) -> str | None:
470
489
  return self._str_option("athena_staging_dir", required)
471
490
 
491
+ def get_athena_workgroup(self, required: bool = False) -> str | None:
492
+ return self._str_option("athena_workgroup", required)
493
+
472
494
  # --- azure ---
473
495
  def get_azure_connection_string(self, required: bool = False) -> str | None:
474
496
  return self._str_option("azure_connection_string", required)
@@ -536,6 +558,37 @@ class Config(BaseSettings):
536
558
  def get_gcs_secret(self, required: bool = False) -> str | None:
537
559
  return self._str_option("gcs_secret", required)
538
560
 
561
+ # --- iceberg ---
562
+ def get_iceberg_catalog_type(self, required: bool = False) -> str | None:
563
+ return self._str_option("iceberg_catalog_type", required)
564
+
565
+ def get_iceberg_s3_endpoint(self, required: bool = False) -> str | None:
566
+ return self._str_option("iceberg_s3_endpoint", required)
567
+
568
+ def get_iceberg_signing_name(self, required: bool = False) -> str | None:
569
+ return self._str_option("iceberg_signing_name", required)
570
+
571
+ def get_iceberg_properties(self, required: bool = False) -> str | None:
572
+ return self._str_option("iceberg_properties", required)
573
+
574
+ def get_iceberg_credential(self, required: bool = False) -> str | None:
575
+ return self._str_option("iceberg_credential", required)
576
+
577
+ def get_iceberg_token(self, required: bool = False) -> str | None:
578
+ return self._str_option("iceberg_token", required)
579
+
580
+ def get_iceberg_catalog_url(self, required: bool = False) -> str | None:
581
+ return self._str_option("iceberg_catalog_url", required)
582
+
583
+ def get_iceberg_catalog(self, required: bool = False) -> str | None:
584
+ return self._str_option("iceberg_catalog", required)
585
+
586
+ def get_iceberg_namespace(self, required: bool = False) -> str | None:
587
+ return self._str_option("iceberg_namespace", required)
588
+
589
+ def get_iceberg_warehouse(self, required: bool = False) -> str | None:
590
+ return self._str_option("iceberg_warehouse", required)
591
+
539
592
  # --- impala ---
540
593
  def get_impala_username(self, required: bool = False) -> str | None:
541
594
  return self._str_option("impala_username", required)
@@ -909,18 +962,8 @@ def unknown_snowflake_env_names() -> list[str]:
909
962
  return sorted(name for name in os.environ if name.startswith("DATACONTRACT_SNOWFLAKE_") and name not in known)
910
963
 
911
964
 
912
- _ENV_REFERENCE = re.compile(r"\$\{([A-Za-z_][A-Za-z0-9_]*)\}")
913
-
914
-
915
965
  def _interpolate_env(value, path):
916
- """Replace ``${VAR}`` references in string values with environment variable values."""
917
- if not isinstance(value, str):
918
- return value
919
-
920
- def replace(match):
921
- name = match.group(1)
922
- if name not in os.environ:
923
- raise ValueError(f"Environment variable {name} referenced in {path} is not set.")
924
- return os.environ[name]
966
+ """Replace ``${VAR}`` and ``${VAR:-default}`` references in string values with environment variable values."""
967
+ from datacontract.config.variables import resolve_variables
925
968
 
926
- return _ENV_REFERENCE.sub(replace, value)
969
+ return resolve_variables(value, source=f"config file {path}")
@@ -0,0 +1,133 @@
1
+ """Variable references in string values, per ODCS v3.2.0 (RFC 0050).
2
+
3
+ Any string value in a data contract may contain ``${VAR_NAME}`` or, with an
4
+ inline default, ``${VAR_NAME:-default}``. References are resolved from the
5
+ process environment (which includes a loaded ``.env`` file) at the moment a
6
+ value is *used*: when a connection is opened or a quality query is executed.
7
+ The loaded contract itself is never mutated, so ``export`` and ``publish``
8
+ write the references back verbatim.
9
+
10
+ A reference to an unset or empty variable without a default is an error;
11
+ an empty string is never substituted silently.
12
+ """
13
+
14
+ import os
15
+ import re
16
+
17
+ from open_data_contract_standard.model import Server
18
+ from pydantic import BaseModel
19
+
20
+ _VARIABLE = re.compile(r"\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}")
21
+
22
+
23
+ class UnresolvedVariableError(ValueError):
24
+ """A ``${VAR}`` reference names a variable that is unset and has no default."""
25
+
26
+ def __init__(self, name: str, source: str = ""):
27
+ self.name = name
28
+ where = f" in {source}" if source else ""
29
+ super().__init__(f"Variable {name} referenced{where} is not set.")
30
+
31
+
32
+ def contains_variables(value) -> bool:
33
+ """True if ``value`` is a string holding at least one ``${VAR}`` reference."""
34
+ return isinstance(value, str) and _VARIABLE.search(value) is not None
35
+
36
+
37
+ def resolve_variables(value, source: str = ""):
38
+ """Return ``value`` with every ``${VAR}`` reference replaced.
39
+
40
+ Non-string values pass through unchanged. ``source`` names the value in
41
+ the error message (``"server 'prod' host"``, ``"config file x.yaml"``).
42
+ """
43
+ if not isinstance(value, str):
44
+ return value
45
+
46
+ def replace(match: re.Match) -> str:
47
+ name, default = match.group(1), match.group(2)
48
+ env_value = os.environ.get(name)
49
+ if env_value:
50
+ return env_value
51
+ if default is not None:
52
+ return default
53
+ raise UnresolvedVariableError(name, source)
54
+
55
+ return _VARIABLE.sub(replace, value)
56
+
57
+
58
+ def resolve_server_variables(server: Server) -> Server:
59
+ """Return a copy of ``server`` with the references in its string fields resolved.
60
+
61
+ ``port`` may hold a reference (the schema allows a string there for that
62
+ reason); a resolved all-digit port becomes an int again. Custom property
63
+ values are resolved too. The contract's server is not mutated.
64
+ """
65
+ updates = {}
66
+ for field in Server.model_fields:
67
+ value = getattr(server, field)
68
+ if contains_variables(value):
69
+ updates[field] = resolve_variables(value, source=f"server '{server.server}' {_field_name(field)}")
70
+ port = updates.get("port", server.port)
71
+ if isinstance(port, str) and port.isdigit():
72
+ updates["port"] = int(port)
73
+ if server.customProperties:
74
+ custom_properties = []
75
+ changed = False
76
+ for prop in server.customProperties:
77
+ if contains_variables(prop.value):
78
+ changed = True
79
+ prop = prop.model_copy(
80
+ update={
81
+ "value": resolve_variables(
82
+ prop.value, source=f"server '{server.server}' custom property '{prop.property}'"
83
+ )
84
+ }
85
+ )
86
+ custom_properties.append(prop)
87
+ if changed:
88
+ updates["customProperties"] = custom_properties
89
+ return server.model_copy(update=updates) if updates else server
90
+
91
+
92
+ def _field_name(field: str) -> str:
93
+ return "schema" if field == "schema_" else field
94
+
95
+
96
+ # These fields document the contract rather than supply test inputs. SQL queries
97
+ # resolve separately, after the engine substitutes its ${model}/${field} tokens;
98
+ # servers resolve separately, after configuration overrides and server selection.
99
+ _DEFERRED_FIELDS = {
100
+ "authoritativeDefinitions",
101
+ "businessName",
102
+ "context",
103
+ "description",
104
+ "examples",
105
+ "implementation",
106
+ "query",
107
+ "servers",
108
+ "synonyms",
109
+ "transformLogic",
110
+ "transformSourceObjects",
111
+ }
112
+
113
+
114
+ def resolve_runtime_variables(value, source: str = "contract"):
115
+ """Copy test inputs with variables resolved, recursively, without altering the contract.
116
+
117
+ Handles property names/types, enum values, logical type options, library
118
+ quality arguments, SLA values, and nested array/map definitions. Dictionary
119
+ keys are structural identifiers and are never interpolated.
120
+ """
121
+ if isinstance(value, BaseModel):
122
+ return value.model_copy(
123
+ update={
124
+ field: resolve_runtime_variables(getattr(value, field), f"{source}.{_field_name(field)}")
125
+ for field in type(value).model_fields
126
+ if field not in _DEFERRED_FIELDS
127
+ }
128
+ )
129
+ if isinstance(value, dict):
130
+ return {key: resolve_runtime_variables(item, f"{source}.{key}") for key, item in value.items()}
131
+ if isinstance(value, list):
132
+ return [resolve_runtime_variables(item, f"{source}[{index}]") for index, item in enumerate(value)]
133
+ return resolve_variables(value, source=source)