datacontract-cli 0.10.7__py3-none-any.whl → 0.10.9__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.

Files changed (55) hide show
  1. datacontract/catalog/catalog.py +4 -2
  2. datacontract/cli.py +44 -15
  3. datacontract/data_contract.py +52 -206
  4. datacontract/engines/fastjsonschema/s3/s3_read_files.py +13 -1
  5. datacontract/engines/soda/check_soda_execute.py +9 -2
  6. datacontract/engines/soda/connections/bigquery.py +8 -1
  7. datacontract/engines/soda/connections/duckdb.py +28 -12
  8. datacontract/engines/soda/connections/trino.py +26 -0
  9. datacontract/export/__init__.py +0 -0
  10. datacontract/export/avro_converter.py +15 -3
  11. datacontract/export/avro_idl_converter.py +29 -22
  12. datacontract/export/bigquery_converter.py +15 -0
  13. datacontract/export/dbml_converter.py +9 -0
  14. datacontract/export/dbt_converter.py +26 -1
  15. datacontract/export/exporter.py +88 -0
  16. datacontract/export/exporter_factory.py +145 -0
  17. datacontract/export/go_converter.py +6 -0
  18. datacontract/export/great_expectations_converter.py +10 -0
  19. datacontract/export/html_export.py +6 -0
  20. datacontract/export/jsonschema_converter.py +31 -23
  21. datacontract/export/odcs_converter.py +24 -1
  22. datacontract/export/protobuf_converter.py +6 -0
  23. datacontract/export/pydantic_converter.py +6 -0
  24. datacontract/export/rdf_converter.py +9 -0
  25. datacontract/export/sodacl_converter.py +23 -12
  26. datacontract/export/spark_converter.py +211 -0
  27. datacontract/export/sql_converter.py +32 -2
  28. datacontract/export/sql_type_converter.py +32 -5
  29. datacontract/export/terraform_converter.py +6 -0
  30. datacontract/imports/avro_importer.py +8 -0
  31. datacontract/imports/bigquery_importer.py +47 -4
  32. datacontract/imports/glue_importer.py +122 -30
  33. datacontract/imports/importer.py +29 -0
  34. datacontract/imports/importer_factory.py +72 -0
  35. datacontract/imports/jsonschema_importer.py +8 -0
  36. datacontract/imports/odcs_importer.py +200 -0
  37. datacontract/imports/sql_importer.py +8 -0
  38. datacontract/imports/unity_importer.py +152 -0
  39. datacontract/lint/resolve.py +22 -1
  40. datacontract/model/data_contract_specification.py +36 -4
  41. datacontract/templates/datacontract.html +17 -2
  42. datacontract/templates/partials/datacontract_information.html +20 -0
  43. datacontract/templates/partials/datacontract_terms.html +7 -0
  44. datacontract/templates/partials/definition.html +9 -1
  45. datacontract/templates/partials/model_field.html +23 -6
  46. datacontract/templates/partials/server.html +113 -48
  47. datacontract/templates/style/output.css +51 -0
  48. datacontract/web.py +17 -0
  49. {datacontract_cli-0.10.7.dist-info → datacontract_cli-0.10.9.dist-info}/METADATA +298 -59
  50. datacontract_cli-0.10.9.dist-info/RECORD +93 -0
  51. {datacontract_cli-0.10.7.dist-info → datacontract_cli-0.10.9.dist-info}/WHEEL +1 -1
  52. datacontract_cli-0.10.7.dist-info/RECORD +0 -84
  53. {datacontract_cli-0.10.7.dist-info → datacontract_cli-0.10.9.dist-info}/LICENSE +0 -0
  54. {datacontract_cli-0.10.7.dist-info → datacontract_cli-0.10.9.dist-info}/entry_points.txt +0 -0
  55. {datacontract_cli-0.10.7.dist-info → datacontract_cli-0.10.9.dist-info}/top_level.txt +0 -0
@@ -1,144 +1,209 @@
1
1
  <li class="relative flex gap-x-6 px-4 py-5 sm:px-6">
2
2
  <div class="flex items-center gap-x-4">
3
- <div class="hidden sm:flex sm:flex-col">
4
- <dt class="text-sm font-medium text-gray-500">Server</dt>
5
- <dd class="mt-1 text-sm text-gray-900">{{server_name}}</dd>
3
+ <div class="sm:flex sm:flex-col">
4
+ <div class="flex flex-col">
5
+ <dt class="text-sm font-medium text-gray-500">Server</dt>
6
+ <dd class="mt-1 text-sm text-gray-900">{{server_name}}</dd>
7
+ </div>
6
8
  </div>
