databricks-sdk 0.44.0__tar.gz → 0.44.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.

Potentially problematic release.


This version of databricks-sdk might be problematic. Click here for more details.

Files changed (100) hide show
  1. {databricks-sdk-0.44.0/databricks_sdk.egg-info → databricks-sdk-0.44.1}/PKG-INFO +1 -1
  2. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/credentials_provider.py +71 -16
  3. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/mixins/jobs.py +12 -6
  4. databricks-sdk-0.44.1/databricks/sdk/version.py +1 -0
  5. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1/databricks_sdk.egg-info}/PKG-INFO +1 -1
  6. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_jobs_mixin.py +34 -16
  7. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_model_serving_auth.py +48 -2
  8. databricks-sdk-0.44.0/databricks/sdk/version.py +0 -1
  9. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/LICENSE +0 -0
  10. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/NOTICE +0 -0
  11. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/README.md +0 -0
  12. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/__init__.py +0 -0
  13. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/__init__.py +0 -0
  14. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/_base_client.py +0 -0
  15. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/_property.py +0 -0
  16. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/_widgets/__init__.py +0 -0
  17. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/_widgets/default_widgets_utils.py +0 -0
  18. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/_widgets/ipywidgets_utils.py +0 -0
  19. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/azure.py +0 -0
  20. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/casing.py +0 -0
  21. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/clock.py +0 -0
  22. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/config.py +0 -0
  23. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/core.py +0 -0
  24. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/data_plane.py +0 -0
  25. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/dbutils.py +0 -0
  26. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/environments.py +0 -0
  27. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/errors/__init__.py +0 -0
  28. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/errors/base.py +0 -0
  29. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/errors/customizer.py +0 -0
  30. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/errors/deserializer.py +0 -0
  31. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/errors/mapper.py +0 -0
  32. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/errors/overrides.py +0 -0
  33. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/errors/parser.py +0 -0
  34. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/errors/platform.py +0 -0
  35. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/errors/private_link.py +0 -0
  36. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/errors/sdk.py +0 -0
  37. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/logger/__init__.py +0 -0
  38. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/logger/round_trip_logger.py +0 -0
  39. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/mixins/__init__.py +0 -0
  40. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/mixins/compute.py +0 -0
  41. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/mixins/files.py +0 -0
  42. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/mixins/open_ai_client.py +0 -0
  43. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/mixins/workspace.py +0 -0
  44. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/oauth.py +0 -0
  45. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/py.typed +0 -0
  46. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/retries.py +0 -0
  47. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/runtime/__init__.py +0 -0
  48. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/runtime/dbutils_stub.py +0 -0
  49. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/__init__.py +0 -0
  50. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/_internal.py +0 -0
  51. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/apps.py +0 -0
  52. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/billing.py +0 -0
  53. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/catalog.py +0 -0
  54. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/cleanrooms.py +0 -0
  55. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/compute.py +0 -0
  56. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/dashboards.py +0 -0
  57. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/files.py +0 -0
  58. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/iam.py +0 -0
  59. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/jobs.py +0 -0
  60. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/marketplace.py +0 -0
  61. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/ml.py +0 -0
  62. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/oauth2.py +0 -0
  63. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/pipelines.py +0 -0
  64. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/provisioning.py +0 -0
  65. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/serving.py +0 -0
  66. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/settings.py +0 -0
  67. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/sharing.py +0 -0
  68. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/sql.py +0 -0
  69. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/vectorsearch.py +0 -0
  70. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/service/workspace.py +0 -0
  71. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks/sdk/useragent.py +0 -0
  72. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks_sdk.egg-info/SOURCES.txt +0 -0
  73. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks_sdk.egg-info/dependency_links.txt +0 -0
  74. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks_sdk.egg-info/requires.txt +0 -0
  75. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/databricks_sdk.egg-info/top_level.txt +0 -0
  76. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/setup.cfg +0 -0
  77. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/setup.py +0 -0
  78. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_auth.py +0 -0
  79. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_auth_manual_tests.py +0 -0
  80. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_base_client.py +0 -0
  81. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_client.py +0 -0
  82. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_compute_mixins.py +0 -0
  83. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_config.py +0 -0
  84. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_core.py +0 -0
  85. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_credentials_provider.py +0 -0
  86. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_data_plane.py +0 -0
  87. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_dbfs_mixins.py +0 -0
  88. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_dbutils.py +0 -0
  89. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_environments.py +0 -0
  90. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_errors.py +0 -0
  91. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_files.py +0 -0
  92. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_init_file.py +0 -0
  93. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_internal.py +0 -0
  94. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_jobs.py +0 -0
  95. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_metadata_service_auth.py +0 -0
  96. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_misc.py +0 -0
  97. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_oauth.py +0 -0
  98. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_open_ai_mixin.py +0 -0
  99. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_retries.py +0 -0
  100. {databricks-sdk-0.44.0 → databricks-sdk-0.44.1}/tests/test_user_agent.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: databricks-sdk
