databricks-sdk 0.44.0__py3-none-any.whl → 0.45.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 (63) hide show
  1. databricks/sdk/__init__.py +123 -115
  2. databricks/sdk/_base_client.py +112 -88
  3. databricks/sdk/_property.py +12 -7
  4. databricks/sdk/_widgets/__init__.py +13 -2
  5. databricks/sdk/_widgets/default_widgets_utils.py +21 -15
  6. databricks/sdk/_widgets/ipywidgets_utils.py +47 -24
  7. databricks/sdk/azure.py +8 -6
  8. databricks/sdk/casing.py +5 -5
  9. databricks/sdk/config.py +152 -99
  10. databricks/sdk/core.py +57 -47
  11. databricks/sdk/credentials_provider.py +360 -210
  12. databricks/sdk/data_plane.py +86 -3
  13. databricks/sdk/dbutils.py +123 -87
  14. databricks/sdk/environments.py +52 -35
  15. databricks/sdk/errors/base.py +61 -35
  16. databricks/sdk/errors/customizer.py +3 -3
  17. databricks/sdk/errors/deserializer.py +38 -25
  18. databricks/sdk/errors/details.py +417 -0
  19. databricks/sdk/errors/mapper.py +1 -1
  20. databricks/sdk/errors/overrides.py +27 -24
  21. databricks/sdk/errors/parser.py +26 -14
  22. databricks/sdk/errors/platform.py +10 -10
  23. databricks/sdk/errors/private_link.py +24 -24
  24. databricks/sdk/logger/round_trip_logger.py +28 -20
  25. databricks/sdk/mixins/compute.py +90 -60
  26. databricks/sdk/mixins/files.py +815 -145
  27. databricks/sdk/mixins/jobs.py +201 -20
  28. databricks/sdk/mixins/open_ai_client.py +26 -20
  29. databricks/sdk/mixins/workspace.py +45 -34
  30. databricks/sdk/oauth.py +372 -196
  31. databricks/sdk/retries.py +14 -12
  32. databricks/sdk/runtime/__init__.py +34 -17
  33. databricks/sdk/runtime/dbutils_stub.py +52 -39
  34. databricks/sdk/service/_internal.py +12 -7
  35. databricks/sdk/service/apps.py +618 -418
  36. databricks/sdk/service/billing.py +827 -604
  37. databricks/sdk/service/catalog.py +6552 -4474
  38. databricks/sdk/service/cleanrooms.py +550 -388
  39. databricks/sdk/service/compute.py +5241 -3531
  40. databricks/sdk/service/dashboards.py +1313 -923
  41. databricks/sdk/service/files.py +442 -309
  42. databricks/sdk/service/iam.py +2115 -1483
  43. databricks/sdk/service/jobs.py +4151 -2588
  44. databricks/sdk/service/marketplace.py +2210 -1517
  45. databricks/sdk/service/ml.py +3364 -2255
  46. databricks/sdk/service/oauth2.py +922 -584
  47. databricks/sdk/service/pipelines.py +1865 -1203
  48. databricks/sdk/service/provisioning.py +1435 -1029
  49. databricks/sdk/service/serving.py +2040 -1278
  50. databricks/sdk/service/settings.py +2846 -1929
  51. databricks/sdk/service/sharing.py +2201 -877
  52. databricks/sdk/service/sql.py +4650 -3103
  53. databricks/sdk/service/vectorsearch.py +816 -550
  54. databricks/sdk/service/workspace.py +1330 -906
  55. databricks/sdk/useragent.py +36 -22
  56. databricks/sdk/version.py +1 -1
  57. {databricks_sdk-0.44.0.dist-info → databricks_sdk-0.45.0.dist-info}/METADATA +31 -31
  58. databricks_sdk-0.45.0.dist-info/RECORD +70 -0
  59. {databricks_sdk-0.44.0.dist-info → databricks_sdk-0.45.0.dist-info}/WHEEL +1 -1
  60. databricks_sdk-0.44.0.dist-info/RECORD +0 -69
  61. {databricks_sdk-0.44.0.dist-info → databricks_sdk-0.45.0.dist-info}/LICENSE +0 -0
  62. {databricks_sdk-0.44.0.dist-info → databricks_sdk-0.45.0.dist-info}/NOTICE +0 -0
  63. {databricks_sdk-0.44.0.dist-info → databricks_sdk-0.45.0.dist-info}/top_level.txt +0 -0
