databricks-sdk 0.27.1__py3-none-any.whl → 0.29.0__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 databricks-sdk might be problematic. Click here for more details.

Files changed (32) hide show
  1. databricks/sdk/__init__.py +16 -12
  2. databricks/sdk/azure.py +0 -27
  3. databricks/sdk/config.py +71 -19
  4. databricks/sdk/core.py +27 -0
  5. databricks/sdk/credentials_provider.py +121 -44
  6. databricks/sdk/dbutils.py +81 -3
  7. databricks/sdk/environments.py +34 -1
  8. databricks/sdk/errors/__init__.py +1 -0
  9. databricks/sdk/errors/mapper.py +4 -0
  10. databricks/sdk/errors/private_link.py +60 -0
  11. databricks/sdk/oauth.py +8 -6
  12. databricks/sdk/service/catalog.py +774 -632
  13. databricks/sdk/service/compute.py +91 -116
  14. databricks/sdk/service/dashboards.py +707 -2
  15. databricks/sdk/service/jobs.py +126 -163
  16. databricks/sdk/service/marketplace.py +145 -31
  17. databricks/sdk/service/oauth2.py +22 -0
  18. databricks/sdk/service/pipelines.py +119 -4
  19. databricks/sdk/service/serving.py +217 -64
  20. databricks/sdk/service/settings.py +1 -0
  21. databricks/sdk/service/sharing.py +36 -2
  22. databricks/sdk/service/sql.py +103 -24
  23. databricks/sdk/service/vectorsearch.py +263 -1
  24. databricks/sdk/service/workspace.py +8 -4
  25. databricks/sdk/version.py +1 -1
  26. {databricks_sdk-0.27.1.dist-info → databricks_sdk-0.29.0.dist-info}/METADATA +2 -1
  27. databricks_sdk-0.29.0.dist-info/RECORD +57 -0
  28. databricks_sdk-0.27.1.dist-info/RECORD +0 -56
  29. {databricks_sdk-0.27.1.dist-info → databricks_sdk-0.29.0.dist-info}/LICENSE +0 -0
  30. {databricks_sdk-0.27.1.dist-info → databricks_sdk-0.29.0.dist-info}/NOTICE +0 -0
  31. {databricks_sdk-0.27.1.dist-info → databricks_sdk-0.29.0.dist-info}/WHEEL +0 -0
  32. {databricks_sdk-0.27.1.dist-info → databricks_sdk-0.29.0.dist-info}/top_level.txt +0 -0
@@ -59,6 +59,38 @@ class AssetType(Enum):
59
59
  ASSET_TYPE_UNSPECIFIED = 'ASSET_TYPE_UNSPECIFIED'
60
60
 
61
61
 
62
+ @dataclass
63
+ class BatchGetListingsResponse:
64
+ listings: Optional[List[Listing]] = None
65
+
66
+ def as_dict(self) -> dict:
67
+ """Serializes the BatchGetListingsResponse into a dictionary suitable for use as a JSON request body."""
68
+ body = {}
69
+ if self.listings: body['listings'] = [v.as_dict() for v in self.listings]
70
+ return body
71
+
72
+ @classmethod
73
+ def from_dict(cls, d: Dict[str, any]) -> BatchGetListingsResponse:
74
+ """Deserializes the BatchGetListingsResponse from a dictionary."""
75
+ return cls(listings=_repeated_dict(d, 'listings', Listing))
76
+
77
+
78
+ @dataclass
79
+ class BatchGetProvidersResponse:
80
+ providers: Optional[List[ProviderInfo]] = None
81
+
82
+ def as_dict(self) -> dict:
83
+ """Serializes the BatchGetProvidersResponse into a dictionary suitable for use as a JSON request body."""
84
+ body = {}
85
+ if self.providers: body['providers'] = [v.as_dict() for v in self.providers]
86
+ return body
87
+
88
+ @classmethod
89
+ def from_dict(cls, d: Dict[str, any]) -> BatchGetProvidersResponse:
90
+ """Deserializes the BatchGetProvidersResponse from a dictionary."""
91
+ return cls(providers=_repeated_dict(d, 'providers', ProviderInfo))
92
+
93
+
62
94
  class Category(Enum):
63
95
 
64
96
  ADVERTISING_AND_MARKETING = 'ADVERTISING_AND_MARKETING'
@@ -1265,11 +1297,16 @@ class Listing:
1265
1297
 
1266
1298
  id: Optional[str] = None
1267
1299
 
1300
+ provider_summary: Optional[ProviderListingSummaryInfo] = None
1301
+ """we can not use just ProviderListingSummary since we already have same name on entity side of the
1302
+ state"""
1303
+
1268
1304
  def as_dict(self) -> dict:
1269
1305
  """Serializes the Listing into a dictionary suitable for use as a JSON request body."""
1270
1306
  body = {}
1271
1307
  if self.detail: body['detail'] = self.detail.as_dict()
1272
1308
  if self.id is not None: body['id'] = self.id
1309
+ if self.provider_summary: body['provider_summary'] = self.provider_summary.as_dict()
1273
1310
  if self.summary: body['summary'] = self.summary.as_dict()
1274
1311
  return body
1275
1312
 
@@ -1278,6 +1315,7 @@ class Listing:
1278
1315
  """Deserializes the Listing from a dictionary."""
1279
1316
  return cls(detail=_from_dict(d, 'detail', ListingDetail),
1280
1317
  id=d.get('id', None),
1318
+ provider_summary=_from_dict(d, 'provider_summary', ProviderListingSummaryInfo),
1281
1319
  summary=_from_dict(d, 'summary', ListingSummary))
1282
1320
 
1283
1321
 
@@ -1695,6 +1733,37 @@ class ProviderAnalyticsDashboard:
1695
1733
  return cls(id=d.get('id', None))
1696
1734
 
1697
1735
 
1736
+ @dataclass
1737
+ class ProviderIconFile:
1738
+ icon_file_id: Optional[str] = None
1739
+
1740
+ icon_file_path: Optional[str] = None
1741
+
1742
+ icon_type: Optional[ProviderIconType] = None
1743
+
1744
+ def as_dict(self) -> dict:
1745
+ """Serializes the ProviderIconFile into a dictionary suitable for use as a JSON request body."""
1746
+ body = {}
1747
+ if self.icon_file_id is not None: body['icon_file_id'] = self.icon_file_id
1748
+ if self.icon_file_path is not None: body['icon_file_path'] = self.icon_file_path
1749
+ if self.icon_type is not None: body['icon_type'] = self.icon_type.value
1750
+ return body
1751
+
1752
+ @classmethod
1753
+ def from_dict(cls, d: Dict[str, any]) -> ProviderIconFile:
1754
+ """Deserializes the ProviderIconFile from a dictionary."""
1755
+ return cls(icon_file_id=d.get('icon_file_id', None),
1756
+ icon_file_path=d.get('icon_file_path', None),
1757
+ icon_type=_enum(d, 'icon_type', ProviderIconType))
1758
+
1759
+
1760
+ class ProviderIconType(Enum):
1761
+
1762
+ DARK = 'DARK'
1763
+ PRIMARY = 'PRIMARY'
1764
+ PROVIDER_ICON_TYPE_UNSPECIFIED = 'PROVIDER_ICON_TYPE_UNSPECIFIED'
1765
+
1766
+
1698
1767
  @dataclass
1699
1768
  class ProviderInfo:
1700
1769
  name: str
@@ -1768,6 +1837,33 @@ class ProviderInfo:
1768
1837
  term_of_service_link=d.get('term_of_service_link', None))
1769
1838
 
1770
1839
 
1840
+ @dataclass
1841
+ class ProviderListingSummaryInfo:
1842
+ """we can not use just ProviderListingSummary since we already have same name on entity side of the
1843
+ state"""
1844
+
1845
+ description: Optional[str] = None
1846
+
1847
+ icon_files: Optional[List[ProviderIconFile]] = None
1848
+
1849
+ name: Optional[str] = None
1850
+
1851
+ def as_dict(self) -> dict:
1852
+ """Serializes the ProviderListingSummaryInfo into a dictionary suitable for use as a JSON request body."""
1853
+ body = {}
1854
+ if self.description is not None: body['description'] = self.description
1855
+ if self.icon_files: body['icon_files'] = [v.as_dict() for v in self.icon_files]
1856
+ if self.name is not None: body['name'] = self.name
1857
+ return body
1858
+
1859
+ @classmethod
1860
+ def from_dict(cls, d: Dict[str, any]) -> ProviderListingSummaryInfo:
1861
+ """Deserializes the ProviderListingSummaryInfo from a dictionary."""
1862
+ return cls(description=d.get('description', None),
1863
+ icon_files=_repeated_dict(d, 'icon_files', ProviderIconFile),
1864
+ name=d.get('name', None))
1865
+
1866
+
1771
1867
  @dataclass
1772
1868
  class RegionInfo:
1773
1869
  cloud: Optional[str] = None
@@ -1908,34 +2004,6 @@ class SortBy(Enum):
1908
2004
  SORT_BY_UNSPECIFIED = 'SORT_BY_UNSPECIFIED'
1909
2005
 
1910
2006
 