3
- Version: 0.44.0
3
+ Version: 0.44.1
4
4
  Summary: Databricks SDK for Python (Beta)
5
5
  Home-page: https://databricks-sdk-py.readthedocs.io
6
6
  Author: Serge Smertin
@@ -9,6 +9,7 @@ import pathlib
9
9
  import platform
10
10
  import subprocess
11
11
  import sys
12
+ import threading
12
13
  import time
13
14
  from datetime import datetime
14
15
  from typing import Callable, Dict, List, Optional, Tuple, Union
@@ -723,14 +724,17 @@ def metadata_service(cfg: 'Config') -> Optional[CredentialsProvider]:
723
724
  # This Code is derived from Mlflow DatabricksModelServingConfigProvider
724
725
  # https://github.com/mlflow/mlflow/blob/1219e3ef1aac7d337a618a352cd859b336cf5c81/mlflow/legacy_databricks_cli/configure/provider.py#L332
725
726
  class ModelServingAuthProvider():
727
+ USER_CREDENTIALS = "user_credentials"
728
+
726
729
  _MODEL_DEPENDENCY_OAUTH_TOKEN_FILE_PATH = "/var/credentials-secret/model-dependencies-oauth-token"
727
730
 
728
- def __init__(self):
731
+ def __init__(self, credential_type: Optional[str]):
729
732
  self.expiry_time = -1
730
733
  self.current_token = None
731
734
  self.refresh_duration = 300 # 300 Seconds
735
+ self.credential_type = credential_type
732
736
 