7
9
  </div>
8
10
 
11
+ {% if server.environment %}
12
+ <div class="flex items-center gap-x-4">
13
+ <div class="sm:flex sm:flex-col">
14
+ <div class="flex flex-col">
15
+ <dt class="text-sm font-medium text-gray-500">Environment</dt>
16
+ <dd class="mt-1 text-sm text-gray-900">{{server.environment}}</dd>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ {% endif %}
21
+
9
22
  {% if server.type %}
10
23
  <div class="flex items-center gap-x-4">
11
- <div class="hidden sm:flex sm:flex-col">
12
- <dt class="text-sm font-medium text-gray-500">Type</dt>
13
- <dd class="mt-1 text-sm text-gray-900">{{server.type}}</dd>
24
+ <div class="sm:flex sm:flex-col">
25
+ <div class="flex flex-col">
26
+ <dt class="text-sm font-medium text-gray-500">Type</dt>
27
+ <dd class="mt-1 text-sm text-gray-900">{{server.type}}</dd>
28
+ </div>
14
29
  </div>
15
30
  </div>
16
31
  {% endif %}
17
32
 
18
33
  {% if server.project %}
19
34
  <div class="flex items-center gap-x-4">
20
- <div class="hidden sm:flex sm:flex-col">
21
- <dt class="text-sm font-medium text-gray-500">Project</dt>
22
- <dd class="mt-1 text-sm text-gray-900">{{server.project}}</dd>
35
+ <div class="sm:flex sm:flex-col">
36
+ <div class="flex flex-col">
37
+ <dt class="text-sm font-medium text-gray-500">Project</dt>
38
+ <dd class="mt-1 text-sm text-gray-900">{{server.project}}</dd>
39
+ </div>
23
40
  </div>
24
41
  </div>
25
42
  {% endif %}
26
43
 
27
44
  {% if server.dataset %}
28
45
  <div class="flex items-center gap-x-4">
29
- <div class="hidden sm:flex sm:flex-col">
30
- <dt class="text-sm font-medium text-gray-500">Dataset</dt>
31
- <dd class="mt-1 text-sm text-gray-900">{{server.dataset}}</dd>
46
+ <div class="sm:flex sm:flex-col">
47
+ <div class="flex flex-col">
48
+ <dt class="text-sm font-medium text-gray-500">Dataset</dt>
49
+ <dd class="mt-1 text-sm text-gray-900">{{server.dataset}}</dd>
50
+ </div>
32
51
  </div>
33
52
  </div>
34
53
  {% endif %}
35
54
 
36
55
  {% if server.location %}
37
56
  <div class="flex items-center gap-x-4">
38
- <div class="hidden sm:flex sm:flex-col">
39
- <dt class="text-sm font-medium text-gray-500">Location</dt>
40
- <dd class="mt-1 text-sm text-gray-900">{{server.location}}</dd>
57
+ <div class="sm:flex sm:flex-col">
58
+ <div class="flex flex-col">
59
+ <dt class="text-sm font-medium text-gray-500">Location</dt>
60
+ <dd class="mt-1 text-sm text-gray-900">{{server.location}}</dd>
61
+ </div>
41
62
  </div>
42
63
  </div>
43
64
  {% endif %}
44
65
 
45
66
  {% if server.endpointUrl %}
46
67
  <div class="flex items-center gap-x-4">
47
- <div class="hidden sm:flex sm:flex-col">
48
- <dt class="text-sm font-medium text-gray-500">Endpoint URL</dt>
49
- <dd class="mt-1 text-sm text-gray-900">{{server.endpointUrl}}</dd>
68
+ <div class="sm:flex sm:flex-col">
69
+ <div class="flex flex-col">
70
+ <dt class="text-sm font-medium text-gray-500">Endpoint URL</dt>
71
+ <dd class="mt-1 text-sm text-gray-900">{{server.endpointUrl}}</dd>
72
+ </div>
50
73
  </div>
51
74
  </div>
52
75
  {% endif %}
53
76
 
54
77
  {% if server.account %}
55
78
  <div class="flex items-center gap-x-4">