1911
- @dataclass
1912
- class SortBySpec:
1913
- sort_by: SortBy
1914
- """The field on which to sort the listing."""
1915
-
1916
- sort_order: SortOrder
1917
- """The order in which to sort the listing."""
1918
-
1919
- def as_dict(self) -> dict:
1920
- """Serializes the SortBySpec into a dictionary suitable for use as a JSON request body."""
1921
- body = {}
1922
- if self.sort_by is not None: body['sort_by'] = self.sort_by.value
1923
- if self.sort_order is not None: body['sort_order'] = self.sort_order.value
1924
- return body
1925
-
1926
- @classmethod
1927
- def from_dict(cls, d: Dict[str, any]) -> SortBySpec:
1928
- """Deserializes the SortBySpec from a dictionary."""
1929
- return cls(sort_by=_enum(d, 'sort_by', SortBy), sort_order=_enum(d, 'sort_order', SortOrder))
1930
-
1931
-
1932
- class SortOrder(Enum):
1933
-
1934
- SORT_ORDER_ASCENDING = 'SORT_ORDER_ASCENDING'
1935
- SORT_ORDER_DESCENDING = 'SORT_ORDER_DESCENDING'
1936
- SORT_ORDER_UNSPECIFIED = 'SORT_ORDER_UNSPECIFIED'
1937
-
1938
-
1939
2007
  @dataclass
1940
2008
  class TokenDetail:
1941
2009
  bearer_token: Optional[str] = None
@@ -2560,6 +2628,26 @@ class ConsumerListingsAPI:
2560
2628
  def __init__(self, api_client):
2561
2629
  self._api = api_client
2562
2630
 
2631
+ def batch_get(self, *, ids: Optional[List[str]] = None) -> BatchGetListingsResponse:
2632
+ """Get one batch of listings. One may specify up to 50 IDs per request.
2633
+
2634
+ Batch get a published listing in the Databricks Marketplace that the consumer has access to.
2635
+
2636
+ :param ids: List[str] (optional)
2637
+
2638
+ :returns: :class:`BatchGetListingsResponse`
2639
+ """
2640
+
2641
+ query = {}
2642
+ if ids is not None: query['ids'] = [v for v in ids]
2643
+ headers = {'Accept': 'application/json', }
2644
+
2645
+ res = self._api.do('GET',
2646
+ '/api/2.1/marketplace-consumer/listings:batchGet',
2647
+ query=query,
2648
+ headers=headers)
2649
+ return BatchGetListingsResponse.from_dict(res)
2650
+
2563
2651
  def get(self, id: str) -> GetListingResponse:
2564
2652
  """Get listing.
2565
2653
 
@@ -2579,13 +2667,14 @@ class ConsumerListingsAPI:
2579
2667
  *,
2580
2668
  assets: Optional[List[AssetType]] = None,
2581
2669
  categories: Optional[List[Category]] = None,
2670
+ is_ascending: Optional[bool] = None,
2582
2671
  is_free: Optional[bool] = None,
2583
2672
  is_private_exchange: Optional[bool] = None,
2584
2673
  is_staff_pick: Optional[bool] = None,
2585
2674
  page_size: Optional[int] = None,
2586
2675
  page_token: Optional[str] = None,
2587
2676
  provider_ids: Optional[List[str]] = None,
2588
- sort_by_spec: Optional[SortBySpec] = None,
2677
+ sort_by: Optional[SortBy] = None,
2589
2678
  tags: Optional[List[ListingTag]] = None) -> Iterator[Listing]:
2590
2679
  """List listings.
2591
2680
 
@@ -2595,6 +2684,7 @@ class ConsumerListingsAPI:
2595
2684
  Matches any of the following asset types
2596
2685
  :param categories: List[:class:`Category`] (optional)
2597
2686
  Matches any of the following categories
2687
+ :param is_ascending: bool (optional)
2598
2688
  :param is_free: bool (optional)
2599
2689
  Filters each listing based on if it is free.
2600
2690
  :param is_private_exchange: bool (optional)
@@ -2605,7 +2695,7 @@ class ConsumerListingsAPI:
2605
2695
  :param page_token: str (optional)
2606
2696
  :param provider_ids: List[str] (optional)
2607
2697
  Matches any of the following provider ids
2608
- :param sort_by_spec: :class:`SortBySpec` (optional)
2698
+ :param sort_by: :class:`SortBy` (optional)
2609
2699
  Criteria for sorting the resulting set of listings.
2610
2700
  :param tags: List[:class:`ListingTag`] (optional)
2611
2701
  Matches any of the following tags
@@ -2616,13 +2706,14 @@ class ConsumerListingsAPI:
2616
2706
  query = {}
2617
2707
  if assets is not None: query['assets'] = [v.value for v in assets]
2618
2708
  if categories is not None: query['categories'] = [v.value for v in categories]