@@ -1,19 +1,163 @@
1
- from typing import Optional
1
+ from typing import Iterator, Optional
2
2
 
3
3
  from databricks.sdk.service import jobs
4
+ from databricks.sdk.service.jobs import BaseJob, BaseRun, Job, RunType
4
5
 
5
6
 
6
7
  class JobsExt(jobs.JobsAPI):
7
8
 
8
- def get_run(self,
9
- run_id: int,
10
- *,
11
- include_history: Optional[bool] = None,
12
- include_resolved_values: Optional[bool] = None,
13
- page_token: Optional[str] = None) -> jobs.Run:
9
+ def list(
10
+ self,
11
+ *,
12
+ expand_tasks: Optional[bool] = None,
13
+ limit: Optional[int] = None,
14
+ name: Optional[str] = None,
15
+ offset: Optional[int] = None,
16
+ page_token: Optional[str] = None,
17
+ ) -> Iterator[BaseJob]:
18
+ """List jobs.
19
+
20
+ Retrieves a list of jobs. If the job has multiple pages of tasks, job_clusters, parameters or environments,
21
+ it will paginate through all pages and aggregate the results.
22
+
23
+ :param expand_tasks: bool (optional)
24
+ Whether to include task and cluster details in the response. Note that in API 2.2, only the first
25
+ 100 elements will be shown. Use :method:jobs/get to paginate through all tasks and clusters.
26
+ :param limit: int (optional)
27
+ The number of jobs to return. This value must be greater than 0 and less or equal to 100. The
28
+ default value is 20.
29
+ :param name: str (optional)
30
+ A filter on the list based on the exact (case insensitive) job name.
31
+ :param offset: int (optional)
32
+ The offset of the first job to return, relative to the most recently created job. Deprecated since
33
+ June 2023. Use `page_token` to iterate through the pages instead.
34
+ :param page_token: str (optional)
35
+ Use `next_page_token` or `prev_page_token` returned from the previous request to list the next or
36
+ previous page of jobs respectively.
37
+
38
+ :returns: Iterator over :class:`BaseJob`
14
39
  """
