datacontract-cli 0.10.24__py3-none-any.whl → 0.10.25__py3-none-any.whl

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

Potentially problematic release.


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

@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datacontract-cli
3
- Version: 0.10.24
3
+ Version: 0.10.25
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
+ License-Expression: MIT
6
7
  Project-URL: Homepage, https://cli.datacontract.com
7
8
  Project-URL: Issues, https://github.com/datacontract/datacontract-cli/issues
8
9
  Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Requires-Python: >=3.10
12
12
  Description-Content-Type: text/markdown
@@ -28,17 +28,21 @@ Requires-Dist: python-dotenv<2.0.0,>=1.0.0
28
28
  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
+ Requires-Dist: datacontract-specification<2.0.0,>=1.1.1
32
+ Requires-Dist: open-data-contract-standard<4.0.0,>=3.0.4
31
33
  Provides-Extra: avro
32
34
  Requires-Dist: avro==1.12.0; extra == "avro"
33
35
  Provides-Extra: bigquery
34
36
  Requires-Dist: soda-core-bigquery<3.6.0,>=3.3.20; extra == "bigquery"
35
37
  Provides-Extra: csv
36
38
  Requires-Dist: pandas>=2.0.0; extra == "csv"
39
+ Provides-Extra: excel
40
+ Requires-Dist: openpyxl<4.0.0,>=3.1.5; extra == "excel"
37
41
  Provides-Extra: databricks
38
42
  Requires-Dist: soda-core-spark-df<3.6.0,>=3.3.20; extra == "databricks"
39
43
  Requires-Dist: soda-core-spark[databricks]<3.6.0,>=3.3.20; extra == "databricks"
40
44
  Requires-Dist: databricks-sql-connector<4.1.0,>=3.7.0; extra == "databricks"
41
- Requires-Dist: databricks-sdk<0.50.0; extra == "databricks"
45
+ Requires-Dist: databricks-sdk<0.51.0; extra == "databricks"
42
46
  Provides-Extra: iceberg
43
47
  Requires-Dist: pyiceberg==0.8.1; extra == "iceberg"
44
48
  Provides-Extra: kafka
@@ -70,7 +74,7 @@ Requires-Dist: uvicorn==0.34.0; extra == "api"
70
74
  Provides-Extra: protobuf
71
75
  Requires-Dist: grpcio-tools>=1.53; extra == "protobuf"
72
76
  Provides-Extra: all
73
- Requires-Dist: datacontract-cli[api,bigquery,csv,databricks,dbml,dbt,iceberg,kafka,parquet,postgres,protobuf,rdf,s3,snowflake,sqlserver,trino]; extra == "all"
77
+ Requires-Dist: datacontract-cli[api,bigquery,csv,databricks,dbml,dbt,excel,iceberg,kafka,parquet,postgres,protobuf,rdf,s3,snowflake,sqlserver,trino]; extra == "all"
74
78
  Provides-Extra: dev
75
79
  Requires-Dist: datacontract-cli[all]; extra == "dev"
76
80
  Requires-Dist: httpx==0.28.1; extra == "dev"
@@ -900,6 +904,29 @@ models:
900
904
  | `DATACONTRACT_TRINO_PASSWORD` | `mysecretpassword` | Password |
901
905
 
902
906
 
907
+ #### Local
908
+
909
+ Data Contract CLI can test local files in parquet, json, csv, or delta format.
910
+
911
+ ##### Example
912
+
913
+ datacontract.yaml
914
+ ```yaml
915
+ servers:
916
+ local:
917
+ type: local
918
+ path: ./*.parquet
919
+ format: parquet
920
+ models:
921
+ my_table_1: # corresponds to a table
922
+ type: table
923
+ fields:
924
+ my_column_1: # corresponds to a column
925
+ type: varchar
926
+ my_column_2: # corresponds to a column
927
+ type: string
928
+ ```
929
+
903
930
 
904
931
  ### export
905
932
  ```
@@ -1994,7 +2021,8 @@ pytest
1994
2021
  ```bash
1995
2022
  # make sure uv is installed
1996
2023
  uv python pin 3.11
1997
- uv sync --all-extras
2024
+ uv pip install -e '.[dev]'
2025
+ uv run ruff check
1998
2026
  uv run pytest
