validio-sdk 7.2.0__tar.gz → 7.3.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.2.0 → validio_sdk-7.3.1}/PKG-INFO +1 -1
  2. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/pyproject.toml +1 -1
  3. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/_api/api.py +29 -0
  4. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/_diffable.py +2 -2
  5. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/_server_resources.py +45 -0
  6. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/channels.py +3 -3
  7. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/credentials.py +227 -12
  8. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/sources.py +72 -0
  9. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/LICENSE +0 -0
  10. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/README_PUBLIC.md +0 -0
  11. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/__init__.py +0 -0
  12. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/_api/__init__.py +0 -0
  13. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/client/__init__.py +0 -0
  14. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/client/client.py +0 -0
  15. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/code/__init__.py +0 -0
  16. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/code/_import.py +0 -0
  17. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/code/_progress.py +0 -0
  18. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/code/apply.py +0 -0
  19. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/code/plan.py +0 -0
  20. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/code/scaffold.py +0 -0
  21. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/code/settings.py +0 -0
  22. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/config.py +0 -0
  23. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/dbt.py +0 -0
  24. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/exception.py +0 -0
  25. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/metadata.py +0 -0
  26. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/py.typed +0 -0
  27. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/__init__.py +0 -0
  28. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/_diff.py +0 -0
  29. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/_diff_util.py +0 -0
  30. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/_errors.py +0 -0
  31. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/_resource.py +0 -0
  32. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/_resource_graph.py +0 -0
  33. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/_serde.py +0 -0
  34. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/_update_namespace.py +0 -0
  35. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/_util.py +0 -0
  36. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/enums.py +0 -0
  37. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/filters.py +0 -0
  38. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/notification_rules.py +0 -0
  39. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/replacement.py +0 -0
  40. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/segmentations.py +0 -0
  41. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/tags.py +0 -0
  42. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/tests/__init__.py +0 -0
  43. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/tests/assets/example_manifest.json +0 -0
  44. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/tests/assets/expected_trimmed_manifest.json +0 -0
  45. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/tests/test__dbt.py +0 -0
  46. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/tests/test__diff.py +0 -0
  47. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/tests/test__plan.py +0 -0
  48. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/tests/test__resource.py +0 -0
  49. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/tests/test__sql_validation.py +0 -0
  50. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/tests/test_import.py +0 -0
  51. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/thresholds.py +0 -0
  52. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/validators.py +0 -0
  53. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/resource/windows.py +0 -0
  54. {validio_sdk-7.2.0 → validio_sdk-7.3.1}/validio_sdk/scalars.py +0 -0
  55. {validio_sdk-7.2.0 → validio_sdk-7.3.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.2.0
3
+ Version: 7.3.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.2.0"
6
+ version = "7.3.1"
7
7
  description = "SDK to interact with the Validio platform"
8
8
  authors = ["Validio <support@validio.io>"]
9
9
  license = "Apache-2.0"
@@ -553,6 +553,13 @@ async def get_sources(
553
553
  schedule
554
554
  }
555
555
  }
556
+ ... on TeradataSource {
557
+ config {
558
+ database
559
+ table
560
+ schedule
561
+ }
562
+ }
556
563
  }
557
564
  """
558
565
 
@@ -962,6 +969,12 @@ async def get_credentials(
962
969
  baseUrl
963
970
  }
964
971
  }
972
+ ... on AnthropicCredential {
973
+ config {
974
+ model
975
+ optBaseUrl: baseUrl
976
+ }
977
+ }
965
978
  ... on AwsCredential {
966
979
  config {
967
980
  accessKey
@@ -1166,6 +1179,21 @@ async def get_credentials(
1166
1179
  }
1167
1180
  enableCatalog
1168
1181
  }
1182
+ ... on TeradataCredential {
1183
+ config {
1184
+ host
1185
+ sslMode
1186
+ httpsPort
1187
+ tdmstPort
1188
+ auth {
1189
+ __typename
1190
+ ... on TeradataCredentialUserPassword {
1191
+ user
1192
+ }
1193
+ }
1194
+ }
1195
+ enableCatalog
1196
+ }
1169
1197
  }
1170
1198
  """