56
- <div class="hidden sm:flex sm:flex-col">
57
- <dt class="text-sm font-medium text-gray-500">Account</dt>
58
- <dd class="mt-1 text-sm text-gray-900">{{server.account}}</dd>
79
+ <div class="sm:flex sm:flex-col">
80
+ <div class="flex flex-col">
81
+ <dt class="text-sm font-medium text-gray-500">Account</dt>
82
+ <dd class="mt-1 text-sm text-gray-900">{{server.account}}</dd>
83
+ </div>
59
84
  </div>
60
85
  </div>
61
86
  {% endif %}
62
87
 
63
88
  {% if server.host %}
64
89
  <div class="flex items-center gap-x-4">
65
- <div class="hidden sm:flex sm:flex-col">
66
- <dt class="text-sm font-medium text-gray-500">Host</dt>
67
- <dd class="mt-1 text-sm text-gray-900">{{server.host}}</dd>
90
+ <div class="sm:flex sm:flex-col">
91
+ <div class="flex flex-col">
92
+ <dt class="text-sm font-medium text-gray-500">Host</dt>
93
+ <dd class="mt-1 text-sm text-gray-900">{{server.host}}</dd>
94
+ </div>
68
95
  </div>
69
96
  </div>
70
97
  {% endif %}
71
98
 
72
99
  {% if server.port %}
73
100
  <div class="flex items-center gap-x-4">
74
- <div class="hidden sm:flex sm:flex-col">
75
- <dt class="text-sm font-medium text-gray-500">Port</dt>
76
- <dd class="mt-1 text-sm text-gray-900">{{server.port}}</dd>
101
+ <div class="sm:flex sm:flex-col">
102
+ <div class="flex flex-col">
103
+ <dt class="text-sm font-medium text-gray-500">Port</dt>
104
+ <dd class="mt-1 text-sm text-gray-900">{{server.port}}</dd>
105
+ </div>
77
106
  </div>
78
107
  </div>
79
108
  {% endif %}
80
109
 
81
110
  {% if server.catalog %}
82
111
  <div class="flex items-center gap-x-4">
83
- <div class="hidden sm:flex sm:flex-col">
84
- <dt class="text-sm font-medium text-gray-500">Catalog</dt>
85
- <dd class="mt-1 text-sm text-gray-900">{{server.catalog}}</dd>
112
+ <div class="sm:flex sm:flex-col">
113
+ <div class="flex flex-col">
114
+ <dt class="text-sm font-medium text-gray-500">Catalog</dt>
115
+ <dd class="mt-1 text-sm text-gray-900">{{server.catalog}}</dd>
116
+ </div>
86
117
  </div>
87
118
  </div>
88
119
  {% endif %}
89
120
 
90
121
  {% if server.database %}
91
122
  <div class="flex items-center gap-x-4">
92
- <div class="hidden sm:flex sm:flex-col">
93
- <dt class="text-sm font-medium text-gray-500">Database</dt>
94
- <dd class="mt-1 text-sm text-gray-900">{{server.database}}</dd>
123
+ <div class="sm:flex sm:flex-col">
124
+ <div class="flex flex-col">
125
+ <dt class="text-sm font-medium text-gray-500">Database</dt>
126
+ <dd class="mt-1 text-sm text-gray-900">{{server.database}}</dd>
127
+ </div>
95
128
  </div>
96
129
  </div>
97
130
  {% endif %}
98
131
 
99
132
  {% if server.schema_ %}
100
133
  <div class="flex items-center gap-x-4">
101
- <div class="hidden sm:flex sm:flex-col">
102
- <dt class="text-sm font-medium text-gray-500">Schema</dt>
103
- <dd class="mt-1 text-sm text-gray-900">{{server.schema_}}</dd>
134
+ <div class="sm:flex sm:flex-col">
135
+ <div class="flex flex-col">
136
+ <dt class="text-sm font-medium text-gray-500">Schema</dt>
137
+ <dd class="mt-1 text-sm text-gray-900">{{server.schema_}}</dd>
138
+ </div>
104
139
  </div>
105
140
  </div>
106
141
  {% endif %}
107
142
 
108
143
  {% if server.topic %}
109
144
  <div class="flex items-center gap-x-4">