2709
+ if is_ascending is not None: query['is_ascending'] = is_ascending
2619
2710
  if is_free is not None: query['is_free'] = is_free
2620
2711
  if is_private_exchange is not None: query['is_private_exchange'] = is_private_exchange
2621
2712
  if is_staff_pick is not None: query['is_staff_pick'] = is_staff_pick
2622
2713
  if page_size is not None: query['page_size'] = page_size
2623
2714
  if page_token is not None: query['page_token'] = page_token
2624
2715
  if provider_ids is not None: query['provider_ids'] = [v for v in provider_ids]
2625
- if sort_by_spec is not None: query['sort_by_spec'] = sort_by_spec.as_dict()
2716
+ if sort_by is not None: query['sort_by'] = sort_by.value
2626
2717
  if tags is not None: query['tags'] = [v.as_dict() for v in tags]
2627
2718
  headers = {'Accept': 'application/json', }
2628
2719
 
@@ -2640,6 +2731,7 @@ class ConsumerListingsAPI:
2640
2731
  *,
2641
2732
  assets: Optional[List[AssetType]] = None,
2642
2733
  categories: Optional[List[Category]] = None,
2734
+ is_ascending: Optional[bool] = None,
2643
2735
  is_free: Optional[bool] = None,
2644
2736
  is_private_exchange: Optional[bool] = None,
2645
2737
  page_size: Optional[int] = None,
@@ -2657,6 +2749,7 @@ class ConsumerListingsAPI:
2657
2749
  Matches any of the following asset types
2658
2750
  :param categories: List[:class:`Category`] (optional)
2659
2751
  Matches any of the following categories
2752
+ :param is_ascending: bool (optional)
2660
2753
  :param is_free: bool (optional)
2661
2754
  :param is_private_exchange: bool (optional)
2662
2755
  :param page_size: int (optional)
@@ -2671,6 +2764,7 @@ class ConsumerListingsAPI:
2671
2764
  query = {}
2672
2765
  if assets is not None: query['assets'] = [v.value for v in assets]
2673
2766
  if categories is not None: query['categories'] = [v.value for v in categories]
2767
+ if is_ascending is not None: query['is_ascending'] = is_ascending
2674
2768
  if is_free is not None: query['is_free'] = is_free
2675
2769
  if is_private_exchange is not None: query['is_private_exchange'] = is_private_exchange
2676
2770
  if page_size is not None: query['page_size'] = page_size
@@ -2802,6 +2896,26 @@ class ConsumerProvidersAPI:
2802
2896
  def __init__(self, api_client):
2803
2897
  self._api = api_client
2804
2898
 
2899
+ def batch_get(self, *, ids: Optional[List[str]] = None) -> BatchGetProvidersResponse:
2900
+ """Get one batch of providers. One may specify up to 50 IDs per request.
2901
+
2902
+ Batch get a provider in the Databricks Marketplace with at least one visible listing.
2903
+
2904
+ :param ids: List[str] (optional)
2905
+
2906
+ :returns: :class:`BatchGetProvidersResponse`
2907
+ """
2908
+
2909
+ query = {}
2910
+ if ids is not None: query['ids'] = [v for v in ids]
2911
+ headers = {'Accept': 'application/json', }
2912
+
2913
+ res = self._api.do('GET',
2914
+ '/api/2.1/marketplace-consumer/providers:batchGet',
2915
+ query=query,
2916
+ headers=headers)
2917
+ return BatchGetProvidersResponse.from_dict(res)
2918
+
2805
2919
  def get(self, id: str) -> GetProviderResponse:
2806
2920
  """Get a provider.
2807
2921
 
@@ -160,6 +160,28 @@ class CreateServicePrincipalSecretResponse:
160
160
  update_time=d.get('update_time', None))
161
161
 
162
162
 
163
+ @dataclass
164
+ class DataPlaneInfo:
165
+ authorization_details: Optional[str] = None
166
+ """Authorization details as a string."""
167
+
168
+ endpoint_url: Optional[str] = None
169
+ """The URL of the endpoint for this operation in the dataplane."""
170
+
171
+ def as_dict(self) -> dict:
172
+ """Serializes the DataPlaneInfo into a dictionary suitable for use as a JSON request body."""
173
+ body = {}
174
+ if self.authorization_details is not None: body['authorization_details'] = self.authorization_details
175
+ if self.endpoint_url is not None: body['endpoint_url'] = self.endpoint_url
176
+ return body
177
+
178
+ @classmethod
179
+ def from_dict(cls, d: Dict[str, any]) -> DataPlaneInfo:
180
+ """Deserializes the DataPlaneInfo from a dictionary."""
181
+ return cls(authorization_details=d.get('authorization_details', None),
182
+ endpoint_url=d.get('endpoint_url', None))
183
+
184
+
163
185
  @dataclass
164
186
  class DeleteCustomAppIntegrationOutput:
165
187
 
@@ -57,6 +57,9 @@ class CreatePipeline:
57
57
  filters: Optional[Filters] = None
58
58
  """Filters on which Pipeline packages to include in the deployed graph."""
59
59
 
60
+ gateway_definition: Optional[IngestionGatewayPipelineDefinition] = None
61
+ """The definition of a gateway pipeline to support CDC."""
62
+
60
63
  id: Optional[str] = None
61
64
  """Unique identifier for this pipeline."""
62
65
 
@@ -104,6 +107,7 @@ class CreatePipeline:
104
107
  if self.dry_run is not None: body['dry_run'] = self.dry_run
105
108
  if self.edition is not None: body['edition'] = self.edition
106
109
  if self.filters: body['filters'] = self.filters.as_dict()
110
+ if self.gateway_definition: body['gateway_definition'] = self.gateway_definition.as_dict()
107
111
  if self.id is not None: body['id'] = self.id
108
112
  if self.ingestion_definition: body['ingestion_definition'] = self.ingestion_definition.as_dict()
109
113
  if self.libraries: body['libraries'] = [v.as_dict() for v in self.libraries]
@@ -130,6 +134,7 @@ class CreatePipeline:
130
134
  dry_run=d.get('dry_run', None),
131
135
  edition=d.get('edition', None),
132
136
  filters=_from_dict(d, 'filters', Filters),
137
+ gateway_definition=_from_dict(d, 'gateway_definition', IngestionGatewayPipelineDefinition),
133
138
  id=d.get('id', None),
134
139
  ingestion_definition=_from_dict(d, 'ingestion_definition',
135
140
  ManagedIngestionPipelineDefinition),
@@ -266,6 +271,9 @@ class EditPipeline:
266
271
  filters: Optional[Filters] = None
267
272
  """Filters on which Pipeline packages to include in the deployed graph."""
268
273
 
274
+ gateway_definition: Optional[IngestionGatewayPipelineDefinition] = None
275
+ """The definition of a gateway pipeline to support CDC."""
276
+
269
277
  id: Optional[str] = None
270
278
  """Unique identifier for this pipeline."""
271
279
 
@@ -317,6 +325,7 @@ class EditPipeline:
317
325
  if self.expected_last_modified is not None:
318
326
  body['expected_last_modified'] = self.expected_last_modified
319
327
  if self.filters: body['filters'] = self.filters.as_dict()
328
+ if self.gateway_definition: body['gateway_definition'] = self.gateway_definition.as_dict()
320
329
  if self.id is not None: body['id'] = self.id
321
330
  if self.ingestion_definition: body['ingestion_definition'] = self.ingestion_definition.as_dict()
322
331
  if self.libraries: body['libraries'] = [v.as_dict() for v in self.libraries]
@@ -344,6 +353,7 @@ class EditPipeline:
344
353
  edition=d.get('edition', None),
345
354
  expected_last_modified=d.get('expected_last_modified', None),
346
355
  filters=_from_dict(d, 'filters', Filters),
356
+ gateway_definition=_from_dict(d, 'gateway_definition', IngestionGatewayPipelineDefinition),
347
357
  id=d.get('id', None),
348
358
  ingestion_definition=_from_dict(d, 'ingestion_definition',
349
359
  ManagedIngestionPipelineDefinition),
@@ -570,6 +580,43 @@ class IngestionConfig:
570
580
  return cls(schema=_from_dict(d, 'schema', SchemaSpec), table=_from_dict(d, 'table', TableSpec))
571
581
 
572
582
 
583
+ @dataclass
584
+ class IngestionGatewayPipelineDefinition:
585
+ connection_id: Optional[str] = None
586
+ """Immutable. The Unity Catalog connection this gateway pipeline uses to communicate with the
587
+ source."""
588
+
589
+ gateway_storage_catalog: Optional[str] = None
590
+ """Required, Immutable. The name of the catalog for the gateway pipeline's storage location."""
591
+
592
+ gateway_storage_name: Optional[str] = None
593
+ """Required. The Unity Catalog-compatible naming for the gateway storage location. This is the
594
+ destination to use for the data that is extracted by the gateway. Delta Live Tables system will
595
+ automatically create the storage location under the catalog and schema."""
596
+
597
+ gateway_storage_schema: Optional[str] = None
598
+ """Required, Immutable. The name of the schema for the gateway pipelines's storage location."""
599
+
600
+ def as_dict(self) -> dict:
601
+ """Serializes the IngestionGatewayPipelineDefinition into a dictionary suitable for use as a JSON request body."""
602
+ body = {}
603
+ if self.connection_id is not None: body['connection_id'] = self.connection_id
604
+ if self.gateway_storage_catalog is not None:
605
+ body['gateway_storage_catalog'] = self.gateway_storage_catalog
606
+ if self.gateway_storage_name is not None: body['gateway_storage_name'] = self.gateway_storage_name
607
+ if self.gateway_storage_schema is not None:
608
+ body['gateway_storage_schema'] = self.gateway_storage_schema
609
+ return body
610
+
611
+ @classmethod
612
+ def from_dict(cls, d: Dict[str, any]) -> IngestionGatewayPipelineDefinition:
613
+ """Deserializes the IngestionGatewayPipelineDefinition from a dictionary."""
614
+ return cls(connection_id=d.get('connection_id', None),
615
+ gateway_storage_catalog=d.get('gateway_storage_catalog', None),
616
+ gateway_storage_name=d.get('gateway_storage_name', None),
617
+ gateway_storage_schema=d.get('gateway_storage_schema', None))
618
+
619
+
573
620
  @dataclass