733
- def should_fetch_model_serving_environment_oauth(self) -> bool:
737
+ def should_fetch_model_serving_environment_oauth() -> bool:
734
738
  """
735
739
  Check whether this is the model serving environment
736
740
  Additionally check if the oauth token file path exists
@@ -739,15 +743,15 @@ class ModelServingAuthProvider():
739
743
  is_in_model_serving_env = (os.environ.get("IS_IN_DB_MODEL_SERVING_ENV")
740
744
  or os.environ.get("IS_IN_DATABRICKS_MODEL_SERVING_ENV") or "false")
741
745
  return (is_in_model_serving_env == "true"
742
- and os.path.isfile(self._MODEL_DEPENDENCY_OAUTH_TOKEN_FILE_PATH))
746
+ and os.path.isfile(ModelServingAuthProvider._MODEL_DEPENDENCY_OAUTH_TOKEN_FILE_PATH))
743
747
 
744
- def get_model_dependency_oauth_token(self, should_retry=True) -> str:
748
+ def _get_model_dependency_oauth_token(self, should_retry=True) -> str:
745
749
  # Use Cached value if it is valid
746
750
  if self.current_token is not None and self.expiry_time > time.time():
747
751
  return self.current_token
748
752
 
749
753
  try:
750
- with open(self._MODEL_DEPENDENCY_OAUTH_TOKEN_FILE_PATH) as f:
754
+ with open(ModelServingAuthProvider._MODEL_DEPENDENCY_OAUTH_TOKEN_FILE_PATH) as f:
751
755
  oauth_dict = json.load(f)
752
756
  self.current_token = oauth_dict["OAUTH_TOKEN"][0]["oauthTokenValue"]
753
757
  self.expiry_time = time.time() + self.refresh_duration
@@ -757,32 +761,43 @@ class ModelServingAuthProvider():
757
761
  logger.warning("Unable to read oauth token on first attmept in Model Serving Environment",
758
762
  exc_info=e)
759
763
  time.sleep(0.5)
760
- return self.get_model_dependency_oauth_token(should_retry=False)
764
+ return self._get_model_dependency_oauth_token(should_retry=False)
761
765
  else:
762
766
  raise RuntimeError(
763
767
  "Unable to read OAuth credentials from the file mounted in Databricks Model Serving"
764
768
  ) from e
765
769
  return self.current_token
766
770
 
771
+ def _get_invokers_token(self):
772
+ current_thread = threading.current_thread()
773
+ thread_data = current_thread.__dict__
774
+ invokers_token = None
775
+ if "invokers_token" in thread_data:
776
+ invokers_token = thread_data["invokers_token"]
777
+
778
+ if invokers_token is None:
779
+ raise RuntimeError("Unable to read Invokers Token in Databricks Model Serving")
780
+
781
+ return invokers_token
782
+
767
783
  def get_databricks_host_token(self) -> Optional[Tuple[str, str]]:
768
- if not self.should_fetch_model_serving_environment_oauth():
784
+ if not ModelServingAuthProvider.should_fetch_model_serving_environment_oauth():
769
785
  return None
770
786
 
771
787
  # read from DB_MODEL_SERVING_HOST_ENV_VAR if available otherwise MODEL_SERVING_HOST_ENV_VAR
772
788
  host = os.environ.get("DATABRICKS_MODEL_SERVING_HOST_URL") or os.environ.get(
773
789
  "DB_MODEL_SERVING_HOST_URL")
774
- token = self.get_model_dependency_oauth_token()
775
790
 
776
- return (host, token)
791
+ if self.credential_type == ModelServingAuthProvider.USER_CREDENTIALS:
792
+ return (host, self._get_invokers_token())
793
+ else:
794
+ return (host, self._get_model_dependency_oauth_token())
777
795
 
778
796
 
779
- @credentials_strategy('model-serving', [])
780
- def model_serving_auth(cfg: 'Config') -> Optional[CredentialsProvider]:
797
+ def model_serving_auth_visitor(cfg: 'Config',
798
+ credential_type: Optional[str] = None) -> Optional[CredentialsProvider]:
781
799
  try:
782
- model_serving_auth_provider = ModelServingAuthProvider()
783
- if not model_serving_auth_provider.should_fetch_model_serving_environment_oauth():
784
- logger.debug("model-serving: Not in Databricks Model Serving, skipping")
785
- return None
800
+ model_serving_auth_provider = ModelServingAuthProvider(credential_type)
786
801
  host, token = model_serving_auth_provider.get_databricks_host_token()
787
802
  if token is None:
788
803
  raise ValueError(
@@ -793,7 +808,6 @@ def model_serving_auth(cfg: 'Config') -> Optional[CredentialsProvider]:
793
808
  except Exception as e:
794
809
  logger.warning("Unable to get auth from Databricks Model Serving Environment", exc_info=e)
795
810
  return None
796
-
797
811
  logger.info("Using Databricks Model Serving Authentication")
798
812
 
799
813
  def inner() -> Dict[str, str]:
@@ -804,6 +818,15 @@ def model_serving_auth(cfg: 'Config') -> Optional[CredentialsProvider]:
804
818
  return inner
805
819
 
806
820
 
821
+ @credentials_strategy('model-serving', [])
822
+ def model_serving_auth(cfg: 'Config') -> Optional[CredentialsProvider]:
823
+ if not ModelServingAuthProvider.should_fetch_model_serving_environment_oauth():
824
+ logger.debug("model-serving: Not in Databricks Model Serving, skipping")
825
+ return None
826
+
827
+ return model_serving_auth_visitor(cfg)
828
+
829
+
807
830
  class DefaultCredentials:
808
831
  """ Select the first applicable credential provider from the chain """
809
832
 
@@ -846,3 +869,35 @@ class DefaultCredentials:
846
869
  raise ValueError(
847
870
  f'cannot configure default credentials, please check {auth_flow_url} to configure credentials for your preferred authentication method.'
848
871
  )
872
+
873
+
874
+ class ModelServingUserCredentials(CredentialsStrategy):
875
+ """
876
+ This credential strategy is designed for authenticating the Databricks SDK in the model serving environment using user-specific rights.
877
+ In the model serving environment, the strategy retrieves a downscoped user token from the thread-local variable.
878
+ In any other environments, the class defaults to the DefaultCredentialStrategy.
879
+ To use this credential strategy, instantiate the WorkspaceClient with the ModelServingUserCredentials strategy as follows:
880
+
881
+ invokers_client = WorkspaceClient(credential_strategy = ModelServingUserCredentials())
882
+ """
883
+
884
+ def __init__(self):
885
+ self.credential_type = ModelServingAuthProvider.USER_CREDENTIALS
886
+ self.default_credentials = DefaultCredentials()
887
+
888
+ def auth_type(self):
889
+ if ModelServingAuthProvider.should_fetch_model_serving_environment_oauth():
890
+ return "model_serving_" + self.credential_type
891
+ else:
892
+ return self.default_credentials.auth_type()
893
+
894
+ def __call__(self, cfg: 'Config') -> CredentialsProvider:
895
+ if ModelServingAuthProvider.should_fetch_model_serving_environment_oauth():
896
+ header_factory = model_serving_auth_visitor(cfg, self.credential_type)
897
+ if not header_factory:
898
+ raise ValueError(
899
+ f"Unable to authenticate using {self.credential_type} in Databricks Model Serving Environment"
900
+ )
901
+ return header_factory
902
+ else:
903
+ return self.default_credentials(cfg)
@@ -11,9 +11,10 @@ class JobsExt(jobs.JobsAPI):
11
11
  include_history: Optional[bool] = None,
12
12
  include_resolved_values: Optional[bool] = None,
13
13
  page_token: Optional[str] = None) -> jobs.Run:
14
- """
15
- This method fetches the details of a run identified by `run_id`. If the run has multiple pages of tasks or iterations,
16
- it will paginate through all pages and aggregate the results.
14
+ """Get a single job run.
15
+
16
+ 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.
17
+
17
18
  :param run_id: int
18
19
  The canonical identifier of the run for which to retrieve the metadata. This field is required.
19
20
  :param include_history: bool (optional)
@@ -21,8 +22,9 @@ class JobsExt(jobs.JobsAPI):
21
22
  :param include_resolved_values: bool (optional)
22
23
  Whether to include resolved parameter values in the response.
23
24
  :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.
25
+ To list the next page of job tasks, set this field to the value of the `next_page_token` returned in
26
+ the GetJob response.
27
+
26
28
  :returns: :class:`Run`
27
29
  """