110
- <div class="hidden sm:flex sm:flex-col">
111
- <dt class="text-sm font-medium text-gray-500">Topic</dt>
112
- <dd class="mt-1 text-sm text-gray-900">{{server.topic}}</dd>
145
+ <div class="sm:flex sm:flex-col">
146
+ <div class="flex flex-col">
147
+ <dt class="text-sm font-medium text-gray-500">Topic</dt>
148
+ <dd class="mt-1 text-sm text-gray-900">{{server.topic}}</dd>
149
+ </div>
113
150
  </div>
114
151
  </div>
115
152
  {% endif %}
116
153
 
117
154
  {% if server.path %}
118
155
  <div class="flex items-center gap-x-4">
119
- <div class="hidden sm:flex sm:flex-col">
120
- <dt class="text-sm font-medium text-gray-500">Path</dt>
121
- <dd class="mt-1 text-sm text-gray-900">{{server.path}}</dd>
156
+ <div class="sm:flex sm:flex-col">
157
+ <div class="flex flex-col">
158
+ <dt class="text-sm font-medium text-gray-500">Path</dt>
159
+ <dd class="mt-1 text-sm text-gray-900">{{server.path}}</dd>
160
+ </div>
122
161
  </div>
123
162
  </div>
124
163
  {% endif %}
125
164
 
126
165
  {% if server.format %}
127
166
  <div class="flex items-center gap-x-4">
128
- <div class="hidden sm:flex sm:flex-col">
129
- <dt class="text-sm font-medium text-gray-500">Format</dt>
130
- <dd class="mt-1 text-sm text-gray-900">{{server.format}}</dd>
167
+ <div class="sm:flex sm:flex-col">
168
+ <div class="flex flex-col">
169
+ <dt class="text-sm font-medium text-gray-500">Format</dt>
170
+ <dd class="mt-1 text-sm text-gray-900">{{server.format}}</dd>
171
+ </div>
131
172
  </div>
132
173
  </div>
133
174
  {% endif %}
134
175
 
135
176
  {% if server.delimiter %}
136
177
  <div class="flex items-center gap-x-4">
137
- <div class="hidden sm:flex sm:flex-col">
138
- <dt class="text-sm font-medium text-gray-500">Delimiter</dt>
139
- <dd class="mt-1 text-sm text-gray-900">{{server.delimiter}}</dd>
178
+ <div class="sm:flex sm:flex-col">
179
+ <div class="flex flex-col">
180
+ <dt class="text-sm font-medium text-gray-500">Delimiter</dt>
181
+ <dd class="mt-1 text-sm text-gray-900">{{server.delimiter}}</dd>
182
+ </div>
183
+ </div>
184
+ </div>
185
+ {% endif %}
186
+
187
+ {% if server.description %}
188
+ <div class="flex items-center gap-x-4">
189
+ <div class="sm:flex sm:flex-col">
190
+ <div class="flex flex-col">
191
+ <dt class="text-sm font-medium text-gray-500">Description</dt>
192
+ <dd class="mt-1 text-sm text-gray-900">{{server.description}}</dd>
193
+ </div>
140
194
  </div>
141
195
  </div>
142
196
  {% endif %}
143
197
 
198
+ {% for key, value in server.model_extra.items() %}
199
+ <div class="flex items-center gap-x-4">
200
+ <div class="sm:flex sm:flex-col">
201
+ <div class="flex flex-col">
202
+ <dt class="text-sm font-medium text-gray-500">{{ key }}</dt>
203
+ <dd class="mt-1 text-sm text-gray-900">{{ value }}</dd>
204
+ </div>
205
+ </div>
206
+ </div>
207
+ {% endfor %}
208
+
144
209
  </li>
@@ -630,6 +630,11 @@ video {
630
630
  margin-right: auto;
631
631
  }
632
632
 
633
+ .my-2 {
634
+ margin-top: 0.5rem;
635
+ margin-bottom: 0.5rem;
636
+ }
637
+
633
638
  .-ml-0 {
634
639
  margin-left: -0px;
635
640
  }
@@ -642,6 +647,10 @@ video {
642
647
  margin-bottom: 0.75rem;
643
648
  }
644
649
 
650
+ .mb-6 {
651
+ margin-bottom: 1.5rem;
652
+ }
653
+
645
654
  .mr-1 {
646
655
  margin-right: 0.25rem;
647
656
  }
@@ -741,6 +750,10 @@ video {
741
750
  height: 1.5rem;
742
751
  }
743
752
 
753
+ .h-8 {
754
+ height: 2rem;
755
+ }
756
+
744
757
  .h-full {
745
758
  height: 100%;
746
759
  }