15
- This method fetches the details of a run identified by `run_id`. If the run has multiple pages of tasks or iterations,
40
+ # fetch jobs with limited elements in top level arrays
41
+ jobs_list = super().list(
42
+ expand_tasks=expand_tasks,
43
+ limit=limit,
44
+ name=name,
45
+ offset=offset,
46
+ page_token=page_token,
47
+ )
48
+ if not expand_tasks:
49
+ yield from jobs_list
50
+
51
+ # fully fetch all top level arrays for each job in the list
52
+ for job in jobs_list:
53
+ if job.has_more:
54
+ job_from_get_call = self.get(job.job_id)
55
+ job.settings.tasks = job_from_get_call.settings.tasks
56
+ job.settings.job_clusters = job_from_get_call.settings.job_clusters
57
+ job.settings.parameters = job_from_get_call.settings.parameters
58
+ job.settings.environments = job_from_get_call.settings.environments
59
+ # Remove has_more fields for each job in the list.
60
+ # This field in Jobs API 2.2 is useful for pagination. It indicates if there are more than 100 tasks or job_clusters in the job.
61
+ # This function hides pagination details from the user. So the field does not play useful role here.
62
+ if hasattr(job, "has_more"):
63
+ delattr(job, "has_more")
64
+ yield job
65
+
66
+ def list_runs(
67
+ self,
68
+ *,
69
+ active_only: Optional[bool] = None,
70
+ completed_only: Optional[bool] = None,
71
+ expand_tasks: Optional[bool] = None,
72
+ job_id: Optional[int] = None,
73
+ limit: Optional[int] = None,
74
+ offset: Optional[int] = None,
75
+ page_token: Optional[str] = None,
76
+ run_type: Optional[RunType] = None,
77
+ start_time_from: Optional[int] = None,
78
+ start_time_to: Optional[int] = None,
79
+ ) -> Iterator[BaseRun]:
80
+ """List job runs.
81
+
82
+ List runs in descending order by start time. If the job has multiple pages of tasks, job_clusters, parameters or repair history,
16
83
  it will paginate through all pages and aggregate the results.
84
+
85
+ :param active_only: bool (optional)
86
+ If active_only is `true`, only active runs are included in the results; otherwise, lists both active
87
+ and completed runs. An active run is a run in the `QUEUED`, `PENDING`, `RUNNING`, or `TERMINATING`.
88
+ This field cannot be `true` when completed_only is `true`.
89
+ :param completed_only: bool (optional)
90
+ If completed_only is `true`, only completed runs are included in the results; otherwise, lists both
91
+ active and completed runs. This field cannot be `true` when active_only is `true`.
92
+ :param expand_tasks: bool (optional)
93
+ Whether to include task and cluster details in the response. Note that in API 2.2, only the first
94
+ 100 elements will be shown. Use :method:jobs/getrun to paginate through all tasks and clusters.
95
+ :param job_id: int (optional)
96
+ The job for which to list runs. If omitted, the Jobs service lists runs from all jobs.
97
+ :param limit: int (optional)
98
+ The number of runs to return. This value must be greater than 0 and less than 25. The default value
99
+ is 20. If a request specifies a limit of 0, the service instead uses the maximum limit.
100
+ :param offset: int (optional)
101
+ The offset of the first run to return, relative to the most recent run. Deprecated since June 2023.
102
+ Use `page_token` to iterate through the pages instead.
103
+ :param page_token: str (optional)
104
+ Use `next_page_token` or `prev_page_token` returned from the previous request to list the next or
105
+ previous page of runs respectively.
106
+ :param run_type: :class:`RunType` (optional)
107
+ The type of runs to return. For a description of run types, see :method:jobs/getRun.
108
+ :param start_time_from: int (optional)
109
+ Show runs that started _at or after_ this value. The value must be a UTC timestamp in milliseconds.
110
+ Can be combined with _start_time_to_ to filter by a time range.
111
+ :param start_time_to: int (optional)
112
+ Show runs that started _at or before_ this value. The value must be a UTC timestamp in milliseconds.
113
+ Can be combined with _start_time_from_ to filter by a time range.
114
+
115
+ :returns: Iterator over :class:`BaseRun`
116
+ """
117
+ # fetch runs with limited elements in top level arrays
118
+ runs_list = super().list_runs(
119
+ active_only=active_only,
120
+ completed_only=completed_only,
121
+ expand_tasks=expand_tasks,
122
+ job_id=job_id,
123
+ limit=limit,
124
+ offset=offset,
125
+ page_token=page_token,
126
+ run_type=run_type,
127
+ start_time_from=start_time_from,
128
+ start_time_to=start_time_to,
129
+ )
130
+
131
+ if not expand_tasks:
132
+ yield from runs_list
133
+
134
+ # fully fetch all top level arrays for each run in the list
135
+ for run in runs_list:
136
+ if run.has_more:
137
+ run_from_get_call = self.get_run(run.run_id)
138
+ run.tasks = run_from_get_call.tasks
139
+ run.job_clusters = run_from_get_call.job_clusters
140
+ run.job_parameters = run_from_get_call.job_parameters
141
+ run.repair_history = run_from_get_call.repair_history
142
+ # Remove has_more fields for each run in the list.
143
+ # This field in Jobs API 2.2 is useful for pagination. It indicates if there are more than 100 tasks or job_clusters in the run.
144
+ # This function hides pagination details from the user. So the field does not play useful role here.
145
+ if hasattr(run, "has_more"):
146
+ delattr(run, "has_more")
147
+ yield run
148
+
149
+ def get_run(
150
+ self,
151
+ run_id: int,
152
+ *,
153
+ include_history: Optional[bool] = None,
154
+ include_resolved_values: Optional[bool] = None,
155
+ page_token: Optional[str] = None,
156
+ ) -> jobs.Run:
157
+ """Get a single job run.
158
+
159
+ Retrieve the metadata of a run. If a run has multiple pages of tasks, it will paginate through all pages of tasks, iterations, job_clusters, job_parameters, and repair history.
160
+
17
161
  :param run_id: int
18
162
  The canonical identifier of the run for which to retrieve the metadata. This field is required.
19
163
  :param include_history: bool (optional)
@@ -21,29 +165,66 @@ class JobsExt(jobs.JobsAPI):
21
165
  :param include_resolved_values: bool (optional)
22
166
  Whether to include resolved parameter values in the response.
23
167
  :param page_token: str (optional)
24
- To list the next page or the previous page of job tasks, set this field to the value of the
25
- `next_page_token` or `prev_page_token` returned in the GetJob response.
168
+ To list the next page of job tasks, set this field to the value of the `next_page_token` returned in
169
+ the GetJob response.
170
+
26
171
  :returns: :class:`Run`
27
172
  """
