databricks-sdk 0.36.0__py3-none-any.whl → 0.38.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.
- databricks/sdk/__init__.py +22 -29
- databricks/sdk/_base_client.py +61 -14
- databricks/sdk/config.py +10 -9
- databricks/sdk/credentials_provider.py +6 -5
- databricks/sdk/mixins/jobs.py +49 -0
- databricks/sdk/service/apps.py +50 -186
- databricks/sdk/service/billing.py +1 -1
- databricks/sdk/service/catalog.py +952 -45
- databricks/sdk/service/compute.py +23 -20
- databricks/sdk/service/dashboards.py +31 -281
- databricks/sdk/service/iam.py +6 -4
- databricks/sdk/service/jobs.py +93 -76
- databricks/sdk/service/marketplace.py +1 -0
- databricks/sdk/service/ml.py +4 -3
- databricks/sdk/service/oauth2.py +29 -8
- databricks/sdk/service/pipelines.py +94 -20
- databricks/sdk/service/provisioning.py +68 -0
- databricks/sdk/service/serving.py +2 -2
- databricks/sdk/service/settings.py +322 -2
- databricks/sdk/service/sharing.py +2 -618
- databricks/sdk/service/sql.py +7 -7
- databricks/sdk/service/workspace.py +7 -4
- databricks/sdk/version.py +1 -1
- {databricks_sdk-0.36.0.dist-info → databricks_sdk-0.38.0.dist-info}/METADATA +1 -1
- {databricks_sdk-0.36.0.dist-info → databricks_sdk-0.38.0.dist-info}/RECORD +29 -28
- {databricks_sdk-0.36.0.dist-info → databricks_sdk-0.38.0.dist-info}/WHEEL +1 -1
- {databricks_sdk-0.36.0.dist-info → databricks_sdk-0.38.0.dist-info}/LICENSE +0 -0
- {databricks_sdk-0.36.0.dist-info → databricks_sdk-0.38.0.dist-info}/NOTICE +0 -0
- {databricks_sdk-0.36.0.dist-info → databricks_sdk-0.38.0.dist-info}/top_level.txt +0 -0
databricks/sdk/service/apps.py
CHANGED
|
@@ -52,6 +52,8 @@ class App:
|
|
|
52
52
|
resources: Optional[List[AppResource]] = None
|
|
53
53
|
"""Resources for the app."""
|
|
54
54
|
|
|
55
|
+
service_principal_client_id: Optional[str] = None
|
|
56
|
+
|
|
55
57
|
service_principal_id: Optional[int] = None
|
|
56
58
|
|
|
57
59
|
service_principal_name: Optional[str] = None
|
|
@@ -79,6 +81,8 @@ class App:
|
|
|
79
81
|
if self.name is not None: body['name'] = self.name
|
|
80
82
|
if self.pending_deployment: body['pending_deployment'] = self.pending_deployment.as_dict()
|
|
81
83
|
if self.resources: body['resources'] = [v.as_dict() for v in self.resources]
|
|
84
|
+
if self.service_principal_client_id is not None:
|
|
85
|
+
body['service_principal_client_id'] = self.service_principal_client_id
|
|
82
86
|
if self.service_principal_id is not None: body['service_principal_id'] = self.service_principal_id
|
|
83
87
|
if self.service_principal_name is not None:
|
|
84
88
|
body['service_principal_name'] = self.service_principal_name
|
|
@@ -100,6 +104,7 @@ class App:
|
|
|
100
104
|
name=d.get('name', None),
|
|
101
105
|
pending_deployment=_from_dict(d, 'pending_deployment', AppDeployment),
|
|
102
106
|
resources=_repeated_dict(d, 'resources', AppResource),
|
|
107
|
+
service_principal_client_id=d.get('service_principal_client_id', None),
|
|
103
108
|
service_principal_id=d.get('service_principal_id', None),
|
|
104
109
|
service_principal_name=d.get('service_principal_name', None),
|
|
105
110
|
update_time=d.get('update_time', None),
|
|
@@ -611,70 +616,6 @@ class ComputeStatus:
|
|
|
611
616
|
return cls(message=d.get('message', None), state=_enum(d, 'state', ComputeState))
|
|
612
617
|
|
|
613
618
|
|
|
614
|
-
@dataclass
|
|
615
|
-
class CreateAppDeploymentRequest:
|
|
616
|
-
app_name: Optional[str] = None
|
|
617
|
-
"""The name of the app."""
|
|
618
|
-
|
|
619
|
-
deployment_id: Optional[str] = None
|
|
620
|
-
"""The unique id of the deployment."""
|
|
621
|
-
|
|
622
|
-
mode: Optional[AppDeploymentMode] = None
|
|
623
|
-
"""The mode of which the deployment will manage the source code."""
|
|
624
|
-
|
|
625
|
-
source_code_path: Optional[str] = None
|
|
626
|
-
"""The workspace file system path of the source code used to create the app deployment. This is
|
|
627
|
-
different from `deployment_artifacts.source_code_path`, which is the path used by the deployed
|
|
628
|
-
app. The former refers to the original source code location of the app in the workspace during
|
|
629
|
-
deployment creation, whereas the latter provides a system generated stable snapshotted source
|
|
630
|
-
code path used by the deployment."""
|
|
631
|
-
|
|
632
|
-
def as_dict(self) -> dict:
|
|
633
|
-
"""Serializes the CreateAppDeploymentRequest into a dictionary suitable for use as a JSON request body."""
|
|
634
|
-
body = {}
|
|
635
|
-
if self.app_name is not None: body['app_name'] = self.app_name
|
|
636
|
-
if self.deployment_id is not None: body['deployment_id'] = self.deployment_id
|
|
637
|
-
if self.mode is not None: body['mode'] = self.mode.value
|
|
638
|
-
if self.source_code_path is not None: body['source_code_path'] = self.source_code_path
|
|
639
|
-
return body
|
|
640
|
-
|
|
641
|
-
@classmethod
|
|
642
|
-
def from_dict(cls, d: Dict[str, any]) -> CreateAppDeploymentRequest:
|
|
643
|
-
"""Deserializes the CreateAppDeploymentRequest from a dictionary."""
|
|
644
|
-
return cls(app_name=d.get('app_name', None),
|
|
645
|
-
deployment_id=d.get('deployment_id', None),
|
|
646
|
-
mode=_enum(d, 'mode', AppDeploymentMode),
|
|
647
|
-
source_code_path=d.get('source_code_path', None))
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
@dataclass
|
|
651
|
-
class CreateAppRequest:
|
|
652
|
-
name: str
|
|
653
|
-
"""The name of the app. The name must contain only lowercase alphanumeric characters and hyphens.
|
|
654
|
-
It must be unique within the workspace."""
|
|
655
|
-
|
|
656
|
-
description: Optional[str] = None
|
|
657
|
-
"""The description of the app."""
|
|
658
|
-
|
|
659
|
-
resources: Optional[List[AppResource]] = None
|
|
660
|
-
"""Resources for the app."""
|
|
661
|
-
|
|
662
|
-
def as_dict(self) -> dict:
|
|
663
|
-
"""Serializes the CreateAppRequest into a dictionary suitable for use as a JSON request body."""
|
|
664
|
-
body = {}
|
|
665
|
-
if self.description is not None: body['description'] = self.description
|
|
666
|
-
if self.name is not None: body['name'] = self.name
|
|
667
|
-
if self.resources: body['resources'] = [v.as_dict() for v in self.resources]
|
|
668
|
-
return body
|
|
669
|
-
|
|
670
|
-
@classmethod
|
|
671
|
-
def from_dict(cls, d: Dict[str, any]) -> CreateAppRequest:
|
|
672
|
-
"""Deserializes the CreateAppRequest from a dictionary."""
|
|
673
|
-
return cls(description=d.get('description', None),
|
|
674
|
-
name=d.get('name', None),
|
|
675
|
-
resources=_repeated_dict(d, 'resources', AppResource))
|
|
676
|
-
|
|
677
|
-
|
|
678
619
|
@dataclass
|
|
679
620
|
class GetAppPermissionLevelsResponse:
|
|
680
621
|
permission_levels: Optional[List[AppPermissionsDescription]] = None
|
|
@@ -746,34 +687,6 @@ class StopAppRequest:
|
|
|
746
687
|
"""The name of the app."""
|
|
747
688
|
|
|
748
689
|
|
|
749
|
-
@dataclass
|
|
750
|
-
class UpdateAppRequest:
|
|
751
|
-
name: str
|
|
752
|
-
"""The name of the app. The name must contain only lowercase alphanumeric characters and hyphens.
|
|
753
|
-
It must be unique within the workspace."""
|
|
754
|
-
|
|
755
|
-
description: Optional[str] = None
|
|
756
|
-
"""The description of the app."""
|
|
757
|
-
|
|
758
|
-
resources: Optional[List[AppResource]] = None
|
|
759
|
-
"""Resources for the app."""
|
|
760
|
-
|
|
761
|
-
def as_dict(self) -> dict:
|
|
762
|
-
"""Serializes the UpdateAppRequest into a dictionary suitable for use as a JSON request body."""
|
|
763
|
-
body = {}
|
|
764
|
-
if self.description is not None: body['description'] = self.description
|
|
765
|
-
if self.name is not None: body['name'] = self.name
|
|
766
|
-
if self.resources: body['resources'] = [v.as_dict() for v in self.resources]
|
|
767
|
-
return body
|
|
768
|
-
|
|
769
|
-
@classmethod
|
|
770
|
-
def from_dict(cls, d: Dict[str, any]) -> UpdateAppRequest:
|
|
771
|
-
"""Deserializes the UpdateAppRequest from a dictionary."""
|
|
772
|
-
return cls(description=d.get('description', None),
|
|
773
|
-
name=d.get('name', None),
|
|
774
|
-
resources=_repeated_dict(d, 'resources', AppResource))
|
|
775
|
-
|
|
776
|
-
|
|
777
690
|
class AppsAPI:
|
|
778
691
|
"""Apps run directly on a customer’s Databricks instance, integrate with their data, use and extend
|
|
779
692
|
Databricks services, and enable users to interact through single sign-on."""
|
|
@@ -813,29 +726,31 @@ class AppsAPI:
|
|
|
813
726
|
attempt += 1
|
|
814
727
|
raise TimeoutError(f'timed out after {timeout}: {status_message}')
|
|
815
728
|
|
|
816
|
-
def
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
729
|
+
def wait_get_deployment_app_succeeded(
|
|
730
|
+
self,
|
|
731
|
+
app_name: str,
|
|
732
|
+
deployment_id: str,
|
|
733
|
+
timeout=timedelta(minutes=20),
|
|
734
|
+
callback: Optional[Callable[[AppDeployment], None]] = None) -> AppDeployment:
|
|
820
735
|
deadline = time.time() + timeout.total_seconds()
|
|
821
|
-
target_states = (
|
|
822
|
-
failure_states = (
|
|
736
|
+
target_states = (AppDeploymentState.SUCCEEDED, )
|
|
737
|
+
failure_states = (AppDeploymentState.FAILED, )
|
|
823
738
|
status_message = 'polling...'
|
|
824
739
|
attempt = 1
|
|
825
740
|
while time.time() < deadline:
|
|
826
|
-
poll = self.
|
|
827
|
-
status = poll.
|
|
741
|
+
poll = self.get_deployment(app_name=app_name, deployment_id=deployment_id)
|
|
742
|
+
status = poll.status.state
|
|
828
743
|
status_message = f'current status: {status}'
|
|
829
|
-
if poll.
|
|
830
|
-
status_message = poll.
|
|
744
|
+
if poll.status:
|
|
745
|
+
status_message = poll.status.message
|
|
831
746
|
if status in target_states:
|
|
832
747
|
return poll
|
|
833
748
|
if callback:
|
|
834
749
|
callback(poll)
|
|
835
750
|
if status in failure_states:
|
|
836
|
-
msg = f'failed to reach
|
|
751
|
+
msg = f'failed to reach SUCCEEDED, got {status}: {status_message}'
|
|
837
752
|
raise OperationFailed(msg)
|
|
838
|
-
prefix = f"
|
|
753
|
+
prefix = f"app_name={app_name}, deployment_id={deployment_id}"
|
|
839
754
|
sleep = attempt
|
|
840
755
|
if sleep > 10:
|
|
841
756
|
# sleep 10s max per attempt
|
|
@@ -845,31 +760,29 @@ class AppsAPI:
|
|
|
845
760
|
attempt += 1
|
|
846
761
|
raise TimeoutError(f'timed out after {timeout}: {status_message}')
|
|
847
762
|
|
|
848
|
-
def
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
timeout=timedelta(minutes=20),
|
|
853
|
-
callback: Optional[Callable[[AppDeployment], None]] = None) -> AppDeployment:
|
|
763
|
+
def wait_get_app_stopped(self,
|
|
764
|
+
name: str,
|
|
765
|
+
timeout=timedelta(minutes=20),
|
|
766
|
+
callback: Optional[Callable[[App], None]] = None) -> App:
|
|
854
767
|
deadline = time.time() + timeout.total_seconds()
|
|
855
|
-
target_states = (
|
|
856
|
-
failure_states = (
|
|
768
|
+
target_states = (ComputeState.STOPPED, )
|
|
769
|
+
failure_states = (ComputeState.ERROR, )
|
|
857
770
|
status_message = 'polling...'
|
|
858
771
|
attempt = 1
|
|
859
772
|
while time.time() < deadline:
|
|
860
|
-
poll = self.
|
|
861
|
-
status = poll.
|
|
773
|
+
poll = self.get(name=name)
|
|
774
|
+
status = poll.compute_status.state
|
|
862
775
|
status_message = f'current status: {status}'
|
|
863
|
-
if poll.
|
|
864
|
-
status_message = poll.
|
|
776
|
+
if poll.compute_status:
|
|
777
|
+
status_message = poll.compute_status.message
|
|
865
778
|
if status in target_states:
|
|
866
779
|
return poll
|
|
867
780
|
if callback:
|
|
868
781
|
callback(poll)
|
|
869
782
|
if status in failure_states:
|
|
870
|
-
msg = f'failed to reach
|
|
783
|
+
msg = f'failed to reach STOPPED, got {status}: {status_message}'
|
|
871
784
|
raise OperationFailed(msg)
|
|
872
|
-
prefix = f"
|
|
785
|
+
prefix = f"name={name}"
|
|
873
786
|
sleep = attempt
|
|
874
787
|
if sleep > 10:
|
|
875
788
|
# sleep 10s max per attempt
|
|
@@ -879,43 +792,25 @@ class AppsAPI:
|
|
|
879
792
|
attempt += 1
|
|
880
793
|
raise TimeoutError(f'timed out after {timeout}: {status_message}')
|
|
881
794
|
|
|
882
|
-
def create(self,
|
|
883
|
-
name: str,
|
|
884
|
-
*,
|
|
885
|
-
description: Optional[str] = None,
|
|
886
|
-
resources: Optional[List[AppResource]] = None) -> Wait[App]:
|
|
795
|
+
def create(self, *, app: Optional[App] = None) -> Wait[App]:
|
|
887
796
|
"""Create an app.
|
|
888
797
|
|
|
889
798
|
Creates a new app.
|
|
890
799
|
|
|
891
|
-
:param
|
|
892
|
-
The name of the app. The name must contain only lowercase alphanumeric characters and hyphens. It
|
|
893
|
-
must be unique within the workspace.
|
|
894
|
-
:param description: str (optional)
|
|
895
|
-
The description of the app.
|
|
896
|
-
:param resources: List[:class:`AppResource`] (optional)
|
|
897
|
-
Resources for the app.
|
|
800
|
+
:param app: :class:`App` (optional)
|
|
898
801
|
|
|
899
802
|
:returns:
|
|
900
803
|
Long-running operation waiter for :class:`App`.
|
|
901
804
|
See :method:wait_get_app_active for more details.
|
|
902
805
|
"""
|
|
903
|
-
body =
|
|
904
|
-
if description is not None: body['description'] = description
|
|
905
|
-
if name is not None: body['name'] = name
|
|
906
|
-
if resources is not None: body['resources'] = [v.as_dict() for v in resources]
|
|
806
|
+
body = app.as_dict()
|
|
907
807
|
headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
|
|
908
808
|
|
|
909
809
|
op_response = self._api.do('POST', '/api/2.0/apps', body=body, headers=headers)
|
|
910
810
|
return Wait(self.wait_get_app_active, response=App.from_dict(op_response), name=op_response['name'])
|
|
911
811
|
|
|
912
|
-
def create_and_wait(self,
|
|
913
|
-
|
|
914
|
-
*,
|
|
915
|
-
description: Optional[str] = None,
|
|
916
|
-
resources: Optional[List[AppResource]] = None,
|
|
917
|
-
timeout=timedelta(minutes=20)) -> App:
|
|
918
|
-
return self.create(description=description, name=name, resources=resources).result(timeout=timeout)
|
|
812
|
+
def create_and_wait(self, *, app: Optional[App] = None, timeout=timedelta(minutes=20)) -> App:
|
|
813
|
+
return self.create(app=app).result(timeout=timeout)
|
|
919
814
|
|
|
920
815
|
def delete(self, name: str) -> App:
|
|
921
816
|
"""Delete an app.
|
|
@@ -933,37 +828,20 @@ class AppsAPI:
|
|
|
933
828
|
res = self._api.do('DELETE', f'/api/2.0/apps/{name}', headers=headers)
|
|
934
829
|
return App.from_dict(res)
|
|
935
830
|
|
|
936
|
-
def deploy(self,
|
|
937
|
-
app_name: str,
|
|
938
|
-
*,
|
|
939
|
-
deployment_id: Optional[str] = None,
|
|
940
|
-
mode: Optional[AppDeploymentMode] = None,
|
|
941
|
-
source_code_path: Optional[str] = None) -> Wait[AppDeployment]:
|
|
831
|
+
def deploy(self, app_name: str, *, app_deployment: Optional[AppDeployment] = None) -> Wait[AppDeployment]:
|
|
942
832
|
"""Create an app deployment.
|
|
943
833
|
|
|
944
834
|
Creates an app deployment for the app with the supplied name.
|
|
945
835
|
|
|
946
836
|
:param app_name: str
|
|
947
837
|
The name of the app.
|
|
948
|
-
:param
|
|
949
|
-
The unique id of the deployment.
|
|
950
|
-
:param mode: :class:`AppDeploymentMode` (optional)
|
|
951
|
-
The mode of which the deployment will manage the source code.
|
|
952
|
-
:param source_code_path: str (optional)
|
|
953
|
-
The workspace file system path of the source code used to create the app deployment. This is
|
|
954
|
-
different from `deployment_artifacts.source_code_path`, which is the path used by the deployed app.
|
|
955
|
-
The former refers to the original source code location of the app in the workspace during deployment
|
|
956
|
-
creation, whereas the latter provides a system generated stable snapshotted source code path used by
|
|
957
|
-
the deployment.
|
|
838
|
+
:param app_deployment: :class:`AppDeployment` (optional)
|
|
958
839
|
|
|
959
840
|
:returns:
|
|
960
841
|
Long-running operation waiter for :class:`AppDeployment`.
|
|
961
842
|
See :method:wait_get_deployment_app_succeeded for more details.
|
|
962
843
|
"""
|
|
963
|
-
body =
|
|
964
|
-
if deployment_id is not None: body['deployment_id'] = deployment_id
|
|
965
|
-
if mode is not None: body['mode'] = mode.value
|
|
966
|
-
if source_code_path is not None: body['source_code_path'] = source_code_path
|
|
844
|
+
body = app_deployment.as_dict()
|
|
967
845
|
headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
|
|
968
846
|
|
|
969
847
|
op_response = self._api.do('POST',
|
|
@@ -975,18 +853,12 @@ class AppsAPI:
|
|
|
975
853
|
app_name=app_name,
|
|
976
854
|
deployment_id=op_response['deployment_id'])
|
|
977
855
|
|
|
978
|
-
def deploy_and_wait(
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
source_code_path: Optional[str] = None,
|
|
985
|
-
timeout=timedelta(minutes=20)) -> AppDeployment:
|
|
986
|
-
return self.deploy(app_name=app_name,
|
|
987
|
-
deployment_id=deployment_id,
|
|
988
|
-
mode=mode,
|
|
989
|
-
source_code_path=source_code_path).result(timeout=timeout)
|
|
856
|
+
def deploy_and_wait(self,
|
|
857
|
+
app_name: str,
|
|
858
|
+
*,
|
|
859
|
+
app_deployment: Optional[AppDeployment] = None,
|
|
860
|
+
timeout=timedelta(minutes=20)) -> AppDeployment:
|
|
861
|
+
return self.deploy(app_deployment=app_deployment, app_name=app_name).result(timeout=timeout)
|
|
990
862
|
|
|
991
863
|
def get(self, name: str) -> App:
|
|
992
864
|
"""Get an app.
|
|
@@ -1121,7 +993,8 @@ class AppsAPI:
|
|
|
1121
993
|
access_control_list: Optional[List[AppAccessControlRequest]] = None) -> AppPermissions:
|
|
1122
994
|
"""Set app permissions.
|
|
1123
995
|
|
|
1124
|
-
Sets permissions on an
|
|
996
|
+
Sets permissions on an object, replacing existing permissions if they exist. Deletes all direct
|
|
997
|
+
permissions if none are specified. Objects can inherit permissions from their root object.
|
|
1125
998
|
|
|
1126
999
|
:param app_name: str
|
|
1127
1000
|
The app for which to get or manage permissions.
|
|
@@ -1179,11 +1052,7 @@ class AppsAPI:
|
|
|
1179
1052
|
def stop_and_wait(self, name: str, timeout=timedelta(minutes=20)) -> App:
|
|
1180
1053
|
return self.stop(name=name).result(timeout=timeout)
|
|
1181
1054
|
|
|
1182
|
-
def update(self,
|
|
1183
|
-
name: str,
|
|
1184
|
-
*,
|
|
1185
|
-
description: Optional[str] = None,
|
|
1186
|
-
resources: Optional[List[AppResource]] = None) -> App:
|
|
1055
|
+
def update(self, name: str, *, app: Optional[App] = None) -> App:
|
|
1187
1056
|
"""Update an app.
|
|
1188
1057
|
|
|
1189
1058
|
Updates the app with the supplied name.
|
|
@@ -1191,16 +1060,11 @@ class AppsAPI:
|
|
|
1191
1060
|
:param name: str
|
|
1192
1061
|
The name of the app. The name must contain only lowercase alphanumeric characters and hyphens. It
|
|
1193
1062
|
must be unique within the workspace.
|
|
1194
|
-
:param
|
|
1195
|
-
The description of the app.
|
|
1196
|
-
:param resources: List[:class:`AppResource`] (optional)
|
|
1197
|
-
Resources for the app.
|
|
1063
|
+
:param app: :class:`App` (optional)
|
|
1198
1064
|
|
|
1199
1065
|
:returns: :class:`App`
|
|
1200
1066
|
"""
|
|
1201
|
-
body =
|
|
1202
|
-
if description is not None: body['description'] = description
|
|
1203
|
-
if resources is not None: body['resources'] = [v.as_dict() for v in resources]
|
|
1067
|
+
body = app.as_dict()
|
|
1204
1068
|
headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
|
|
1205
1069
|
|
|
1206
1070
|
res = self._api.do('PATCH', f'/api/2.0/apps/{name}', body=body, headers=headers)
|
|
@@ -1121,7 +1121,7 @@ class BudgetsAPI:
|
|
|
1121
1121
|
Gets a budget configuration for an account. Both account and budget configuration are specified by ID.
|
|
1122
1122
|
|
|
1123
1123
|
:param budget_id: str
|
|
1124
|
-
The
|
|
1124
|
+
The budget configuration ID
|
|
1125
1125
|
|
|
1126
1126
|
:returns: :class:`GetBudgetConfigurationResponse`
|
|
1127
1127
|
"""
|