28
30
  run = super().get_run(run_id,
@@ -34,6 +36,7 @@ class JobsExt(jobs.JobsAPI):
34
36
  # 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
37
  is_paginating_iterations = run.iterations is not None and len(run.iterations) > 0
36
38
 
39
+ # runs/get response includes next_page_token as long as there are more pages to fetch.
37
40
  while run.next_page_token is not None:
38
41
  next_run = super().get_run(run_id,
39
42
  include_history=include_history,
@@ -43,7 +46,10 @@ class JobsExt(jobs.JobsAPI):
43
46
  run.iterations.extend(next_run.iterations)
44
47
  else:
45
48
  run.tasks.extend(next_run.tasks)
49
+ # Each new page of runs/get response includes the next page of the job_clusters, job_parameters, and repair history.
50
+ run.job_clusters.extend(next_run.job_clusters)
51
+ run.job_parameters.extend(next_run.job_parameters)
52
+ run.repair_history.extend(next_run.repair_history)
46
53
  run.next_page_token = next_run.next_page_token
47
54
 
48
- run.prev_page_token = None
49
55
  return run
@@ -0,0 +1 @@
1
+ __version__ = '0.44.1'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: databricks-sdk
3
- Version: 0.44.0
3
+ Version: 0.44.1
4
4
  Summary: Databricks SDK for Python (Beta)
5
5
  Home-page: https://databricks-sdk-py.readthedocs.io
6
6
  Author: Serge Smertin
@@ -22,14 +22,28 @@ def test_get_run_with_no_pagination(config, requests_mock):
22
22
 
23
23
 
24
24
  def test_get_run_pagination_with_tasks(config, requests_mock):
25
+ from databricks.sdk.service import compute, jobs
26
+ cluster_spec = compute.ClusterSpec(spark_version="11.3.x-scala2.12",
27
+ custom_tags={"ResourceClass": "SingleNode"},
28
+ num_workers=0,
29
+ node_type_id="Standard_DS3_v2",
30
+ )
31
+ cluster1 = jobs.JobCluster(job_cluster_key="cluster1", new_cluster=cluster_spec)
32
+ cluster2 = jobs.JobCluster(job_cluster_key="cluster2", new_cluster=cluster_spec)
33
+ cluster3 = jobs.JobCluster(job_cluster_key="cluster3", new_cluster=cluster_spec)
34
+ cluster4 = jobs.JobCluster(job_cluster_key="cluster4", new_cluster=cluster_spec)
25
35
  run1 = {
26
36
  "tasks": [{
27
37
  "run_id": 0
28
38
  }, {
29
39
  "run_id": 1
30
40
  }],
41
+ "job_clusters": [cluster1.as_dict(), cluster2.as_dict(), ],
42
+ "job_parameters": [{
43
+ "name": "param1",
44
+ "value": "value1"
45
+ }],
31
46
  "next_page_token": "tokenToSecondPage",
32
- "prev_page_token": "tokenToPreviousPage"
33
47
  }
34
48
  run2 = {
35
49
  "tasks": [{
@@ -37,10 +51,14 @@ def test_get_run_pagination_with_tasks(config, requests_mock):
37
51
  }, {
38
52
  "run_id": 3
39
53
  }],
54
+ "job_clusters": [cluster3.as_dict(), cluster4.as_dict(), ],
55
+ "job_parameters": [{
56
+ "name": "param2",
57
+ "value": "value2"
58
+ }],
40
59
  "next_page_token": "tokenToThirdPage",
41
- "prev_page_token": "initialToken"
42
60
  }
43
- run3 = {"tasks": [{"run_id": 4}], "next_page_token": None, "prev_page_token": "tokenToSecondPage"}
61
+ run3 = {"tasks": [{"run_id": 4}]}
44
62
  requests_mock.get(make_path_pattern(1337, "initialToken"), text=json.dumps(run1))
45
63
  requests_mock.get(make_path_pattern(1337, "tokenToSecondPage"), text=json.dumps(run2))
46
64
  requests_mock.get(make_path_pattern(1337, "tokenToThirdPage"), text=json.dumps(run3))
@@ -60,6 +78,17 @@ def test_get_run_pagination_with_tasks(config, requests_mock):
60
78
  }, {
61
79
  'run_id': 4
62
80
  }],
