validio-sdk 7.4.0__tar.gz → 7.4.1__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 (55) hide show
  1. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/PKG-INFO +1 -1
  2. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/pyproject.toml +1 -1
  3. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/_api/api.py +7 -0
  4. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/_diffable.py +8 -0
  5. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/_resource.py +1 -1
  6. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/_server_resources.py +23 -1
  7. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/credentials.py +112 -12
  8. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/LICENSE +0 -0
  9. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/README_PUBLIC.md +0 -0
  10. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/__init__.py +0 -0
  11. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/_api/__init__.py +0 -0
  12. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/client/__init__.py +0 -0
  13. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/client/client.py +0 -0
  14. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/code/__init__.py +0 -0
  15. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/code/_import.py +0 -0
  16. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/code/_progress.py +0 -0
  17. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/code/apply.py +0 -0
  18. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/code/plan.py +0 -0
  19. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/code/scaffold.py +0 -0
  20. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/code/settings.py +0 -0
  21. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/config.py +0 -0
  22. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/dbt.py +0 -0
  23. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/exception.py +0 -0
  24. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/metadata.py +0 -0
  25. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/py.typed +0 -0
  26. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/__init__.py +0 -0
  27. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/_diff.py +0 -0
  28. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/_diff_util.py +0 -0
  29. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/_errors.py +0 -0
  30. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/_resource_graph.py +0 -0
  31. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/_serde.py +0 -0
  32. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/_update_namespace.py +0 -0
  33. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/_util.py +0 -0
  34. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/channels.py +0 -0
  35. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/enums.py +0 -0
  36. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/filters.py +0 -0
  37. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/notification_rules.py +0 -0
  38. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/replacement.py +0 -0
  39. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/segmentations.py +0 -0
  40. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/sources.py +0 -0
  41. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/tags.py +0 -0
  42. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/tests/__init__.py +0 -0
  43. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/tests/assets/example_manifest.json +0 -0
  44. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/tests/assets/expected_trimmed_manifest.json +0 -0
  45. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/tests/test__dbt.py +0 -0
  46. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/tests/test__diff.py +0 -0
  47. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/tests/test__plan.py +0 -0
  48. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/tests/test__resource.py +0 -0
  49. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/tests/test__sql_validation.py +0 -0
  50. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/tests/test_import.py +0 -0
  51. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/thresholds.py +0 -0
  52. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/validators.py +0 -0
  53. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/resource/windows.py +0 -0
  54. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/scalars.py +0 -0
  55. {validio_sdk-7.4.0 → validio_sdk-7.4.1}/validio_sdk/util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: validio-sdk
3
- Version: 7.4.0
3
+ Version: 7.4.1
4
4
  Summary: SDK to interact with the Validio platform
5
5
  Home-page: https://validio.io/
6
6
  License: Apache-2.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.0"
6
+ version = "7.4.1"
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"),
@@ -195,6 +195,11 @@ class ApiSecretChangeNestedResource(Diffable):
195
195
  data[NODE_TYPE_FIELD_NAME] = self.__class__.__name__
196
196
  return data
197
197
 
198
+ def _nested_objects(
199
+ self,
200
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
201
+ return {}
202
+
198
203
  @staticmethod
199
204
  def _decode(
200
205
  type_: type,
@@ -218,6 +223,9 @@ class ApiSecretChangeNestedResource(Diffable):
218
223
  }
219
224
  }
220
225
 
226
+ def _api_secret_change_input(self) -> dict[str, Any]:
227
+ return self._api_input()
228
+
221
229
  def _api_secret_change_auth_query(self) -> str:
222
230
  """Returns the GraphQL query with fragments for the API secret change."""
223
231
  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._api_input()
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."""
File without changes