574
621
  class ListPipelineEventsResponse:
575
622
  events: Optional[List[PipelineEvent]] = None
@@ -659,12 +706,17 @@ class ManagedIngestionPipelineDefinition:
659
706
  objects: Optional[List[IngestionConfig]] = None
660
707
  """Required. Settings specifying tables to replicate and the destination for the replicated tables."""
661
708
 
709
+ table_configuration: Optional[TableSpecificConfig] = None
710
+ """Configuration settings to control the ingestion of tables. These settings are applied to all
711
+ tables in the pipeline."""
712
+
662
713
  def as_dict(self) -> dict:
663
714
  """Serializes the ManagedIngestionPipelineDefinition into a dictionary suitable for use as a JSON request body."""
664
715
  body = {}
665
716
  if self.connection_name is not None: body['connection_name'] = self.connection_name
666
717
  if self.ingestion_gateway_id is not None: body['ingestion_gateway_id'] = self.ingestion_gateway_id
667
718
  if self.objects: body['objects'] = [v.as_dict() for v in self.objects]
719
+ if self.table_configuration: body['table_configuration'] = self.table_configuration.as_dict()
668
720
  return body
669
721
 
670
722
  @classmethod
@@ -672,7 +724,8 @@ class ManagedIngestionPipelineDefinition:
672
724
  """Deserializes the ManagedIngestionPipelineDefinition from a dictionary."""
673
725
  return cls(connection_name=d.get('connection_name', None),
674
726
  ingestion_gateway_id=d.get('ingestion_gateway_id', None),
675
- objects=_repeated_dict(d, 'objects', IngestionConfig))
727
+ objects=_repeated_dict(d, 'objects', IngestionConfig),
728
+ table_configuration=_from_dict(d, 'table_configuration', TableSpecificConfig))
676
729
 
677
730
 
678
731
  @dataclass
@@ -1189,7 +1242,7 @@ class PipelineLibrary:
1189
1242
  """Specification of a maven library to be installed."""
1190
1243
 
1191
1244
  notebook: Optional[NotebookLibrary] = None
1192
- """The path to a notebook that defines a pipeline and is stored in the <Databricks> workspace."""
1245
+ """The path to a notebook that defines a pipeline and is stored in the Databricks workspace."""
1193
1246
 
1194
1247
  def as_dict(self) -> dict:
1195
1248
  """Serializes the PipelineLibrary into a dictionary suitable for use as a JSON request body."""
@@ -1344,6 +1397,9 @@ class PipelineSpec:
1344
1397
  filters: Optional[Filters] = None
1345
1398
  """Filters on which Pipeline packages to include in the deployed graph."""
1346
1399
 
1400
+ gateway_definition: Optional[IngestionGatewayPipelineDefinition] = None
1401
+ """The definition of a gateway pipeline to support CDC."""
1402
+
1347
1403
  id: Optional[str] = None
1348
1404
  """Unique identifier for this pipeline."""
1349
1405
 
@@ -1389,6 +1445,7 @@ class PipelineSpec:
1389
1445
  if self.development is not None: body['development'] = self.development
1390
1446
  if self.edition is not None: body['edition'] = self.edition
1391
1447
  if self.filters: body['filters'] = self.filters.as_dict()
1448
+ if self.gateway_definition: body['gateway_definition'] = self.gateway_definition.as_dict()
1392
1449
  if self.id is not None: body['id'] = self.id
1393
1450
  if self.ingestion_definition: body['ingestion_definition'] = self.ingestion_definition.as_dict()
1394
1451
  if self.libraries: body['libraries'] = [v.as_dict() for v in self.libraries]
@@ -1413,6 +1470,7 @@ class PipelineSpec:
1413
1470
  development=d.get('development', None),