81
+ "job_clusters": [cluster1.as_dict(),
82
+ cluster2.as_dict(),
83
+ cluster3.as_dict(),
84
+ cluster4.as_dict()],
85
+ "job_parameters": [{
86
+ "name": "param1",
87
+ "value": "value1"
88
+ }, {
89
+ "name": "param2",
90
+ "value": "value2"
91
+ }],
63
92
  }
64
93
 
65
94
 
@@ -74,7 +103,6 @@ def test_get_run_pagination_with_iterations(config, requests_mock):
74
103
  "run_id": 1
75
104
  }],
76
105
  "next_page_token": "tokenToSecondPage",
77
- "prev_page_token": "tokenToPreviousPage"
78
106
  }
79
107
  run2 = {
80
108
  "tasks": [{
@@ -86,18 +114,8 @@ def test_get_run_pagination_with_iterations(config, requests_mock):
86
114
  "run_id": 3
87
115
  }],
88
116
  "next_page_token": "tokenToThirdPage",
89
- "prev_page_token": "initialToken"
90
- }
91
- run3 = {
92
- "tasks": [{
93
- "run_id": 1337
94
- }],
95
- "iterations": [{
96
- "run_id": 4
97
- }],
98
- "next_page_token": None,
99
- "prev_page_token": "tokenToSecondPage"
100
117
  }
118
+ run3 = {"tasks": [{"run_id": 1337}], "iterations": [{"run_id": 4}], }
101
119
  requests_mock.get(make_path_pattern(1337, "initialToken"), text=json.dumps(run1))
102
120
  requests_mock.get(make_path_pattern(1337, "tokenToSecondPage"), text=json.dumps(run2))
103
121
  requests_mock.get(make_path_pattern(1337, "tokenToThirdPage"), text=json.dumps(run3))
