tobiko-cloud-api-client 202508.58.0__py3-none-any.whl → 202508.60.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tobiko-cloud-api-client
3
- Version: 202508.58.0
3
+ Version: 202508.60.0
4
4
  Author: TobikoData Inc.
5
5
  Author-email: engineering@tobikodata.com
6
6
  Requires-Python: <3.13,>=3.9
@@ -10,4 +10,4 @@ Requires-Dist: pydantic>=2.0.0
10
10
  Requires-Dist: rich[jupyter]
11
11
  Requires-Dist: ruamel.yaml
12
12
  Requires-Dist: tenacity
13
- Requires-Dist: tobiko-cloud-helpers==202508.58.0
13
+ Requires-Dist: tobiko-cloud-helpers==202508.60.0
@@ -1,14 +1,14 @@
1
1
  tobikodata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  tobikodata/http_client/__init__.py,sha256=0vzfsVlDAfzAktEsvzRnsMYy3OpkzAeY6dQoe5tW6oA,457
3
3
  tobikodata/http_client/api.py,sha256=J8W2IuKs7i7hbW3gWinWpCFnnPGwOszeUz3J3Bt41_o,8130
4
- tobikodata/http_client/auth.py,sha256=XP6jYsK58fM-gvCFT66_1z-MFMcKcdZe9mAKRVBArrQ,7112
4
+ tobikodata/http_client/auth.py,sha256=AjT3HDO-Q9DZEzpyc5q3ASY-nOpC2Tc5fbNCFV4oMNk,8027
5
5
  tobikodata/http_client/public.py,sha256=rs_E5RurQlKT-DfuqGX7W5rJQA2Q3MkeWS6hSC0bFbI,17554
6
6
  tobikodata/http_client/api_models/v1/common.py,sha256=T79ytQywoyLAr157Hbiae3neCV52bm8Ny1i8S8nDzkE,418
7
7
  tobikodata/http_client/api_models/v1/dags.py,sha256=np7OeHQ9Vhdo1JqOsD4el3OTUdz-P5L7vYJEGrp3k8U,893
8
8
  tobikodata/http_client/api_models/v1/evaluations.py,sha256=Oa_BUxPt61jMpiz0JgUzpTvulU7yK08SC7AQjb3LqzY,1164
9
9
  tobikodata/http_client/api_models/v1/runs.py,sha256=F2kGhwRTYxSYS5NSJfDSvyNM0y4NIVHL1ONgM3MnD7w,444
10
- tobiko_cloud_api_client-202508.58.0.dist-info/METADATA,sha256=H_4x03y4kxWBQU9C5Of1GUAvSEQkx8VqBeHrmSCi18w,371
11
- tobiko_cloud_api_client-202508.58.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
12
- tobiko_cloud_api_client-202508.58.0.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
13
- tobiko_cloud_api_client-202508.58.0.dist-info/top_level.txt,sha256=RtGY-jz-WpCF6_ox51-oVGzCMZ7v9RHTWLreUe86rUY,11
14
- tobiko_cloud_api_client-202508.58.0.dist-info/RECORD,,
10
+ tobiko_cloud_api_client-202508.60.0.dist-info/METADATA,sha256=4a9gBi8LY1KHTI5bpXIh0_PoHxiGXHAjdPhd0TzPjdw,371
11
+ tobiko_cloud_api_client-202508.60.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
12
+ tobiko_cloud_api_client-202508.60.0.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
13
+ tobiko_cloud_api_client-202508.60.0.dist-info/top_level.txt,sha256=RtGY-jz-WpCF6_ox51-oVGzCMZ7v9RHTWLreUe86rUY,11
14
+ tobiko_cloud_api_client-202508.60.0.dist-info/RECORD,,
@@ -25,14 +25,20 @@ yaml = YAML()
25
25
 
26
26
  # This is duplicated from tcloud in order to avoid pulling in tcloud deps into
27
27
  # http client
28
+ SCOPE = os.environ.get("TCLOUD_SCOPE", "tbk:scope:projects")
29
+ """The scopes to request from the tobiko auth service"""
30
+
28
31
  TCLOUD_PATH = Path(os.environ.get("TCLOUD_HOME", Path.home() / ".tcloud"))
29
32
  """The location of the tcloud config folder"""
30
33
 
31
- CLIENT_ID = "f695a000-bc5b-43c2-bcb7-8e0179ddff0c"
32
- """The oauth client ID to use"""
34
+ CLIENT_ID = os.environ.get("TCLOUD_CLIENT_ID", "f695a000-bc5b-43c2-bcb7-8e0179ddff0c")
35
+ """The OAuth client ID to use"""
36
+
37
+ CLIENT_SECRET = os.environ.get("TCLOUD_CLIENT_SECRET")
38
+ """The OAuth client secret to use for the client credentials (service-to-service) flow"""
33
39
 
34
- TOKEN_URL = "https://cloud.tobikodata.com/auth/token"
35
- """The oauth token endpoint to use"""
40
+ TOKEN_URL = os.environ.get("TCLOUD_TOKEN_URL", "https://cloud.tobikodata.com/auth/token")
41
+ """The OAuth token endpoint to use"""
36
42
 
37
43
  THEME = Theme(
38
44
  {
@@ -100,7 +106,7 @@ class SSOAuth:
100
106
 
101
107
  def __init__(self) -> None:
102
108
  self.console = Console(theme=THEME)
103
- self.session = OAuth2Session(CLIENT_ID)
109
+ self.session = OAuth2Session(CLIENT_ID, CLIENT_SECRET, scope=SCOPE)
104
110
  self.tokenInfo = SSOAuth._load_auth_yaml()
105
111
 
106
112
  def id_token(self) -> t.Optional[str]:
@@ -131,9 +137,24 @@ class SSOAuth:
131
137
  # We failed to refresh, logout
132
138
  SSOAuth._delete_auth_yaml()
133
139
 
140
+ # Can we use client credentials?
141
+ if CLIENT_SECRET:
142
+ return self.login_with_client_credentials()
143
+
134
144
  return None
135
145
 
146
+ def login_with_client_credentials(self) -> t.Optional[str]:
147
+ self.session.fetch_token(
148
+ TOKEN_URL,
149
+ grant_type="client_credentials",
150
+ )
151
+ return self._create_token_info(self.session.token)["id_token"]
152
+
136
153
  def refresh_token(self) -> t.Optional[str]:
154
+ # Can we use client credentials?
155
+ if CLIENT_SECRET:
156
+ return self.login_with_client_credentials()
157
+
137
158
  if not self.tokenInfo:
138
159
  self.console.print("Not currently authenticated", style="error")
139
160
  return None
@@ -159,10 +180,12 @@ class SSOAuth:
159
180
  "token_type": token["token_type"],
160
181
  "expires_at": token["expires_at"],
161
182
  "access_token": token["access_token"],
162
- "refresh_token": token["refresh_token"],
163
183
  "id_token": token["id_token"],
164
184
  }
165
185
 
186
+ if "refresh_token" in token:
187
+ self.tokenInfo["refresh_token"] = token["refresh_token"]
188
+
166
189
  SSOAuth._save_auth_yaml(self.tokenInfo)
167
190
 
168
191
  return self.tokenInfo