validio-sdk 7.4.0__tar.gz → 7.4.2__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.
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/PKG-INFO +1 -1
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/pyproject.toml +1 -1
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/_api/api.py +7 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/code/_import.py +10 -4
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/_diffable.py +53 -1
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/_resource.py +1 -1
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/_server_resources.py +23 -1
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/credentials.py +112 -12
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/tests/test_import.py +24 -3
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/LICENSE +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/README_PUBLIC.md +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/__init__.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/_api/__init__.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/client/__init__.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/client/client.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/code/__init__.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/code/_progress.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/code/apply.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/code/plan.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/code/scaffold.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/code/settings.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/config.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/dbt.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/exception.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/metadata.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/py.typed +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/__init__.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/_diff.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/_diff_util.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/_errors.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/_resource_graph.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/_serde.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/_update_namespace.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/_util.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/channels.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/enums.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/filters.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/notification_rules.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/replacement.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/segmentations.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/sources.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/tags.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/tests/__init__.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/tests/assets/example_manifest.json +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/tests/assets/expected_trimmed_manifest.json +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/tests/test__dbt.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/tests/test__diff.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/tests/test__plan.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/tests/test__resource.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/tests/test__sql_validation.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/thresholds.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/validators.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/windows.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/scalars.py +0 -0
- {validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/util.py +0 -0
|
@@ -3,7 +3,7 @@ name = "validio-sdk"
|
|
|
3
3
|
# This version does not represent the released version or any tag. For each
|
|
4
4
|
# release we automatically bump this before building and publishing so this
|
|
5
5
|
# should be kept at 0.0.1dev1
|
|
6
|
-
version = "7.4.
|
|
6
|
+
version = "7.4.2"
|
|
7
7
|
description = "SDK to interact with the Validio platform"
|
|
8
8
|
authors = ["Validio <support@validio.io>"]
|
|
9
9
|
license = "Apache-2.0"
|
|
@@ -1023,6 +1023,12 @@ async def get_credentials(
|
|
|
1023
1023
|
host
|
|
1024
1024
|
port
|
|
1025
1025
|
httpPath
|
|
1026
|
+
databricksAuth: auth {
|
|
1027
|
+
__typename
|
|
1028
|
+
... on DatabricksCredentialOAuth {
|
|
1029
|
+
clientId
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1026
1032
|
}
|
|
1027
1033
|
enableCatalog
|
|
1028
1034
|
}
|
|
@@ -1242,6 +1248,7 @@ async def get_credentials(
|
|
|
1242
1248
|
credential.get("config", {}),
|
|
1243
1249
|
[
|
|
1244
1250
|
("powerBiAuth", "auth"),
|
|
1251
|
+
("databricksAuth", "auth"),
|
|
1245
1252
|
("databaseRequired", "database"),
|
|
1246
1253
|
("optUser", "user"),
|
|
1247
1254
|
("optBaseUrl", "baseUrl"),
|
|
@@ -101,6 +101,7 @@ class ImportContext:
|
|
|
101
101
|
async def _import(
|
|
102
102
|
ctx: DiffContext,
|
|
103
103
|
tags_ctx: DiffContext,
|
|
104
|
+
include_schema: bool = False,
|
|
104
105
|
) -> str:
|
|
105
106
|
import_ctx = ImportContext()
|
|
106
107
|
|
|
@@ -189,16 +190,21 @@ async def _import(
|
|
|
189
190
|
def import_sources(cls: type, name: str, r: Resource) -> None:
|
|
190
191
|
credential = import_ctx.get_variable(Credential, cast(Any, r).credential_name)
|
|
191
192
|
|
|
193
|
+
inits: list[tuple[str, Any, str | None]] = [
|
|
194
|
+
("credential", credential, None),
|
|
195
|
+
("tags", resource_tags(r), None),
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
if include_schema and isinstance(r, Source):
|
|
199
|
+
inits.append(("jtd_schema", r.jtd_schema, None))
|
|
200
|
+
|
|
192
201
|
import_ctx.add_resource_decl(
|
|
193
202
|
cls,
|
|
194
203
|
name,
|
|
195
204
|
r._import_str(
|
|
196
205
|
indent_level=0,
|
|
197
206
|
import_ctx=import_ctx,
|
|
198
|
-
inits=
|
|
199
|
-
("credential", credential, None),
|
|
200
|
-
("tags", resource_tags(r), None),
|
|
201
|
-
],
|
|
207
|
+
inits=inits,
|
|
202
208
|
skip={"tag_names"},
|
|
203
209
|
),
|
|
204
210
|
)
|
|
@@ -23,6 +23,12 @@ could enter a cycle.
|
|
|
23
23
|
"""
|
|
24
24
|
MAX_RESOURCE_DEPTH = 15
|
|
25
25
|
|
|
26
|
+
"""
|
|
27
|
+
When we format dictionaries this is the limit of how deep we can go to build a
|
|
28
|
+
formatted output.
|
|
29
|
+
"""
|
|
30
|
+
MAX_FORMAT_DICT_DEPTH = 20
|
|
31
|
+
|
|
26
32
|
|
|
27
33
|
class Diffable(ABC):
|
|
28
34
|
"""
|
|
@@ -162,8 +168,13 @@ class Diffable(ABC):
|
|
|
162
168
|
import_args = []
|
|
163
169
|
|
|
164
170
|
for field, arg, comment in sorted_params:
|
|
171
|
+
if isinstance(arg, dict):
|
|
172
|
+
value = _format_dict_value(arg, indent_level + 1, 0)
|
|
173
|
+
else:
|
|
174
|
+
value = arg
|
|
175
|
+
|
|
165
176
|
comment_str = "" if not comment else f" # {comment}"
|
|
166
|
-
import_args.append(f"{field}={
|
|
177
|
+
import_args.append(f"{field}={value},{comment_str}")
|
|
167
178
|
|
|
168
179
|
params_str = line_indent.join(import_args)
|
|
169
180
|
closing_indent = " " * self._num_ident_spaces(indent_level)
|
|
@@ -175,6 +186,39 @@ class Diffable(ABC):
|
|
|
175
186
|
return 4 * indent_level
|
|
176
187
|
|
|
177
188
|
|
|
189
|
+
def _format_dict_value(value: Any, indent_level: int, recursion_depth: int) -> str:
|
|
190
|
+
"""
|
|
191
|
+
Format dictionary for import.
|
|
192
|
+
|
|
193
|
+
This is only a best effort to try to wrap dict values instead of having a
|
|
194
|
+
long line for e.g. jtd schemas on import.
|
|
195
|
+
"""
|
|
196
|
+
if recursion_depth >= MAX_FORMAT_DICT_DEPTH:
|
|
197
|
+
return value
|
|
198
|
+
|
|
199
|
+
indent = " " * (indent_level * 4)
|
|
200
|
+
if isinstance(value, dict):
|
|
201
|
+
if not value:
|
|
202
|
+
return "{}"
|
|
203
|
+
|
|
204
|
+
inner = indent + " " * 4
|
|
205
|
+
|
|
206
|
+
items = []
|
|
207
|
+
for k, v in value.items():
|
|
208
|
+
formatted = _format_dict_value(v, indent_level + 1, recursion_depth + 1)
|
|
209
|
+
items.append(f"{inner}'{k}': {formatted}")
|
|
210
|
+
|
|
211
|
+
return "{\n" + ",\n".join(items) + ",\n" + indent + "}"
|
|
212
|
+
|
|
213
|
+
if isinstance(value, bool):
|
|
214
|
+
return "True" if value else "False"
|
|
215
|
+
|
|
216
|
+
if value is None:
|
|
217
|
+
return "None"
|
|
218
|
+
|
|
219
|
+
return repr(value)
|
|
220
|
+
|
|
221
|
+
|
|
178
222
|
class ApiSecretChangeNestedResource(Diffable):
|
|
179
223
|
"""An interface for nested structure inside a list of secret fields."""
|
|
180
224
|
|
|
@@ -195,6 +239,11 @@ class ApiSecretChangeNestedResource(Diffable):
|
|
|
195
239
|
data[NODE_TYPE_FIELD_NAME] = self.__class__.__name__
|
|
196
240
|
return data
|
|
197
241
|
|
|
242
|
+
def _nested_objects(
|
|
243
|
+
self,
|
|
244
|
+
) -> dict[str, "Diffable | list[Diffable] | None"]:
|
|
245
|
+
return {}
|
|
246
|
+
|
|
198
247
|
@staticmethod
|
|
199
248
|
def _decode(
|
|
200
249
|
type_: type,
|
|
@@ -218,6 +267,9 @@ class ApiSecretChangeNestedResource(Diffable):
|
|
|
218
267
|
}
|
|
219
268
|
}
|
|
220
269
|
|
|
270
|
+
def _api_secret_change_input(self) -> dict[str, Any]:
|
|
271
|
+
return self._api_input()
|
|
272
|
+
|
|
221
273
|
def _api_secret_change_auth_query(self) -> str:
|
|
222
274
|
"""Returns the GraphQL query with fragments for the API secret change."""
|
|
223
275
|
fields = "\n".join([to_camel(f) for f in self._secret_fields()])
|
|
@@ -546,7 +546,7 @@ class Resource(Diffable):
|
|
|
546
546
|
|
|
547
547
|
def _api_secret_change_input(self) -> dict[str, Any]:
|
|
548
548
|
nested_objects = {
|
|
549
|
-
to_camel(f): obj.
|
|
549
|
+
to_camel(f): obj._api_secret_change_input()
|
|
550
550
|
for f, obj in self._nested_secret_objects().items()
|
|
551
551
|
}
|
|
552
552
|
|
|
@@ -50,6 +50,9 @@ from validio_sdk.resource.credentials import (
|
|
|
50
50
|
ClickHouseCredential,
|
|
51
51
|
Credential,
|
|
52
52
|
DatabricksCredential,
|
|
53
|
+
DatabricksCredentialAuth,
|
|
54
|
+
DatabricksCredentialOAuth,
|
|
55
|
+
DatabricksCredentialPersonalAccessToken,
|
|
53
56
|
DbtCloudCredential,
|
|
54
57
|
DbtCoreCredential,
|
|
55
58
|
DemoCredential,
|
|
@@ -326,12 +329,31 @@ async def load_credentials(
|
|
|
326
329
|
__internal__=g,
|
|
327
330
|
)
|
|
328
331
|
case "DatabricksCredential":
|
|
332
|
+
access_token = None
|
|
333
|
+
auth: DatabricksCredentialAuth | None = None
|
|
334
|
+
|
|
335
|
+
auth_type_config = c.get("config", {}).get("auth", {}) or {}
|
|
336
|
+
auth_type = auth_type_config.get("__typename")
|
|
337
|
+
|
|
338
|
+
if auth_type == "DatabricksCredentialPersonalAccessToken":
|
|
339
|
+
auth = DatabricksCredentialPersonalAccessToken(token="UNSET")
|
|
340
|
+
elif auth_type == "DatabricksCredentialOAuth":
|
|
341
|
+
auth = DatabricksCredentialOAuth(
|
|
342
|
+
client_id=c["config"]["auth"]["clientId"],
|
|
343
|
+
client_secret="UNSET",
|
|
344
|
+
)
|
|
345
|
+
elif auth_type is None:
|
|
346
|
+
access_token = "UNSET"
|
|
347
|
+
else:
|
|
348
|
+
raise ValidioBugError(f"unknown auth type '{auth_type}'")
|
|
349
|
+
|
|
329
350
|
credential = DatabricksCredential(
|
|
330
351
|
name=name,
|
|
331
352
|
host=c["config"]["host"],
|
|
332
353
|
port=c["config"]["port"],
|
|
333
|
-
access_token="UNSET",
|
|
334
354
|
http_path=c["config"]["httpPath"],
|
|
355
|
+
access_token=access_token,
|
|
356
|
+
auth=auth,
|
|
335
357
|
display_name=display_name,
|
|
336
358
|
enable_catalog=c["enableCatalog"],
|
|
337
359
|
__internal__=g,
|
|
@@ -8,6 +8,8 @@ from camel_converter import to_camel
|
|
|
8
8
|
|
|
9
9
|
from validio_sdk._api.api import APIClient, test_credential
|
|
10
10
|
from validio_sdk.client.client import Session
|
|
11
|
+
from validio_sdk.config import ValidioConfig
|
|
12
|
+
from validio_sdk.exception import ValidioError
|
|
11
13
|
from validio_sdk.resource._resource import (
|
|
12
14
|
ApiSecretChangeNestedResource,
|
|
13
15
|
Resource,
|
|
@@ -749,11 +751,6 @@ class SnowflakeCredentialKeyPair(ApiSecretChangeNestedResource):
|
|
|
749
751
|
def _secret_fields(self) -> set[str]:
|
|
750
752
|
return {"private_key", "private_key_passphrase"}
|
|
751
753
|
|
|
752
|
-
def _nested_objects(
|
|
753
|
-
self,
|
|
754
|
-
) -> dict[str, "Diffable | list[Diffable] | None"]:
|
|
755
|
-
return {}
|
|
756
|
-
|
|
757
754
|
|
|
758
755
|
class SnowflakeCredentialUserPassword(ApiSecretChangeNestedResource):
|
|
759
756
|
"""Snowflake password-based authentication."""
|
|
@@ -785,11 +782,6 @@ class SnowflakeCredentialUserPassword(ApiSecretChangeNestedResource):
|
|
|
785
782
|
def _secret_fields(self) -> set[str]:
|
|
786
783
|
return {"password"}
|
|
787
784
|
|
|
788
|
-
def _nested_objects(
|
|
789
|
-
self,
|
|
790
|
-
) -> dict[str, "Diffable | list[Diffable] | None"]:
|
|
791
|
-
return {}
|
|
792
|
-
|
|
793
785
|
|
|
794
786
|
SnowflakeCredentialAuth = Union[
|
|
795
787
|
SnowflakeCredentialKeyPair, SnowflakeCredentialUserPassword
|
|
@@ -1185,6 +1177,81 @@ class LookerCredential(Credential):
|
|
|
1185
1177
|
return {"client_secret"}
|
|
1186
1178
|
|
|
1187
1179
|
|
|
1180
|
+
class DatabricksCredentialPersonalAccessToken(ApiSecretChangeNestedResource):
|
|
1181
|
+
"""Databricks personal access token authentication."""
|
|
1182
|
+
|
|
1183
|
+
def __init__(
|
|
1184
|
+
self,
|
|
1185
|
+
*,
|
|
1186
|
+
token: str,
|
|
1187
|
+
):
|
|
1188
|
+
"""
|
|
1189
|
+
Constructor.
|
|
1190
|
+
|
|
1191
|
+
:param token: Databricks personal access token.
|
|
1192
|
+
"""
|
|
1193
|
+
self.token = token
|
|
1194
|
+
|
|
1195
|
+
def _api_variant_name(self) -> str:
|
|
1196
|
+
return "personalAccessToken"
|
|
1197
|
+
|
|
1198
|
+
def _immutable_fields(self) -> set[str]:
|
|
1199
|
+
return set({})
|
|
1200
|
+
|
|
1201
|
+
def _mutable_fields(self) -> set[str]:
|
|
1202
|
+
return set({})
|
|
1203
|
+
|
|
1204
|
+
def _secret_fields(self) -> set[str]:
|
|
1205
|
+
return {"token"}
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
class DatabricksCredentialOAuth(ApiSecretChangeNestedResource):
|
|
1209
|
+
"""Databricks OAuth token authentication."""
|
|
1210
|
+
|
|
1211
|
+
def __init__(
|
|
1212
|
+
self,
|
|
1213
|
+
*,
|
|
1214
|
+
client_id: str,
|
|
1215
|
+
client_secret: str,
|
|
1216
|
+
):
|
|
1217
|
+
"""
|
|
1218
|
+
Constructor.
|
|
1219
|
+
|
|
1220
|
+
:param client_id: Databricks OAuth client ID.
|
|
1221
|
+
:param client_secret: Databricks OAuth client secret.
|
|
1222
|
+
"""
|
|
1223
|
+
self.client_id = client_id
|
|
1224
|
+
self.client_secret = client_secret
|
|
1225
|
+
|
|
1226
|
+
def _api_variant_name(self) -> str:
|
|
1227
|
+
return "oauth"
|
|
1228
|
+
|
|
1229
|
+
def _immutable_fields(self) -> set[str]:
|
|
1230
|
+
return set({})
|
|
1231
|
+
|
|
1232
|
+
def _mutable_fields(self) -> set[str]:
|
|
1233
|
+
return {"client_id"}
|
|
1234
|
+
|
|
1235
|
+
def _secret_fields(self) -> set[str]:
|
|
1236
|
+
return {"client_secret"}
|
|
1237
|
+
|
|
1238
|
+
def _api_secret_change_input(self) -> dict[str, Any]:
|
|
1239
|
+
# We override this for Databricks since Databricks is the only one that
|
|
1240
|
+
# doesn't reuse the input type for creating credentials when checking if
|
|
1241
|
+
# secrets are changed. This mean we can use the API input as is, we need
|
|
1242
|
+
# to filter out non secrets.
|
|
1243
|
+
return {
|
|
1244
|
+
self._api_variant_name(): {
|
|
1245
|
+
to_camel(f): getattr(self, f) for f in self._secret_fields()
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
|
|
1250
|
+
DatabricksCredentialAuth = (
|
|
1251
|
+
DatabricksCredentialPersonalAccessToken | DatabricksCredentialOAuth
|
|
1252
|
+
)
|
|
1253
|
+
|
|
1254
|
+
|
|
1188
1255
|
class DatabricksCredential(Credential):
|
|
1189
1256
|
"""A credential resource that can be used to connect to a Databricks table."""
|
|
1190
1257
|
|
|
@@ -1194,8 +1261,9 @@ class DatabricksCredential(Credential):
|
|
|
1194
1261
|
name: str,
|
|
1195
1262
|
host: str,
|
|
1196
1263
|
port: int,
|
|
1197
|
-
access_token: str,
|
|
1198
1264
|
http_path: str,
|
|
1265
|
+
access_token: str | None = None,
|
|
1266
|
+
auth: DatabricksCredentialAuth | None = None,
|
|
1199
1267
|
enable_catalog: bool = False,
|
|
1200
1268
|
display_name: str | None = None,
|
|
1201
1269
|
ignore_changes: bool = False,
|
|
@@ -1207,8 +1275,9 @@ class DatabricksCredential(Credential):
|
|
|
1207
1275
|
:param name: Unique resource name assigned to the credential
|
|
1208
1276
|
:param host: A host of Databricks deployment
|
|
1209
1277
|
:param port: A port of Databricks deployment
|
|
1210
|
-
:param access_token: An access token of system principal or a user
|
|
1211
1278
|
:param http_path: Connection path of the compute resource to use.
|
|
1279
|
+
:param access_token: Deprecated.
|
|
1280
|
+
:param auth: Authentication method and config.
|
|
1212
1281
|
:param enable_catalog: If set to true, this credential will
|
|
1213
1282
|
be used to fetch catalog information.
|
|
1214
1283
|
:param display_name: Human-readable name for the credential. This name is
|
|
@@ -1221,11 +1290,22 @@ class DatabricksCredential(Credential):
|
|
|
1221
1290
|
ignore_changes=ignore_changes,
|
|
1222
1291
|
__internal__=__internal__,
|
|
1223
1292
|
)
|
|
1293
|
+
|
|
1294
|
+
if access_token and auth:
|
|
1295
|
+
raise ValidioError("only one of 'access_token' and 'auth' can be specified")
|
|
1296
|
+
|
|
1297
|
+
if not access_token and not auth:
|
|
1298
|
+
raise ValidioError("auth configuration missing")
|
|
1299
|
+
|
|
1300
|
+
if access_token:
|
|
1301
|
+
self.add_field_deprecation("access_token", "auth")
|
|
1302
|
+
|
|
1224
1303
|
self.host = host
|
|
1225
1304
|
self.port = port
|
|
1226
1305
|
self.access_token = access_token
|
|
1227
1306
|
self.http_path = http_path
|
|
1228
1307
|
self.enable_catalog = enable_catalog
|
|
1308
|
+
self.auth = auth
|
|
1229
1309
|
|
|
1230
1310
|
def _immutable_fields(self) -> set[str]:
|
|
1231
1311
|
return set({})
|
|
@@ -1237,8 +1317,28 @@ class DatabricksCredential(Credential):
|
|
|
1237
1317
|
}
|
|
1238
1318
|
|
|
1239
1319
|
def _secret_fields(self) -> set[str]:
|
|
1320
|
+
# We must always include access token even when it's not used to ensure
|
|
1321
|
+
# we can go from the legacy way of using this to the new auth config.
|
|
1322
|
+
# When we pass auth we must also pass `access_token` as `null` to clear
|
|
1323
|
+
# it.
|
|
1240
1324
|
return {"access_token"}
|
|
1241
1325
|
|
|
1326
|
+
def _nested_objects(
|
|
1327
|
+
self,
|
|
1328
|
+
) -> dict[str, "Diffable | list[Diffable] | None"]:
|
|
1329
|
+
return {"auth": self.auth}
|
|
1330
|
+
|
|
1331
|
+
def _api_update_input(self, namespace: str, ctx: "DiffContext") -> Any:
|
|
1332
|
+
# Nested objects are not included in the input if they are `None` but we
|
|
1333
|
+
# want to pass `auth` in all requests to ensure we can go from the new
|
|
1334
|
+
# config (auth being set) to the old (access_token being set).
|
|
1335
|
+
#
|
|
1336
|
+
# Once we've dropped the legacy support we can also drop this override.
|
|
1337
|
+
if self.auth is None:
|
|
1338
|
+
return _api_update_input_params(self, overrides={"auth": None})
|
|
1339
|
+
|
|
1340
|
+
return super()._api_update_input(namespace, ctx)
|
|
1341
|
+
|
|
1242
1342
|
|
|
1243
1343
|
class AzureSynapseCredential(Credential):
|
|
1244
1344
|
"""A base class of Azure Credential resource."""
|
|
@@ -165,7 +165,7 @@ notificationrule_0 = NotificationRule(
|
|
|
165
165
|
assert doc.strip() == expected.strip()
|
|
166
166
|
|
|
167
167
|
|
|
168
|
-
def
|
|
168
|
+
def test_import_sql_source_with_include_schema() -> None:
|
|
169
169
|
credential = PostgreSqlCredential(
|
|
170
170
|
name="postgres",
|
|
171
171
|
host="127.0.0.1",
|
|
@@ -188,7 +188,14 @@ def test_import_sql_source() -> None:
|
|
|
188
188
|
"nullable": False,
|
|
189
189
|
"optionalProperties": {},
|
|
190
190
|
"properties": {
|
|
191
|
-
"value": {
|
|
191
|
+
"value": {
|
|
192
|
+
"type": "int32",
|
|
193
|
+
"metadata": {
|
|
194
|
+
"json_path": "value",
|
|
195
|
+
"catalog_type": "NUMBER",
|
|
196
|
+
"sampled_field": False,
|
|
197
|
+
},
|
|
198
|
+
},
|
|
192
199
|
},
|
|
193
200
|
},
|
|
194
201
|
)
|
|
@@ -224,6 +231,20 @@ source_0 = SqlSource(
|
|
|
224
231
|
credential=credential_0,
|
|
225
232
|
description=None,
|
|
226
233
|
display_name='sql-source-postgres',
|
|
234
|
+
jtd_schema={
|
|
235
|
+
'nullable': False,
|
|
236
|
+
'optionalProperties': {},
|
|
237
|
+
'properties': {
|
|
238
|
+
'value': {
|
|
239
|
+
'type': 'int32',
|
|
240
|
+
'metadata': {
|
|
241
|
+
'json_path': 'value',
|
|
242
|
+
'catalog_type': 'NUMBER',
|
|
243
|
+
'sampled_field': False,
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
},
|
|
227
248
|
owner=None,
|
|
228
249
|
priority=None,
|
|
229
250
|
schedule='* * * * *',
|
|
@@ -240,7 +261,7 @@ source_0 = SqlSource(
|
|
|
240
261
|
sources={source.name: source},
|
|
241
262
|
)
|
|
242
263
|
|
|
243
|
-
doc = asyncio.run(_import(ctx, DiffContext()))
|
|
264
|
+
doc = asyncio.run(_import(ctx, DiffContext(), include_schema=True))
|
|
244
265
|
|
|
245
266
|
assert doc.strip() == expected.strip()
|
|
246
267
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{validio_sdk-7.4.0 → validio_sdk-7.4.2}/validio_sdk/resource/tests/assets/example_manifest.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|