1999
2027
  ```
2000
2028
 
@@ -1,6 +1,6 @@
1
1
  datacontract/__init__.py,sha256=ThDdxDJsd7qNErLoh628nK5M7RzhJNYCmN-C6BAJFoo,405
2
- datacontract/api.py,sha256=qZJr8I5MI4wZlvjUEAvqna9Xj5Ic2GCBxSyogBlKEbE,8166
3
- datacontract/cli.py,sha256=7jvwNDLe4TqaegpPiNOjMeHIg2qFxK6AGBWUkzqH7AM,16880
2
+ datacontract/api.py,sha256=031PVQbZGHPVpFLFHGQ-Igc5queVCnjAun6oxLDMIOo,8175
3
+ datacontract/cli.py,sha256=32f-hsUVUp_ArNbRB4uCr0dE-fxB5qpjB31lu_AbbmU,16863
4
4
  datacontract/data_contract.py,sha256=unt7wnThY4qMtexdCc4fYU0gCEwdhDdYjHn_u_Ya6_Q,10740
5
5
  datacontract/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  datacontract/breaking/breaking.py,sha256=DnqgxUjD-EAZcg5RBizOP9a2WxsFTaQBik0AB_m3K00,20431
@@ -37,36 +37,37 @@ datacontract/export/duckdb_type_converter.py,sha256=hUAAbImhJUMJOXEG-UoOKQqYGrJM
37
37
  datacontract/export/exporter.py,sha256=XrNmoIH_5Myb8jx-vaS1ZCF11RTw5zf5JATkqXWunXE,3025
38
38
  datacontract/export/exporter_factory.py,sha256=0XmU51fQNZVQdC78gDy_82CatazhioMmcd6qdCl8muU,5847
39
39
  datacontract/export/go_converter.py,sha256=Ttvbfu3YU-3GBwRD6nwCsFyZuc_hiIvJD-Jg2sT5WLw,3331
40
- datacontract/export/great_expectations_converter.py,sha256=zMaHaj5DLj_Q_q-iFEa7EZHW-qHdFMxWL4MiMIFKV80,10505
40
+ datacontract/export/great_expectations_converter.py,sha256=WvEa4HNUMyzn2a5YNkcI9mjROzGkKRYOS2gFPjRRHNc,12218
41
41
  datacontract/export/html_export.py,sha256=ojazWrb0AwSc7Vr72M_otMo-3PA8mfi8tfIy9BCXk9o,2578
42
42
  datacontract/export/iceberg_converter.py,sha256=ArcQ_Y3z_W4_kGDU_8jPRx2-pHpP3Nhx1zYoETOL3c4,6804
43
43
  datacontract/export/jsonschema_converter.py,sha256=2MT82MurcQQbrVDRj1kFsxnmFd9scNSfYI1upQSecl4,5631
44
44
  datacontract/export/markdown_converter.py,sha256=chtaZX4vXTee7JCMYmWiDQ9m55gwJjHPw6SEM3UOwpQ,6467
45
- datacontract/export/odcs_v3_exporter.py,sha256=-nGpIbdqV3OATWlJt_gDvtM8SscPEHk0RDGmFVWPlHw,13242
45
+ datacontract/export/odcs_v3_exporter.py,sha256=4iMPsREiVwODx29KETRUMcd1RRLRYLQy4mdwzsi0qbU,13128
46
46
  datacontract/export/pandas_type_converter.py,sha256=464pQ3JQKFQa1TO0HBNcEoZvQye_yUbY6jQtiBaphSc,1117
47
47
  datacontract/export/protobuf_converter.py,sha256=DHLl8BW26xqltBsd7Qhz0RhTl9YZQKCbkmjNpECgubg,7928
48
48
  datacontract/export/pydantic_converter.py,sha256=1Lt9F8i6zyQYb44MyQtsXwCWWXYxZ47SmzArr_uPqsU,5579
49
49
  datacontract/export/rdf_converter.py,sha256=4gnKus37Geth4MJ3Ruc8AbnpD_Ll9OCx8oTIEKScvh8,6435
50
50
  datacontract/export/sodacl_converter.py,sha256=lQCOcNiT7i6KGaJ1Ua4MYBYGm-EyktTGrL4FLZDi14c,1102
51
- datacontract/export/spark_converter.py,sha256=-6P2_VRFqGfSF7n_lJcD-fuY9Pv8qoH-ud6g8Zimpz4,7190
51
+ datacontract/export/spark_converter.py,sha256=LCue-rLan3ki7HgzUFyBaO8YUlc6CrDNBZD-QVgUv-U,7190
52
52
  datacontract/export/sql_converter.py,sha256=BGjmOAlzB5QfzJiXP61ajV0wj4M5oJrmNZZe_4Lo1Ik,4821
53
53
  datacontract/export/sql_type_converter.py,sha256=qjm8Fdyihq3VBL4x2D7RHdWoOm6HWIJe28U4XboYCk8,13436
54
54
  datacontract/export/sqlalchemy_converter.py,sha256=0DMncvA811lTtd5q4ZORREQ9YH1vQm1lJeqMWsFvloE,6463
55
55
  datacontract/export/terraform_converter.py,sha256=ExFoEvErVk-gBnWJiqC38SxDUmUEydpACWc917l5RyM,2163
56
- datacontract/imports/avro_importer.py,sha256=yvI3oupVkfWaTfVr9q6ruLCheirVN1GQ-fs_DDsZF24,10947
56
+ datacontract/imports/avro_importer.py,sha256=ryu4iUCSPJEV1uaE3AKdxD7fUxmRJ-ta936xurbgtHc,10922
57
57
  datacontract/imports/bigquery_importer.py,sha256=7TcP9FDsIas5LwJZ-HrOPXZ-NuR056sxLfDDh3vjo8E,8419
58
- datacontract/imports/csv_importer.py,sha256=pDwQ37KVc38B3iLauLTtVwUEKcawlJuM751xf01M0Lc,5330
58
+ datacontract/imports/csv_importer.py,sha256=mBsmyTvfB8q64Z3NYqv4zTDUOvoXG896hZvp3oLt5YM,5330
59
59
  datacontract/imports/dbml_importer.py,sha256=o0IOgvXN34lU1FICDHm_QUTv0DKsgwbHPHUDxQhIapE,3872
60
60
  datacontract/imports/dbt_importer.py,sha256=hQwqD9vbvwLLc6Yj3tQbar5ldI0pV-ynSiz7CZZ0JCc,8290
61
+ datacontract/imports/excel_importer.py,sha256=gBKBKYImkv-bpmJu7JChnGqh8Yie3WIlxvjqgq8wNSc,36951
61
62
  datacontract/imports/glue_importer.py,sha256=fiJPkvfwOCsaKKCGW19-JM5CCGXZ2mkNrVtUzp2iw6g,8370
62
63
  datacontract/imports/iceberg_importer.py,sha256=vadGJVqQKgG-j8swUytZALFB8QjbGRqZPCcPcCy0vco,5923
63
- datacontract/imports/importer.py,sha256=a3QF1pA5HavsSdczfyzGepoaMCkX1vfWr6abl6Maxmc,902
64
- datacontract/imports/importer_factory.py,sha256=XbUooE1icPT-dZxipDnnCeIaGsI1XwpH9y45pSaUVps,3807
64
+ datacontract/imports/importer.py,sha256=u9HJHQ_PQKW9MoIsfRxzs-qQ33JZbeo2EjZiB71O63c,1006
65
+ datacontract/imports/importer_factory.py,sha256=VBSrr9e3g09eJwnkZveJXuUMrQr072AcTJZ0q1MVf18,3966
65
66
  datacontract/imports/jsonschema_importer.py,sha256=67H__XLugV4vguHrIqzW02dtx27zYTWnOms4D1ma3bk,4961
66
67
  datacontract/imports/odcs_importer.py,sha256=vv2dHLGL0Cdivv1CdKn5euJwGNKmiZmXCoxUYAXsHX8,2126
67
- datacontract/imports/odcs_v3_importer.py,sha256=icCndBIFLXGLO4K_t6cSBKyZ0xQjO694YPpnxebj6xo,14997
68
+ datacontract/imports/odcs_v3_importer.py,sha256=sZVBENcPMl6rt0bbT_b1lnTFs3KOe1cZ2hwWaJBQhgY,16924
68
69
  datacontract/imports/parquet_importer.py,sha256=W_0_16mX4stwDUt4GM2L7dnGmTpAySab5k13-OlTCCc,3095
69
- datacontract/imports/protobuf_importer.py,sha256=AGwtsTHsawyCCM-dqXq3ZGDFyAIyA3Jq_HSXuxiJAi4,10842
70
+ datacontract/imports/protobuf_importer.py,sha256=rlUIskv9PNi5rFQ4Hobt9zlnKpahGsb4dy5G5UJoVAw,10840
70
71
  datacontract/imports/spark_importer.py,sha256=h2na1YtdJYu9Oz07tSvwx8L4RX6aLCCDVkAv-RTKyVA,5100
71
72
  datacontract/imports/sql_importer.py,sha256=ElFS2LILDOvWzW-X4emSIKltFV42i78TEoyg0bvn3II,9322
72
73
  datacontract/imports/unity_importer.py,sha256=UcPYABhLZaWNl5IkCazwAuMoVDdujsu_QteuV_Q9hgI,6737
@@ -79,15 +80,15 @@ datacontract/lint/resources.py,sha256=nfeZmORh1aP7EKpMKCmfbS04Te8pQ0nz64vJVkHOq3
79
80
  datacontract/lint/schema.py,sha256=4pYX6JX6SkASftyqaWTodKFRVPi2qV0_Z60tvaCOk80,1813
80
81
  datacontract/lint/urls.py,sha256=giac0eAYa6hha8exleL3KsiPtiFlOq8l53axtAmCilw,2529
81
82
  datacontract/lint/linters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
- datacontract/lint/linters/description_linter.py,sha256=7fla7FQwDa-1UrLFCFKFoeUzkR91e4o9W6ySKSW6_U8,1555
83
+ datacontract/lint/linters/description_linter.py,sha256=kQi38TKhqiEL3fwQDs6SdQQ9hXBHgfAi6Q6ZFNuLw1o,1505
83
84
  datacontract/lint/linters/field_pattern_linter.py,sha256=lreGvOW3v_Glah_SriVe9ejZ7EuR6_gJsdr2tEORB_8,1084
84
- datacontract/lint/linters/field_reference_linter.py,sha256=65GnbBtazn55dXslujOho3YIHCwNy9DDp0m56pNMkUk,2021
85
- datacontract/lint/linters/notice_period_linter.py,sha256=6r413aEVOVHWJHb33-68ecVTAUNzbxL4me6ebmPcgpE,2130
86
- datacontract/lint/linters/valid_constraints_linter.py,sha256=qTFh1X3I9wOtAxuXlvbGesCQ3GQ6iWc-MT_ttIybRsw,4916
87
- datacontract/model/data_contract_specification.py,sha256=5-59qU0BD1mM4D7LuUGuJeUFSG9vkICEVYI9bA2wsI4,8673
85
+ datacontract/lint/linters/field_reference_linter.py,sha256=klLsQleJwW2qSJT0haS_V63oo7uYt2-SXbJh-rRkfVI,1989
86
+ datacontract/lint/linters/notice_period_linter.py,sha256=_0ZrwlHWA8my0IWAY3upQNKfeigj5N0ulT7Me9kd2PE,2124
87
+ datacontract/lint/linters/valid_constraints_linter.py,sha256=-IUyFFoEbnoNbjjJntlJv1POajh2mRU-4mJQVPL5r9s,4904
88
88
  datacontract/model/exceptions.py,sha256=5BMuEH2qWuckNP4FTfpUEeEu6rjgGcLOD0GQugKRQ1U,1242
89
89
  datacontract/model/odcs.py,sha256=9PXwm72FASjNwteF1Jn591iP3-St0aq16Cpsk0PkEW8,389
90
90
  datacontract/model/run.py,sha256=4UdEUaJl5RxEpN9S3swSu1vGJUVyNhOpRkdfbBZhh90,3146
91
+ datacontract/model/data_contract_specification/__init__.py,sha256=lO7ywraknlDwJNUaSd2B9FWFsWhE8v5S-kob_shW_lg,47
91
92
  datacontract/output/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
93
  datacontract/output/junit_test_results.py,sha256=hAT7UgxwbfNzA0f5uuGzM4OIwLfXbmA4dgsfxsclWh0,4822
93
94
  datacontract/output/output_format.py,sha256=_ZokDBo7-HXBs6czUv7kLLf9cYft_q5QaKzthsVnc58,212
@@ -106,9 +107,9 @@ datacontract/templates/partials/model_field.html,sha256=2YBF95ypNCPFYuYKoeilRnDG
106
107
  datacontract/templates/partials/quality.html,sha256=ynEDWRn8I90Uje-xhGYgFcfwOgKI1R-CDki-EvTsauQ,1785
107
108
  datacontract/templates/partials/server.html,sha256=WkWFbz1ZvhIAUQQhH5Lkwb0HZRW907ehEnFmJSkpquQ,6235
108
109
  datacontract/templates/style/output.css,sha256=V1k6smSvlz07W2UNOkhcDFUb0HLmoas7DnNg_o8XUcA,25759
109
- datacontract_cli-0.10.24.dist-info/licenses/LICENSE,sha256=23h64qnSeIZ0DKeziWAKC-zBCt328iSbRbWBrXoYRb4,2210
110
- datacontract_cli-0.10.24.dist-info/METADATA,sha256=QqfRrDVFBpt6_oh7hLt-Qs6SvJq8l3Wv4Kvv128nqkY,103839
111
- datacontract_cli-0.10.24.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
112
- datacontract_cli-0.10.24.dist-info/entry_points.txt,sha256=D3Eqy4q_Z6bHauGd4ppIyQglwbrm1AJnLau4Ppbw9Is,54
113
- datacontract_cli-0.10.24.dist-info/top_level.txt,sha256=VIRjd8EIUrBYWjEXJJjtdUgc0UAJdPZjmLiOR8BRBYM,13
114
- datacontract_cli-0.10.24.dist-info/RECORD,,
110
+ datacontract_cli-0.10.25.dist-info/licenses/LICENSE,sha256=23h64qnSeIZ0DKeziWAKC-zBCt328iSbRbWBrXoYRb4,2210
111
+ datacontract_cli-0.10.25.dist-info/METADATA,sha256=Kc_fZ_wuwVoDjKluxLUkH0-chM_b_lMcsCUnm9tNlyo,104455
112
+ datacontract_cli-0.10.25.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
113
+ datacontract_cli-0.10.25.dist-info/entry_points.txt,sha256=D3Eqy4q_Z6bHauGd4ppIyQglwbrm1AJnLau4Ppbw9Is,54
114
+ datacontract_cli-0.10.25.dist-info/top_level.txt,sha256=VIRjd8EIUrBYWjEXJJjtdUgc0UAJdPZjmLiOR8BRBYM,13
115
+ datacontract_cli-0.10.25.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,327 +0,0 @@
1
- import os
2
- from typing import Any, Dict, List
3
-
4
- import pydantic as pyd
5
- import yaml
6
-
7
- DATACONTRACT_TYPES = [
8
- "string",
9
- "text",
10
- "varchar",
11
- "number",
12
- "decimal",
13
- "numeric",
14
- "int",
15
- "integer",
16
- "long",
17
- "bigint",
18
- "float",
19
- "double",
20
- "boolean",
21
- "timestamp",
22
- "timestamp_tz",
23
- "timestamp_ntz",
24
- "date",
25
- "array",
26
- "bytes",
27
- "object",
28
- "record",
29
- "struct",
30
- "null",
31
- ]
32
-
33
-
34
- class Contact(pyd.BaseModel):
35
- name: str | None = None
36
- url: str | None = None
37
- email: str | None = None
38
-
39
- model_config = pyd.ConfigDict(
40
- extra="allow",
41
- )
42
-
43
-
44
- class ServerRole(pyd.BaseModel):
45
- name: str | None = None
46
- description: str | None = None
47
- model_config = pyd.ConfigDict(
48
- extra="allow",
49
- )
50
-
51
-
52
- class Server(pyd.BaseModel):
53
- type: str | None = None
54
- description: str | None = None
55
- environment: str | None = None
56
- format: str | None = None
57
- project: str | None = None
58
- dataset: str | None = None
59
- path: str | None = None
60
- delimiter: str | None = None
61
- endpointUrl: str | None = None
62
- location: str | None = None
63
- account: str | None = None
64
- database: str | None = None
65
- schema_: str | None = pyd.Field(default=None, alias="schema")
66
- host: str | None = None
67
- port: int | None = None
68
- catalog: str | None = None
69
- topic: str | None = None
70
- http_path: str | None = None # Use ENV variable
71
- token: str | None = None # Use ENV variable
72
- dataProductId: str | None = None
73
- outputPortId: str | None = None
74
- driver: str | None = None
75
- storageAccount: str | None = None
76
- roles: List[ServerRole] = None
77
-
78
- model_config = pyd.ConfigDict(
79
- extra="allow",
80
- )
81
-
82
-
83
- class Terms(pyd.BaseModel):
84
- usage: str | None = None
85
- limitations: str | None = None
86
- billing: str | None = None
87
- noticePeriod: str | None = None
88
- description: str | None = None
89
-
90
- model_config = pyd.ConfigDict(
91
- extra="allow",
92
- )
93
-
94
-
95
- class Definition(pyd.BaseModel):
96
- domain: str | None = None
97
- name: str | None = None
98
- title: str | None = None
99
- description: str | None = None
100
- type: str | None = None
101
- enum: List[str] = []
102
- format: str | None = None
103
- minLength: int | None = None
104
- maxLength: int | None = None
105
- pattern: str | None = None
106
- minimum: int | None = None
107
- exclusiveMinimum: int | None = None
108
- maximum: int | None = None
109
- exclusiveMaximum: int | None = None
110
- pii: bool | None = None
111
- classification: str | None = None
112
- fields: Dict[str, "Field"] = {}
113
- items: "Field" = None
114
- tags: List[str] = []
115
- links: Dict[str, str] = {}
116
- example: str | None = None
117
- examples: List[Any] | None = None
118
-
119
- model_config = pyd.ConfigDict(
120
- extra="allow",
121
- )
122
-
123
-
124
- class Quality(pyd.BaseModel):
125
- type: str | None = None
126
- description: str | None = None
127
- query: str | None = None
128
- dialect: str | None = None
129
- mustBe: int | None = None
130
- mustNotBe: int | None = None
131
- mustBeGreaterThan: int | None = None
132
- mustBeGreaterThanOrEqualTo: int | None = None
133
- mustBeLessThan: int | None = None
134
- mustBeLessThanOrEqualTo: int | None = None
135
- mustBeBetween: List[int] = None
136
- mustNotBeBetween: List[int] = None
137
- engine: str | None = None
138
- implementation: str | Dict[str, Any] | None = None
139
-
140
- model_config = pyd.ConfigDict(
141
- extra="allow",
142
- )
143
-
144
-
145
- class Field(pyd.BaseModel):
146
- ref: str = pyd.Field(default=None, alias="$ref")
147
- title: str | None = None
148
- type: str | None = None
149
- format: str | None = None
150
- required: bool | None = None
151
- primary: bool = pyd.Field(
152
- default=None,
153
- deprecated="Removed in Data Contract Specification v1.1.0. Use primaryKey instead.",
154
- )
155
- primaryKey: bool | None = None
156
- unique: bool | None = None
157
- references: str | None = None
158
- description: str | None = None
159
- pii: bool | None = None
160
- classification: str | None = None
161
- pattern: str | None = None
162
- minLength: int | None = None
163
- maxLength: int | None = None
164
- minimum: int | None = None
165
- exclusiveMinimum: int | None = None
166
- maximum: int | None = None
167
- exclusiveMaximum: int | None = None
168
- enum: List[str] | None = []
169
- tags: List[str] | None = []
170
- links: Dict[str, str] = {}
171
- fields: Dict[str, "Field"] = {}
172
- items: "Field" = None
173
- keys: "Field" = None
174
- values: "Field" = None
175
- precision: int | None = None
176
- scale: int | None = None
177
- example: Any | None = pyd.Field(
178
- default=None,
179
- deprecated="Removed in Data Contract Specification v1.1.0. Use examples instead.",
180
- )
181
- examples: List[Any] | None = None
182
- quality: List[Quality] | None = []
183
- config: Dict[str, Any] | None = None
184
-
185
- model_config = pyd.ConfigDict(
186
- extra="allow",
187
- )
188
-
189
-
190
- class Model(pyd.BaseModel):
191
- description: str | None = None
192
- type: str | None = None
193
- namespace: str | None = None
194
- title: str | None = None
195
- fields: Dict[str, Field] = {}
196
- quality: List[Quality] | None = []
197
- primaryKey: List[str] | None = []
198
- examples: List[Any] | None = None
199
- config: Dict[str, Any] = None
200
- tags: List[str] | None = None
201
-
202
- model_config = pyd.ConfigDict(
203
- extra="allow",
204
- )
205
-
206
-
207
- class Info(pyd.BaseModel):
208
- title: str | None = None
209
- version: str | None = None
210
- status: str | None = None
211
- description: str | None = None
212
- owner: str | None = None
213
- contact: Contact | None = None
214
-
215
- model_config = pyd.ConfigDict(
216
- extra="allow",
217
- )
218
-
219
-
220
- class Example(pyd.BaseModel):
221
- type: str | None = None
222
- description: str | None = None
223
- model: str | None = None
224
- data: str | object = None
225
-
226
-
227
- # Deprecated Quality class
228
- class DeprecatedQuality(pyd.BaseModel):
229
- type: str | None = None
230
- specification: str | object = None
231
-
232
-
233
- class Availability(pyd.BaseModel):
234
- description: str | None = None
235
- percentage: str | None = None
236
-
237
-
238
- class Retention(pyd.BaseModel):
239
- description: str | None = None
240
- period: str | None = None
241
- unlimited: bool | None = None
242
- timestampField: str | None = None
243
-
244
-
245
- class Latency(pyd.BaseModel):
246
- description: str | None = None
247
- threshold: str | None = None
248
- sourceTimestampField: str | None = None
249
- processedTimestampField: str | None = None
250
-
251
-
252
- class Freshness(pyd.BaseModel):
253
- description: str | None = None
254
- threshold: str | None = None
255
- timestampField: str | None = None
256
-
257
-
258
- class Frequency(pyd.BaseModel):
259
- description: str | None = None
260
- type: str | None = None
261
- interval: str | None = None
262
- cron: str | None = None
263
-
264
-
265
- class Support(pyd.BaseModel):
266
- description: str | None = None
267
- time: str | None = None
268
- responseTime: str | None = None
269
-
270
-
271
- class Backup(pyd.BaseModel):
272
- description: str | None = None
273
- interval: str | None = None
274
- cron: str | None = None
275
- recoveryTime: str | None = None
276
- recoveryPoint: str | None = None
277
-
278
-
279
- class ServiceLevel(pyd.BaseModel):
280
- availability: Availability | None = None
281
- retention: Retention | None = None
282
- latency: Latency | None = None
283
- freshness: Freshness | None = None
284
- frequency: Frequency | None = None
285
- support: Support | None = None
286
- backup: Backup | None = None
287
-
288
-
289
- class DataContractSpecification(pyd.BaseModel):
290
- dataContractSpecification: str | None = None
291
- id: str | None = None
292
- info: Info | None = None
293
- servers: Dict[str, Server] = {}
294
- terms: Terms | None = None
295
- models: Dict[str, Model] = {}
296
- definitions: Dict[str, Definition] = {}
297
- examples: List[Example] = pyd.Field(
298
- default_factory=list,
299
- deprecated="Removed in Data Contract Specification " "v1.1.0. Use models.examples instead.",
300
- )
301
- quality: DeprecatedQuality | None = pyd.Field(
302
- default=None,
303
- deprecated="Removed in Data Contract Specification v1.1.0. Use " "model-level and field-level quality instead.",
304
- )
305
- servicelevels: ServiceLevel | None = None
306
- links: Dict[str, str] = {}
307
- tags: List[str] = []
308
-
309
- @classmethod
310
- def from_file(cls, file):
311
- if not os.path.exists(file):
312
- raise FileNotFoundError(f"The file '{file}' does not exist.")
313
- with open(file, "r") as file:
314
- file_content = file.read()
315
- return DataContractSpecification.from_string(file_content)
316
-
317
- @classmethod
318
- def from_string(cls, data_contract_str):
319
- data = yaml.safe_load(data_contract_str)
320
- return DataContractSpecification(**data)
321
-
322
- def to_yaml(self):
323
- return yaml.safe_dump(
324
- self.model_dump(mode="json", exclude_defaults=True, exclude_none=True, by_alias=True),
325
- sort_keys=False,
326
- allow_unicode=True,
327
- )