28
- run = super().get_run(run_id,
29
- include_history=include_history,
30
- include_resolved_values=include_resolved_values,
31
- page_token=page_token)
173
+ run = super().get_run(
174
+ run_id,
175
+ include_history=include_history,
176
+ include_resolved_values=include_resolved_values,
177
+ page_token=page_token,
178
+ )
32
179
 
33
180
  # When querying a Job run, a page token is returned when there are more than 100 tasks. No iterations are defined for a Job run. Therefore, the next page in the response only includes the next page of tasks.
34
181
  # When querying a ForEach task run, a page token is returned when there are more than 100 iterations. Only a single task is returned, corresponding to the ForEach task itself. Therefore, the client only reads the iterations from the next page and not the tasks.
35
182
  is_paginating_iterations = run.iterations is not None and len(run.iterations) > 0
36
183
 
184
+ # runs/get response includes next_page_token as long as there are more pages to fetch.
37
185
  while run.next_page_token is not None:
38
- next_run = super().get_run(run_id,
39
- include_history=include_history,
40
- include_resolved_values=include_resolved_values,
41
- page_token=run.next_page_token)
186
+ next_run = super().get_run(
187
+ run_id,
188
+ include_history=include_history,
189
+ include_resolved_values=include_resolved_values,
190
+ page_token=run.next_page_token,
191
+ )
42
192
  if is_paginating_iterations:
43
193
  run.iterations.extend(next_run.iterations)
44
194
  else:
45
195
  run.tasks.extend(next_run.tasks)
196
+ # Each new page of runs/get response includes the next page of the job_clusters, job_parameters, and repair history.
197
+ run.job_clusters.extend(next_run.job_clusters)
198
+ run.job_parameters.extend(next_run.job_parameters)
199
+ run.repair_history.extend(next_run.repair_history)
46
200
  run.next_page_token = next_run.next_page_token
47
201
 
48
- run.prev_page_token = None
49
- return run
202
+ return run
203
+
204
+ def get(self, job_id: int, *, page_token: Optional[str] = None) -> Job:
205
+ """Get a single job.
206
+
207
+ Retrieves the details for a single job. If the job has multiple pages of tasks, job_clusters, parameters or environments,
208
+ it will paginate through all pages and aggregate the results.
209
+
210
+ :param job_id: int
211
+ The canonical identifier of the job to retrieve information about. This field is required.
212
+ :param page_token: str (optional)
213
+ Use `next_page_token` returned from the previous GetJob to request the next page of the job's
214
+ sub-resources.
215
+
216
+ :returns: :class:`Job`
217
+ """
218
+ job = super().get(job_id, page_token=page_token)
219
+
220
+ # jobs/get response includes next_page_token as long as there are more pages to fetch.
221
+ while job.next_page_token is not None:
222
+ next_job = super().get(job_id, page_token=job.next_page_token)
223
+ # Each new page of jobs/get response includes the next page of the tasks, job_clusters, job_parameters, and environments.
224
+ job.settings.tasks.extend(next_job.settings.tasks)
225
+ job.settings.job_clusters.extend(next_job.settings.job_clusters)
226
+ job.settings.parameters.extend(next_job.settings.parameters)
227
+ job.settings.environments.extend(next_job.settings.environments)
228
+ job.next_page_token = next_job.next_page_token
229
+
230
+ return job
@@ -40,8 +40,9 @@ class ServingEndpointsExt(ServingEndpointsAPI):
40
40
 