@@ -120,4 +138,4 @@ def test_get_run_pagination_with_iterations(config, requests_mock):
120
138
  }, {
121
139
  'run_id': 4
122
140
  }],
123
- }
141
+ }
@@ -1,8 +1,10 @@
1
+ import threading
1
2
  import time
2
3
 
3
4
  import pytest
4
5
 
5
6
  from databricks.sdk.core import Config
7
+ from databricks.sdk.credentials_provider import ModelServingUserCredentials
6
8
 
7
9
  from .conftest import raises
8
10
 
@@ -39,7 +41,6 @@ def test_model_serving_auth(env_values, del_env_values, oauth_file_name, monkeyp
39
41
  mocker.patch('databricks.sdk.config.Config._known_file_config_loader')
40
42
 
41
43
  cfg = Config()
42
-
43
44
  assert cfg.auth_type == 'model-serving'
44
45
  headers = cfg.authenticate()
45
46
  assert (cfg.host == 'x')
@@ -93,7 +94,6 @@ def test_model_serving_auth_refresh(monkeypatch, mocker):
93
94
  assert (cfg.host == 'x')
94
95
  assert headers.get(
95
96
  "Authorization") == 'Bearer databricks_sdk_unit_test_token' # Token defined in the test file
96
-
97
97
  # Simulate refreshing the token by patching to to a new file
98
98
  monkeypatch.setattr(
99
99
  "databricks.sdk.credentials_provider.ModelServingAuthProvider._MODEL_DEPENDENCY_OAUTH_TOKEN_FILE_PATH",
@@ -113,3 +113,49 @@ def test_model_serving_auth_refresh(monkeypatch, mocker):
113
113
  assert (cfg.host == 'x')
114
114
  # Read V2 now
115
115
  assert headers.get("Authorization") == 'Bearer databricks_sdk_unit_test_token_v2'
116
+
117
+
118
+ def test_agent_user_credentials(monkeypatch, mocker):
119
+ monkeypatch.setenv('IS_IN_DB_MODEL_SERVING_ENV', 'true')
120
+ monkeypatch.setenv('DB_MODEL_SERVING_HOST_URL', 'x')
121
+ monkeypatch.setattr(
122
+ "databricks.sdk.credentials_provider.ModelServingAuthProvider._MODEL_DEPENDENCY_OAUTH_TOKEN_FILE_PATH",
123
+ "tests/testdata/model-serving-test-token")
124
+
125
+ invokers_token_val = "databricks_invokers_token"
126
+ current_thread = threading.current_thread()
127
+ thread_data = current_thread.__dict__
128
+ thread_data["invokers_token"] = invokers_token_val
129
+
130
+ cfg = Config(credentials_strategy=ModelServingUserCredentials())
131
+ assert cfg.auth_type == 'model_serving_user_credentials'
132
+
133
+ headers = cfg.authenticate()
134
+
135
+ assert (cfg.host == 'x')
136
+ assert headers.get("Authorization") == f'Bearer {invokers_token_val}'
137
+
138
+ # Test updates of invokers token
139
+ invokers_token_val = "databricks_invokers_token_v2"
140
+ current_thread = threading.current_thread()
141
+ thread_data = current_thread.__dict__
142
+ thread_data["invokers_token"] = invokers_token_val
143
+
144
+ headers = cfg.authenticate()
145
+ assert (cfg.host == 'x')
146
+ assert headers.get("Authorization") == f'Bearer {invokers_token_val}'
147
+
148
+
149
+ # If this credential strategy is being used in a non model serving environments then use default credential strategy instead
150
+ def test_agent_user_credentials_in_non_model_serving_environments(monkeypatch):
151
+
152
+ monkeypatch.setenv('DATABRICKS_HOST', 'x')
153
+ monkeypatch.setenv('DATABRICKS_TOKEN', 'token')
154
+
155
+ cfg = Config(credentials_strategy=ModelServingUserCredentials())
156
+ assert cfg.auth_type == 'pat' # Auth type is PAT as it is no longer in a model serving environment
157
+
158
+ headers = cfg.authenticate()
159
+
160
+ assert (cfg.host == 'https://x')
161
+ assert headers.get("Authorization") == f'Bearer token'
@@ -1 +0,0 @@
1
- __version__ = '0.44.0'
File without changes
File without changes