1414
1471
  edition=d.get('edition', None),
1415
1472
  filters=_from_dict(d, 'filters', Filters),
1473
+ gateway_definition=_from_dict(d, 'gateway_definition', IngestionGatewayPipelineDefinition),
1416
1474
  id=d.get('id', None),
1417
1475
  ingestion_definition=_from_dict(d, 'ingestion_definition',
1418
1476
  ManagedIngestionPipelineDefinition),
@@ -1523,6 +1581,11 @@ class SchemaSpec:
1523
1581
  source_schema: Optional[str] = None
1524
1582
  """Required. Schema name in the source database."""
1525
1583
 
1584
+ table_configuration: Optional[TableSpecificConfig] = None
1585
+ """Configuration settings to control the ingestion of tables. These settings are applied to all
1586
+ tables in this schema and override the table_configuration defined in the
1587
+ ManagedIngestionPipelineDefinition object."""
1588
+
1526
1589
  def as_dict(self) -> dict:
1527
1590
  """Serializes the SchemaSpec into a dictionary suitable for use as a JSON request body."""
1528
1591
  body = {}
@@ -1530,6 +1593,7 @@ class SchemaSpec:
1530
1593
  if self.destination_schema is not None: body['destination_schema'] = self.destination_schema
1531
1594
  if self.source_catalog is not None: body['source_catalog'] = self.source_catalog
1532
1595
  if self.source_schema is not None: body['source_schema'] = self.source_schema
1596
+ if self.table_configuration: body['table_configuration'] = self.table_configuration.as_dict()
1533
1597
  return body
1534
1598
 
1535
1599
  @classmethod
@@ -1538,7 +1602,8 @@ class SchemaSpec:
1538
1602
  return cls(destination_catalog=d.get('destination_catalog', None),
1539
1603
  destination_schema=d.get('destination_schema', None),
1540
1604
  source_catalog=d.get('source_catalog', None),
1541
- source_schema=d.get('source_schema', None))
1605
+ source_schema=d.get('source_schema', None),
1606
+ table_configuration=_from_dict(d, 'table_configuration', TableSpecificConfig))
1542
1607
 
1543
1608
 
1544
1609
  @dataclass
@@ -1729,6 +1794,10 @@ class TableSpec:
1729
1794
  source_table: Optional[str] = None
1730
1795
  """Required. Table name in the source database."""
1731
1796
 
1797
+ table_configuration: Optional[TableSpecificConfig] = None
1798
+ """Configuration settings to control the ingestion of tables. These settings override the
1799
+ table_configuration defined in the ManagedIngestionPipelineDefinition object and the SchemaSpec."""
1800
+
1732
1801
  def as_dict(self) -> dict:
1733
1802
  """Serializes the TableSpec into a dictionary suitable for use as a JSON request body."""
1734
1803
  body = {}
@@ -1738,6 +1807,7 @@ class TableSpec:
1738
1807
  if self.source_catalog is not None: body['source_catalog'] = self.source_catalog
1739
1808
  if self.source_schema is not None: body['source_schema'] = self.source_schema
1740
1809
  if self.source_table is not None: body['source_table'] = self.source_table
1810
+ if self.table_configuration: body['table_configuration'] = self.table_configuration.as_dict()
1741
1811
  return body
1742
1812
 
1743
1813
  @classmethod
@@ -1748,7 +1818,44 @@ class TableSpec:
1748
1818
  destination_table=d.get('destination_table', None),
1749
1819
  source_catalog=d.get('source_catalog', None),
1750
1820
  source_schema=d.get('source_schema', None),
1751
- source_table=d.get('source_table', None))
1821
+ source_table=d.get('source_table', None),
1822
+ table_configuration=_from_dict(d, 'table_configuration', TableSpecificConfig))
1823
+
1824
+
1825
+ @dataclass
1826
+ class TableSpecificConfig:
1827
+ primary_keys: Optional[List[str]] = None
1828
+ """The primary key of the table used to apply changes."""
1829
+
1830
+ salesforce_include_formula_fields: Optional[bool] = None
1831
+ """If true, formula fields defined in the table are included in the ingestion. This setting is only
1832
+ valid for the Salesforce connector"""
1833
+
1834
+ scd_type: Optional[TableSpecificConfigScdType] = None
1835
+ """The SCD type to use to ingest the table."""
1836
+
1837
+ def as_dict(self) -> dict:
1838
+ """Serializes the TableSpecificConfig into a dictionary suitable for use as a JSON request body."""
1839
+ body = {}
1840
+ if self.primary_keys: body['primary_keys'] = [v for v in self.primary_keys]
1841
+ if self.salesforce_include_formula_fields is not None:
1842
+ body['salesforce_include_formula_fields'] = self.salesforce_include_formula_fields
1843
+ if self.scd_type is not None: body['scd_type'] = self.scd_type.value
1844
+ return body
1845
+
1846
+ @classmethod
1847
+ def from_dict(cls, d: Dict[str, any]) -> TableSpecificConfig:
1848
+ """Deserializes the TableSpecificConfig from a dictionary."""
1849
+ return cls(primary_keys=d.get('primary_keys', None),
1850
+ salesforce_include_formula_fields=d.get('salesforce_include_formula_fields', None),
1851
+ scd_type=_enum(d, 'scd_type', TableSpecificConfigScdType))
1852
+
1853
+
1854
+ class TableSpecificConfigScdType(Enum):
1855
+ """The SCD type to use to ingest the table."""
1856
+
1857
+ SCD_TYPE_1 = 'SCD_TYPE_1'
1858
+ SCD_TYPE_2 = 'SCD_TYPE_2'
1752
1859
 