41
41
  return OpenAI(
42
42
  base_url=self._api._cfg.host + "/serving-endpoints",
43
- api_key="no-token", # Passing in a placeholder to pass validations, this will not be used
44
- http_client=self._get_authorized_http_client())
43
+ api_key="no-token", # Passing in a placeholder to pass validations, this will not be used
44
+ http_client=self._get_authorized_http_client(),
45
+ )
45
46
 
46
47
  def get_langchain_chat_open_ai_client(self, model):
47
48
  try:
@@ -54,17 +55,20 @@ class ServingEndpointsExt(ServingEndpointsAPI):
54
55
  return ChatOpenAI(
55
56
  model=model,
56
57
  openai_api_base=self._api._cfg.host + "/serving-endpoints",
57
- api_key="no-token", # Passing in a placeholder to pass validations, this will not be used
58
- http_client=self._get_authorized_http_client())
59
-
60
- def http_request(self,
61
- conn: str,
62
- method: ExternalFunctionRequestHttpMethod,
63
- path: str,
64
- *,
65
- headers: Optional[Dict[str, str]] = None,
66
- json: Optional[Dict[str, str]] = None,
67
- params: Optional[Dict[str, str]] = None) -> Response:
58
+ api_key="no-token", # Passing in a placeholder to pass validations, this will not be used
59
+ http_client=self._get_authorized_http_client(),
60
+ )
61
+
62
+ def http_request(
63
+ self,
64
+ conn: str,
65
+ method: ExternalFunctionRequestHttpMethod,
66
+ path: str,
67
+ *,
68
+ headers: Optional[Dict[str, str]] = None,
69
+ json: Optional[Dict[str, str]] = None,
70
+ params: Optional[Dict[str, str]] = None,
71
+ ) -> Response:
68
72
  """Make external services call using the credentials stored in UC Connection.
69
73
  **NOTE:** Experimental: This API may change or be removed in a future release without warning.
70
74
  :param conn: str
@@ -84,16 +88,18 @@ class ServingEndpointsExt(ServingEndpointsAPI):
84
88
  """
85
89
  response = Response()
86
90
  response.status_code = 200
87
- server_response = super().http_request(connection_name=conn,
88
- method=method,
89
- path=path,
90
- headers=js.dumps(headers) if headers is not None else None,
91
- json=js.dumps(json) if json is not None else None,
92
- params=js.dumps(params) if params is not None else None)
91
+ server_response = super().http_request(
92
+ connection_name=conn,
93
+ method=method,
94
+ path=path,
95
+ headers=js.dumps(headers) if headers is not None else None,
96
+ json=js.dumps(json) if json is not None else None,
97
+ params=js.dumps(params) if params is not None else None,
98
+ )
93
99
 
94
100
  # Read the content from the HttpRequestResponse object
95
101
  if hasattr(server_response, "contents") and hasattr(server_response.contents, "read"):
96
- raw_content = server_response.contents.read() # Read the bytes
102
+ raw_content = server_response.contents.read() # Read the bytes
97
103
  else:
98
104
  raise ValueError("Invalid response from the server.")
99
105
 
@@ -1,23 +1,25 @@
1
- from typing import BinaryIO, Iterator, Optional, Union
1
+ from typing import Any, BinaryIO, Iterator, Optional, Union
2
2
 
3
3
  from ..core import DatabricksError
4
4
  from ..service.workspace import (ExportFormat, ImportFormat, Language,
5
5
  ObjectInfo, ObjectType, WorkspaceAPI)
6
6
 
7
7
 
8
- def _fqcn(x: any) -> str:
9
- return f'{x.__module__}.{x.__name__}'
8
+ def _fqcn(x: Any) -> str:
9
+ return f"{x.__module__}.{x.__name__}"
10
10
 
11
11
 
12
12
  class WorkspaceExt(WorkspaceAPI):
13
13
  __doc__ = WorkspaceAPI.__doc__
14
14
 