1171
1199
 
@@ -1214,6 +1242,7 @@ async def get_credentials(
1214
1242
  ("powerBiAuth", "auth"),
1215
1243
  ("databaseRequired", "database"),
1216
1244
  ("optUser", "user"),
1245
+ ("optBaseUrl", "baseUrl"),
1217
1246
  ],
1218
1247
  )
1219
1248
  result[i] = credential
@@ -1,7 +1,7 @@
1
1
  import inspect
2
2
  from abc import ABC, abstractmethod
3
3
  from collections.abc import Iterator
4
- from typing import TYPE_CHECKING, Any, Optional
4
+ from typing import TYPE_CHECKING, Any
5
5
 
6
6
  from camel_converter import to_camel
7
7
 
@@ -53,7 +53,7 @@ class Diffable(ABC):
53
53
  @abstractmethod
54
54
  def _nested_objects(
55
55
  self,
56
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
56
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
57
57
  """Returns any nested objects contained within this object.
58
58
 
59
59
  Nested objects will be diff-ed recursively.
@@ -38,6 +38,9 @@ from validio_sdk.resource.channels import (
38
38
  WebhookChannel,
39
39
  )
40
40
  from validio_sdk.resource.credentials import (
41
+ AnthropicCredential,
42
+ AnthropicCredentialApiKey,
43
+ AnthropicCredentialAuth,
41
44
  AtlanCredential,
42
45
  AwsAthenaCredential,
43
46
  AwsCredential,
@@ -74,6 +77,9 @@ from validio_sdk.resource.credentials import (
74
77
  SnowflakeCredentialUserPassword,
75
78
  TableauConnectedAppCredential,
76
79
  TableauPersonalAccessTokenCredential,
80
+ TeradataCredential,
81
+ TeradataCredentialAuth,
82
+ TeradataCredentialUserPassword,
77
83
  )
78
84
  from validio_sdk.resource.filters import Filter, SqlFilter
79
85
  from validio_sdk.resource.notification_rules import Conditions
@@ -205,6 +211,19 @@ async def load_credentials(
205
211
  display_name=display_name,
206
212
  __internal__=g,
207
213
  )
214
+ case "AnthropicCredential":
215
+ anthropic_auth: AnthropicCredentialAuth = AnthropicCredentialApiKey(
216
+ api_key="UNSET",
217
+ )
218
+
219
+ credential = AnthropicCredential(
220
+ name=name,
221
+ model=c["config"]["model"],
222
+ base_url=c["config"]["baseUrl"],
223
+ auth=anthropic_auth,
224
+ display_name=display_name,
225
+ __internal__=g,
226
+ )
208
227
  case "AtlanCredential":
209
228
  credential = AtlanCredential(
210
229
  name=name,
@@ -491,6 +510,32 @@ async def load_credentials(
491
510
  enable_catalog=c["enableCatalog"],
492
511
  __internal__=g,
493
512
  )
513
+ case "TeradataCredential":
514
+ auth_type = c["config"]["auth"]["__typename"]
515
+
516
+ if auth_type == "TeradataCredentialUserPassword":
517
+ teradata_auth: TeradataCredentialAuth = (
518
+ TeradataCredentialUserPassword(
519
+ user=c["config"]["auth"]["user"],
520
+ password="UNSET",
521
+ )
522
+ )
523
+ else:
524
+ raise ValidioBugError(
525
+ f"Unknown Teradata auth type on {name}: '{auth_type}'"
526
+ )
527
+
528
+ credential = TeradataCredential(
529
+ name=name,
530
+ host=c["config"]["host"],
531
+ auth=teradata_auth,
532
+ ssl_mode=c["config"]["sslMode"],
533
+ https_port=c["config"]["httpsPort"],
534
+ tdmst_port=c["config"]["tdmstPort"],
535
+ display_name=display_name,
536
+ enable_catalog=c["enableCatalog"],
537
+ __internal__=g,
538
+ )
494
539
  case _:
495
540
  raise ValidioError(
496
541
  f"unsupported credential '{name}' of type '{type(c)}'"
@@ -1,7 +1,7 @@
1
1
  """Notification Channels."""
2
2
 
3
3
  from enum import Enum
4
- from typing import TYPE_CHECKING, Any, Optional, Union, cast
4
+ from typing import TYPE_CHECKING, Any, Union, cast
5
5
 
6
6
  from camel_converter import to_camel
7
7
 
@@ -387,7 +387,7 @@ class EmailChannelAuthSmtpUserPassword(ApiSecretChangeNestedResource):
387
387
 
388
388
  def _nested_objects(
389
389
  self,
390
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
390
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
391
391
  return {}
392
392
 
393
393
 
@@ -456,5 +456,5 @@ class EmailChannel(Channel):
456
456
 
457
457
  def _nested_objects(
458
458
  self,
459
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
459
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
460
460
  return {"auth": self.auth}
@@ -21,6 +21,7 @@ from validio_sdk.resource._serde import (
21
21
  _api_update_input_params,
22
22
  _encode_resource,
23
23
  _import_resource_params,
24
+ _maybe_cast,
24
25
  decode_nested_objects,
25
26
  get_children_node,
26
27
  get_config_node,
@@ -48,6 +49,15 @@ class ClickHouseProtocol(str, Enum):
48
49
  NATIVE_TLS = "NATIVE_TLS"
49
50
 
50
51
 
52
+ class TeradataSSLMode(str, Enum):
53
+ """SSL encryption mode when connecting to Teradata."""
54
+
55
+ PREFER = "PREFER"
56
+ ALLOW = "ALLOW"
57
+ DISABLE = "DISABLE"
58
+ REQUIRE = "REQUIRE"
59
+
60
+
51
61
  class Credential(Resource):
52
62
  """
53
63
  Base class for a credential resource.
@@ -236,6 +246,100 @@ class Credential(Resource):
236
246
  return test_input
237
247
 
238
248
 
249
+ class AnthropicCredentialApiKey(ApiSecretChangeNestedResource):
250
+ """Anthropic credential using API key for authentication."""
251
+
252
+ def __init__(
253
+ self,
254
+ *,
255
+ api_key: str,
256
+ ):
257
+ """
258
+ Constructor.
259
+
260
+ :param api_key: API key to use for connecting to Anthropic.
261
+ """
262
+ self.api_key = api_key
263
+
264
+ def _api_variant_name(self) -> str:
265
+ return "apiKey"
266
+
267
+ def _immutable_fields(self) -> set[str]:
268
+ return set({})
269
+
270
+ def _mutable_fields(self) -> set[str]:
271
+ return set({})
272
+
273
+ def _secret_fields(self) -> set[str]:
274
+ return {"api_key"}
275
+
276
+ def _nested_objects(
277
+ self,
278
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
279
+ return {}
280
+
281
+
282
+ AnthropicCredentialAuth = Union[AnthropicCredentialApiKey]
283
+
284
+
285
+ class AnthropicCredential(Credential):
286
+ """Credential to connect to Anthropic."""
287
+
288
+ def __init__(
289
+ self,
290
+ *,
291
+ name: str,
292
+ model: str,
293
+ auth: AnthropicCredentialAuth,
294
+ base_url: str | None = None,
295
+ display_name: str | None = None,
296
+ ignore_changes: bool = False,
297
+ __internal__: ResourceGraph | None = None,
298
+ ):
299
+ """
300
+ Constructor.
301
+
302
+ :param name: Unique resource name assigned to the credential
303
+ :param model: Name of the model to use. E.g. claude-sonnet-4-5
304
+ :param auth: Auth method to use for connecting to Anthropic.
305
+ :param base_url: Base URL of Anthropic API. E.g. https://api.anthropic.com/v1.
306
+ If not provided, defaults to the standard Anthropic API endpoint.
307
+ :param display_name: Human-readable name for the credential. This name is
308
+ visible in the UI and does not need to be unique.
309
+ :param ignore_changes: If set to true, changes to the resource will be ignored.
310
+ """
311
+ super().__init__(
312
+ name=name,
313
+ display_name=display_name,
314
+ ignore_changes=ignore_changes,
315
+ __internal__=__internal__,
316
+ )
317
+
318
+ self.model = model
319
+ self.auth = auth
320
+ self.base_url = base_url
321
+
322
+ def _immutable_fields(self) -> set[str]:
323
+ return set({})
324
+
325
+ def _mutable_fields(self) -> set[str]:
326
+ return {
327
+ *super()._mutable_fields(),
328
+ *{
329
+ "model",
330
+ "base_url",
331
+ },
332
+ }
333
+
334
+ def _secret_fields(self) -> set[str]:
335
+ return set()
336
+
337
+ def _nested_objects(
338
+ self,
339
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
340
+ return {"auth": self.auth}
341
+
342
+
239
343
  class AtlanCredential(Credential):
240
344
  """(BETA) An Atlan credential resource."""
241
345
 
@@ -647,7 +751,7 @@ class SnowflakeCredentialKeyPair(ApiSecretChangeNestedResource):
647
751
 
648
752
  def _nested_objects(
649
753
  self,
650
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
754
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
651
755
  return {}
652
756
 
653
757
 
@@ -683,7 +787,7 @@ class SnowflakeCredentialUserPassword(ApiSecretChangeNestedResource):
683
787
 
684
788
  def _nested_objects(
685
789
  self,
686
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
790
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
687
791
  return {}
688
792
 
689
793
 
@@ -748,7 +852,7 @@ class SnowflakeCredential(Credential):
748
852
 
749
853
  def _nested_objects(
750
854
  self,
751
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
855
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
752
856
  return {"auth": self.auth}
753
857
 
754
858
 
@@ -1337,7 +1441,7 @@ class MsSqlServerCredentialUserPassword(ApiSecretChangeNestedResource):
1337
1441
 
1338
1442
  def _nested_objects(
1339
1443
  self,
1340
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1444
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
1341
1445
  return {}
1342
1446
 
1343
1447
 
@@ -1372,7 +1476,7 @@ class MsSqlServerCredentialEntraId(ApiSecretChangeNestedResource):
1372
1476
 
1373
1477
  def _nested_objects(
1374
1478
  self,
1375
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1479
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
1376
1480
  return {}
1377
1481
 
1378
1482
 
@@ -1442,7 +1546,7 @@ class MsSqlServerCredential(Credential):
1442
1546
 
1443
1547
  def _nested_objects(
1444
1548
  self,
1445
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1549
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
1446
1550
  return {"auth": self.auth}
1447
1551
 
1448
1552
 
@@ -1475,7 +1579,7 @@ class OmniCredentialApiKey(ApiSecretChangeNestedResource):
1475
1579
 
1476
1580
  def _nested_objects(
1477
1581
  self,
1478
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1582
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
1479
1583
  return {}
1480
1584
 
1481
1585
 
@@ -1536,7 +1640,7 @@ class OmniCredential(Credential):
1536
1640
 
1537
1641
  def _nested_objects(
1538
1642
  self,
1539
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1643
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
1540
1644
  return {"auth": self.auth}
1541
1645
 
1542
1646
 
@@ -1571,7 +1675,7 @@ class OracleCredentialUserPassword(ApiSecretChangeNestedResource):
1571
1675
 
1572
1676
  def _nested_objects(
1573
1677
  self,
1574
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1678
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
1575
1679
  return {}
1576
1680
 
1577
1681
 
@@ -1639,7 +1743,7 @@ class OracleCredential(Credential):
1639
1743
 
1640
1744
  def _nested_objects(
1641
1745
  self,
1642
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1746
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
1643
1747
  return {"auth": self.auth}
1644
1748
 
1645
1749
 
@@ -1871,7 +1975,7 @@ class MsPowerBiCredentialAuthEntraId(ApiSecretChangeNestedResource):
1871
1975
 
1872
1976
  def _nested_objects(
1873
1977
  self,
1874
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1978
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
1875
1979
  return {}
1876
1980
 
1877
1981
 
@@ -1922,7 +2026,7 @@ class MsPowerBiCredential(Credential):
1922
2026
 
1923
2027
  def _nested_objects(
1924
2028
  self,
1925
- ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
2029
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
1926
2030
  return {"auth": self.auth}
1927
2031
 
1928
2032
 
@@ -1978,6 +2082,115 @@ class SigmaCredential(Credential):
1978
2082
  return {"client_secret"}
1979
2083
 
1980
2084
 
2085
+ class TeradataCredentialUserPassword(ApiSecretChangeNestedResource):
2086
+ """Teradata credential via user-password auth."""
2087
+
2088
+ def __init__(
2089
+ self,
2090
+ user: str,
2091
+ password: str,
2092
+ ):
2093
+ """
2094
+ Constructor.
2095
+
2096
+ :param user: Username.
2097
+ :param password: Password.
2098
+ """
2099
+ self.user = user
2100
+ self.password = password
2101
+
2102
+ def _api_variant_name(self) -> str:
2103
+ return "userPassword"
2104
+
2105
+ def _immutable_fields(self) -> set[str]:
2106
+ return set({})
2107
+
2108
+ def _mutable_fields(self) -> set[str]:
2109
+ return {"user"}
2110
+
2111
+ def _secret_fields(self) -> set[str]:
2112
+ return {"password"}
2113
+
2114
+ def _nested_objects(
2115
+ self,
2116
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
2117
+ return {}
2118
+
2119
+
2120
+ TeradataCredentialAuth = Union[TeradataCredentialUserPassword]
2121
+
2122
+
2123
+ class TeradataCredential(Credential):
2124
+ """Credential to connect to a Teradata warehouse."""
2125
+
2126
+ def __init__(
2127
+ self,
2128
+ name: str,
2129
+ host: str,
2130
+ auth: TeradataCredentialAuth,
2131
+ ssl_mode: TeradataSSLMode,
2132
+ https_port: int | None = None,
2133
+ tdmst_port: int | None = None,
2134
+ enable_catalog: bool = False,
2135
+ display_name: str | None = None,
2136
+ ignore_changes: bool = False,
2137
+ __internal__: ResourceGraph | None = None,
2138
+ ):
2139
+ """
2140
+ Constructor.
2141
+
2142
+ :param name: Unique resource name assigned to the credential
2143
+ :param host: Host address of the server.
2144
+ :param auth: Credentials to use for authentication.
2145
+ :param ssl_mode: SSL encryption mode when connecting to Teradata.
2146
+ :param https_port: Port number to use to access the Teradata server
2147
+ via SSL connection (default 443).
2148
+ :param tdmst_port: Port number to use to access the Teradata server
2149
+ via non-SSL connection (default 1025).
2150
+ :param enable_catalog: If set to true, this credential will
2151
+ be used to fetch catalog information.
2152
+ :param display_name: Human-readable name for the credential. This name is
2153
+ visible in the UI and does not need to be unique.
2154
+ :param ignore_changes: If set to true, changes to the resource will be ignored.
2155
+ """
2156
+ super().__init__(
2157
+ name=name,
2158
+ display_name=display_name,
2159
+ ignore_changes=ignore_changes,
2160
+ __internal__=__internal__,
2161
+ )
2162
+
2163
+ self.host = host
2164
+ self.auth = auth
2165
+ self.ssl_mode = _maybe_cast(ssl_mode, TeradataSSLMode)
2166
+ self.https_port = https_port
2167
+ self.tdmst_port = tdmst_port
2168
+ self.enable_catalog = enable_catalog
2169
+
2170
+ def _immutable_fields(self) -> set[str]:
2171
+ return set({})
2172
+
2173
+ def _mutable_fields(self) -> set[str]:
2174
+ return {
2175
+ *super()._mutable_fields(),
2176
+ *{
2177
+ "host",
2178
+ "enable_catalog",
2179
+ "ssl_mode",
2180
+ "https_port",
2181
+ "tdmst_port",
2182
+ },
2183
+ }
2184
+
2185
+ def _secret_fields(self) -> set[str]:
2186
+ return set()
2187
+
2188
+ def _nested_objects(
2189
+ self,
2190
+ ) -> dict[str, "Diffable | list[Diffable] | None"]:
2191
+ return {"auth": self.auth}
2192
+
2193
+
1981
2194
  WarehouseCredential = Union[
1982
2195
  AzureSynapseCredential,
1983
2196
  AwsAthenaCredential,
@@ -1986,5 +2199,7 @@ WarehouseCredential = Union[
1986
2199
  DatabricksCredential,
1987
2200
  GcpCredential,
1988
2201
  PostgreSqlCredential,
2202
+ OracleCredential,
1989
2203
  SnowflakeCredential,
2204
+ TeradataCredential,
1990
2205
  ]
@@ -39,6 +39,7 @@ from validio_sdk.resource.credentials import (
39
39
  OracleCredential,
40
40
  PostgreSqlCredential,
41
41
  SnowflakeCredential,
42
+ TeradataCredential,
42
43
  WarehouseCredential,
43
44
  )
44
45
  from validio_sdk.resource.enums import IncidentGroupPriority
@@ -1444,6 +1445,77 @@ class OracleSource(Source):
1444
1445
  }
1445
1446
 
1446
1447
 
1448
+ class TeradataSource(Source):
1449
+ """A Teradata source configuration."""
1450
+
1451
+ def __init__(
1452
+ self,
1453
+ name: str,
1454
+ credential: TeradataCredential,
1455
+ database: str,
1456
+ table: str,
1457
+ schedule: str | None,
1458
+ display_name: str | None = None,
1459
+ owner: str | None = None,
1460
+ ignore_changes: bool = False,
1461
+ jtd_schema: JsonTypeDefinition | None = None,
1462
+ description: str | None = None,
1463
+ tags: list[Tag] | None = None,
1464
+ priority: IncidentGroupPriority | None = None,
1465
+ ):
1466
+ """
1467
+ Constructor.
1468
+
1469
+ :param database: Name of the database to connect to.
1470
+ :param table: Name of table to monitor.
1471
+ :param schedule: A 5-digit cron expression specifying how when the source
1472
+ polls for new data. Example: '0 0 * * *' to poll daily at midnight.
1473
+ :param display_name: Human-readable name for the source. This name is
1474
+ visible in the UI and does not need to be unique.
1475
+ :param owner: User email address of the source owner.
1476
+ :param ignore_changes: If set to true, changes to the resource will be ignored.
1477
+ :param description: Description of the resource.
1478
+ :param tags: Tags to add to the resource
1479
+ :param priority: Priority to assign to incidents created by this source.
1480
+ """
1481
+ super().__init__(
1482
+ name=name,
1483
+ credential=credential,
1484
+ display_name=display_name,
1485
+ owner=owner,
1486
+ ignore_changes=ignore_changes,
1487
+ jtd_schema=jtd_schema,
1488
+ description=description,
1489
+ tags=tags,
1490
+ priority=priority,
1491
+ )
1492
+
1493
+ self.database = database
1494
+ self.table = table
1495
+ self.schedule = schedule
1496
+
1497
+ def _immutable_fields(self) -> set[str]:
1498
+ return {
1499
+ *super()._immutable_fields(),
1500
+ *{
1501
+ "database",
1502
+ "table",
1503
+ },
1504
+ }
1505
+
1506
+ def _mutable_fields(self) -> set[str]:
1507
+ return {
1508
+ *super()._mutable_fields(),
1509
+ *{"schedule"},
1510
+ }
1511
+
1512
+ def _api_infer_schema_input(self) -> dict[str, object] | None:
1513
+ return {
1514
+ "database": self.database,
1515
+ "table": self.table,
1516
+ }
1517
+
1518
+
1447
1519
  # Streaming
1448
1520
 
1449
1521
 
File without changes