1753
1860
 
1754
1861
  @dataclass
@@ -1981,6 +2088,7 @@ class PipelinesAPI:
1981
2088
  dry_run: Optional[bool] = None,
1982
2089
  edition: Optional[str] = None,
1983
2090
  filters: Optional[Filters] = None,
2091
+ gateway_definition: Optional[IngestionGatewayPipelineDefinition] = None,
1984
2092
  id: Optional[str] = None,
1985
2093
  ingestion_definition: Optional[ManagedIngestionPipelineDefinition] = None,
1986
2094
  libraries: Optional[List[PipelineLibrary]] = None,
@@ -2019,6 +2127,8 @@ class PipelinesAPI:
2019
2127
  Pipeline product edition.
2020
2128
  :param filters: :class:`Filters` (optional)
2021
2129
  Filters on which Pipeline packages to include in the deployed graph.
2130
+ :param gateway_definition: :class:`IngestionGatewayPipelineDefinition` (optional)
2131
+ The definition of a gateway pipeline to support CDC.
2022
2132
  :param id: str (optional)
2023
2133
  Unique identifier for this pipeline.
2024
2134
  :param ingestion_definition: :class:`ManagedIngestionPipelineDefinition` (optional)
@@ -2056,6 +2166,7 @@ class PipelinesAPI:
2056
2166
  if dry_run is not None: body['dry_run'] = dry_run
2057
2167
  if edition is not None: body['edition'] = edition
2058
2168
  if filters is not None: body['filters'] = filters.as_dict()
2169
+ if gateway_definition is not None: body['gateway_definition'] = gateway_definition.as_dict()
2059
2170
  if id is not None: body['id'] = id
2060
2171
  if ingestion_definition is not None: body['ingestion_definition'] = ingestion_definition.as_dict()
2061
2172
  if libraries is not None: body['libraries'] = [v.as_dict() for v in libraries]
@@ -2385,6 +2496,7 @@ class PipelinesAPI:
2385
2496
  edition: Optional[str] = None,
2386
2497
  expected_last_modified: Optional[int] = None,
2387
2498
  filters: Optional[Filters] = None,
2499
+ gateway_definition: Optional[IngestionGatewayPipelineDefinition] = None,
2388
2500
  id: Optional[str] = None,
2389
2501
  ingestion_definition: Optional[ManagedIngestionPipelineDefinition] = None,
2390
2502
  libraries: Optional[List[PipelineLibrary]] = None,
@@ -2426,6 +2538,8 @@ class PipelinesAPI:
2426
2538
  modified after that time, then the request will fail with a conflict.
2427
2539
  :param filters: :class:`Filters` (optional)
2428
2540
  Filters on which Pipeline packages to include in the deployed graph.
2541
+ :param gateway_definition: :class:`IngestionGatewayPipelineDefinition` (optional)
2542
+ The definition of a gateway pipeline to support CDC.
2429
2543
  :param id: str (optional)
2430
2544
  Unique identifier for this pipeline.
2431
2545
  :param ingestion_definition: :class:`ManagedIngestionPipelineDefinition` (optional)
@@ -2463,6 +2577,7 @@ class PipelinesAPI:
2463
2577
  if edition is not None: body['edition'] = edition
2464
2578
  if expected_last_modified is not None: body['expected_last_modified'] = expected_last_modified
2465
2579
  if filters is not None: body['filters'] = filters.as_dict()
2580
+ if gateway_definition is not None: body['gateway_definition'] = gateway_definition.as_dict()
2466
2581
  if id is not None: body['id'] = id
2467
2582
  if ingestion_definition is not None: body['ingestion_definition'] = ingestion_definition.as_dict()
2468
2583
  if libraries is not None: body['libraries'] = [v.as_dict() for v in libraries]