15
- def list(self,
16
- path: str,
17
- *,
18
- notebooks_modified_after: Optional[int] = None,
19
- recursive: Optional[bool] = False,
20
- **kwargs) -> Iterator[ObjectInfo]:
15
+ def list(
16
+ self,
17
+ path: str,
18
+ *,
19
+ notebooks_modified_after: Optional[int] = None,
20
+ recursive: Optional[bool] = False,
21
+ **kwargs,
22
+ ) -> Iterator[ObjectInfo]:
21
23
  """List workspace objects
22
24
 
23
25
  :param recursive: bool
@@ -35,13 +37,15 @@ class WorkspaceExt(WorkspaceAPI):
35
37
  continue
36
38
  yield object_info
37
39
 
38
- def upload(self,
39
- path: str,
40
- content: Union[bytes, BinaryIO],
41
- *,
42
- format: Optional[ImportFormat] = None,
43
- language: Optional[Language] = None,
44
- overwrite: Optional[bool] = False) -> None:
40
+ def upload(
41
+ self,
42
+ path: str,
43
+ content: Union[bytes, BinaryIO],
44
+ *,
45
+ format: Optional[ImportFormat] = None,
46
+ language: Optional[Language] = None,
47
+ overwrite: Optional[bool] = False,
48
+ ) -> None:
45
49
  """
46
50
  Uploads a workspace object (for example, a notebook or file) or the contents of an entire
47
51
  directory (`DBC` format).
@@ -60,31 +64,37 @@ class WorkspaceExt(WorkspaceAPI):
60
64
  :param language: Only required if using `ExportFormat.SOURCE`.
61
65
  """
62
66
  if format is not None and not isinstance(format, ImportFormat):
63
- raise ValueError(
64
- f'format is expected to be {_fqcn(ImportFormat)}, but got {_fqcn(format.__class__)}')
67
+ raise ValueError(f"format is expected to be {_fqcn(ImportFormat)}, but got {_fqcn(format.__class__)}")
65
68
  if (not format or format == ImportFormat.SOURCE) and not language:
66
69
  suffixes = {
67
- '.py': Language.PYTHON,
68
- '.sql': Language.SQL,
69
- '.scala': Language.SCALA,
70
- '.R': Language.R
70
+ ".py": Language.PYTHON,
71
+ ".sql": Language.SQL,
72
+ ".scala": Language.SCALA,
73
+ ".R": Language.R,
71
74
  }
72
75
  for sfx, lang in suffixes.items():
73
76
  if path.endswith(sfx):
74
77
  language = lang
75
78
  break
76
79
  if language is not None and not isinstance(language, Language):
77
- raise ValueError(
78
- f'language is expected to be {_fqcn(Language)}, but got {_fqcn(language.__class__)}')
79
- data = {'path': path}
80
- if format: data['format'] = format.value
81
- if language: data['language'] = language.value
82
- if overwrite: data['overwrite'] = 'true'
80
+ raise ValueError(f"language is expected to be {_fqcn(Language)}, but got {_fqcn(language.__class__)}")
81
+ data = {"path": path}
82
+ if format:
83
+ data["format"] = format.value
84
+ if language:
85
+ data["language"] = language.value
86
+ if overwrite:
87
+ data["overwrite"] = "true"
83
88
  try:
84
- return self._api.do('POST', '/api/2.0/workspace/import', files={'content': content}, data=data)
89
+ return self._api.do(
90
+ "POST",
91
+ "/api/2.0/workspace/import",
92
+ files={"content": content},
93
+ data=data,
94
+ )
85
95
  except DatabricksError as e:
86
- if e.error_code == 'INVALID_PARAMETER_VALUE':
87
- msg = f'Perhaps you forgot to specify the `format=ImportFormat.AUTO`. {e}'
96
+ if e.error_code == "INVALID_PARAMETER_VALUE":
97
+ msg = f"Perhaps you forgot to specify the `format=ImportFormat.AUTO`. {e}"
88
98
  raise DatabricksError(message=msg, error_code=e.error_code)
89
99
  else:
90
100
  raise e
@@ -100,7 +110,8 @@ class WorkspaceExt(WorkspaceAPI):
100
110
  the request.
101
111
  :return: file-like `io.BinaryIO` of the `path` contents.
102
112
  """
103
- query = {'path': path, 'direct_download': 'true'}
104
- if format: query['format'] = format.value
105
- response = self._api.do('GET', '/api/2.0/workspace/export', query=query, raw=True)
113
+ query = {"path": path, "direct_download": "true"}
114
+ if format:
115
+ query["format"] = format.value
116
+ response = self._api.do("GET", "/api/2.0/workspace/export", query=query, raw=True)
106
117
  return response["contents"]