@@ -781,6 +794,10 @@ video {
781
794
  width: 58.333333%;
782
795
  }
783
796
 
797
+ .w-8 {
798
+ width: 2rem;
799
+ }
800
+
784
801
  .w-9\/12 {
785
802
  width: 75%;
786
803
  }
@@ -866,6 +883,11 @@ video {
866
883
  column-gap: 1rem;
867
884
  }
868
885
 
886
+ .gap-x-6 {
887
+ -moz-column-gap: 1.5rem;
888
+ column-gap: 1.5rem;
889
+ }
890
+
869
891
  .gap-y-6 {
870
892
  row-gap: 1.5rem;
871
893
  }
@@ -983,6 +1005,11 @@ video {
983
1005
  background-color: rgb(107 114 128 / var(--tw-bg-opacity));
984
1006
  }
985
1007
 
1008
+ .bg-indigo-100 {
1009
+ --tw-bg-opacity: 1;
1010
+ background-color: rgb(224 231 255 / var(--tw-bg-opacity));
1011
+ }
1012
+
986
1013
  .bg-indigo-600 {
987
1014
  --tw-bg-opacity: 1;
988
1015
  background-color: rgb(79 70 229 / var(--tw-bg-opacity));
@@ -1025,6 +1052,11 @@ video {
1025
1052
  padding-right: 0.5rem;
1026
1053
  }
1027
1054
 
1055
+ .px-2\.5 {
1056
+ padding-left: 0.625rem;
1057
+ padding-right: 0.625rem;
1058
+ }
1059
+
1028
1060
  .px-3 {
1029
1061
  padding-left: 0.75rem;
1030
1062
  padding-right: 0.75rem;
@@ -1040,6 +1072,16 @@ video {
1040
1072
  padding-right: 1.5rem;
1041
1073
  }
1042
1074
 
1075
+ .py-0 {
1076
+ padding-top: 0px;
1077
+ padding-bottom: 0px;
1078
+ }
1079
+
1080
+ .py-0\.5 {
1081
+ padding-top: 0.125rem;
1082
+ padding-bottom: 0.125rem;
1083
+ }
1084
+
1043
1085
  .py-1 {
1044
1086
  padding-top: 0.25rem;
1045
1087
  padding-bottom: 0.25rem;
@@ -1193,6 +1235,11 @@ video {
1193
1235
  color: rgb(75 85 99 / var(--tw-text-opacity));
1194
1236
  }
1195
1237
 
1238
+ .text-gray-800 {
1239
+ --tw-text-opacity: 1;
1240
+ color: rgb(31 41 55 / var(--tw-text-opacity));
1241
+ }
1242
+
1196
1243
  .text-gray-900 {
1197
1244
  --tw-text-opacity: 1;
1198
1245
  color: rgb(17 24 39 / var(--tw-text-opacity));
@@ -1399,6 +1446,10 @@ video {
1399
1446
  flex-direction: row;
1400
1447
  }
1401
1448
 
1449
+ .sm\:flex-col {
1450
+ flex-direction: column;
1451
+ }
1452
+
1402
1453
  .sm\:flex-wrap {
1403
1454
  flex-wrap: wrap;
1404
1455
  }
datacontract/web.py CHANGED
@@ -2,6 +2,7 @@ from typing import Annotated, Union, Optional
2
2
 
3
3
  import typer
4
4
  from fastapi import FastAPI, File
5
+ from fastapi.responses import HTMLResponse
5
6
 
6
7
  from datacontract.data_contract import DataContract, ExportFormat
7
8
  from fastapi.responses import PlainTextResponse
@@ -9,6 +10,22 @@ from fastapi.responses import PlainTextResponse
9
10
  app = FastAPI()
10
11
 
11
12
 
13
+ @app.get("/", response_class=HTMLResponse)
14
+ def index():
15
+ # TODO OpenAPI spec
16
+ return """
17
+ <html>
18
+ <body>
19
+ <h1>datacontract web server</h1>
20
+ <ul>
21
+ <li>POST /lint</li>
22
+ <li>POST /export</li>
23
+ </ul>
24
+ </body>
25
+ </html>
26
+ """
27
+
28
+
12
29
  @app.post("/lint")
13
30
  def lint(file: Annotated[bytes, File()], linters: Union[str, set[str]] = "all"):
14
31
  data_contract = DataContract(data_contract_str=str(file, encoding="utf-8"))