dnastack-client-library 3.1.207__py3-none-any.whl → 3.1.209__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.
- dnastack/constants.py +1 -1
- dnastack/http/authenticators/oauth2.py +11 -11
- dnastack/http/authenticators/oauth2_adapter/cloud_providers.py +42 -0
- {dnastack_client_library-3.1.207.dist-info → dnastack_client_library-3.1.209.dist-info}/METADATA +2 -1
- {dnastack_client_library-3.1.207.dist-info → dnastack_client_library-3.1.209.dist-info}/RECORD +9 -9
- {dnastack_client_library-3.1.207.dist-info → dnastack_client_library-3.1.209.dist-info}/WHEEL +1 -1
- {dnastack_client_library-3.1.207.dist-info → dnastack_client_library-3.1.209.dist-info}/entry_points.txt +0 -0
- {dnastack_client_library-3.1.207.dist-info → dnastack_client_library-3.1.209.dist-info}/licenses/LICENSE +0 -0
- {dnastack_client_library-3.1.207.dist-info → dnastack_client_library-3.1.209.dist-info}/top_level.txt +0 -0
dnastack/constants.py
CHANGED
|
@@ -255,16 +255,12 @@ class OAuth2Authenticator(Authenticator):
|
|
|
255
255
|
except JSONDecodeError:
|
|
256
256
|
error_msg = refresh_token_res.text
|
|
257
257
|
|
|
258
|
-
# Handle
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
if not reauthentication_required:
|
|
266
|
-
event_details['reason'] = 'Invalid state while refreshing tokens'
|
|
267
|
-
self.events.dispatch('refresh-failure', event_details)
|
|
258
|
+
# Handle token refresh failure based on HTTP status.
|
|
259
|
+
# 400/401 = the refresh token is invalid (expired, revoked, key rotated, etc.)
|
|
260
|
+
# -> prompt the user to re-authenticate
|
|
261
|
+
# 5xx = transient server error, re-login won't help
|
|
262
|
+
# -> raise InvalidStateError
|
|
263
|
+
reauthentication_required = refresh_token_res.status_code in (400, 401)
|
|
268
264
|
|
|
269
265
|
exception_details = {
|
|
270
266
|
'debug_mode': currently_in_debug_mode(),
|
|
@@ -285,8 +281,12 @@ class OAuth2Authenticator(Authenticator):
|
|
|
285
281
|
}
|
|
286
282
|
|
|
287
283
|
if reauthentication_required:
|
|
288
|
-
|
|
284
|
+
logger.warning(f'Refresh token rejected by server (HTTP {refresh_token_res.status_code}): {error_msg}')
|
|
285
|
+
raise ReauthenticationRequired(f'Refresh token rejected: {error_msg}')
|
|
289
286
|
else:
|
|
287
|
+
event_details['reason'] = 'Invalid state while refreshing tokens'
|
|
288
|
+
self.events.dispatch('refresh-failure', event_details)
|
|
289
|
+
|
|
290
290
|
raise InvalidStateError('Unable to refresh the access token',
|
|
291
291
|
details=exception_details)
|
|
292
292
|
finally:
|
|
@@ -4,12 +4,15 @@ from enum import Enum
|
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
5
5
|
import logging
|
|
6
6
|
|
|
7
|
+
import boto3
|
|
8
|
+
|
|
7
9
|
from dnastack.common.tracing import Span
|
|
8
10
|
from dnastack.http.client_factory import HttpClientFactory
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class CloudProvider(str, Enum):
|
|
12
14
|
GCP = "gcp"
|
|
15
|
+
AWS = "aws"
|
|
13
16
|
|
|
14
17
|
|
|
15
18
|
class CloudMetadataProvider(ABC):
|
|
@@ -89,6 +92,44 @@ class GCPMetadataProvider(CloudMetadataProvider):
|
|
|
89
92
|
return None
|
|
90
93
|
|
|
91
94
|
|
|
95
|
+
class AWSMetadataProvider(CloudMetadataProvider):
|
|
96
|
+
"""Amazon Web Services metadata provider using STS GetWebIdentityToken."""
|
|
97
|
+
|
|
98
|
+
def __init__(self, timeout: int = 5):
|
|
99
|
+
super().__init__(timeout)
|
|
100
|
+
self._session: Optional[boto3.Session] = None
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def name(self) -> str:
|
|
104
|
+
return CloudProvider.AWS.value
|
|
105
|
+
|
|
106
|
+
def is_available(self) -> bool:
|
|
107
|
+
"""Check if AWS credentials are available."""
|
|
108
|
+
try:
|
|
109
|
+
self._session = boto3.Session()
|
|
110
|
+
credentials = self._session.get_credentials()
|
|
111
|
+
return credentials is not None
|
|
112
|
+
except Exception:
|
|
113
|
+
return False
|
|
114
|
+
|
|
115
|
+
def get_identity_token(self, audience: str, trace_context: Span) -> Optional[str]:
|
|
116
|
+
"""Fetch AWS identity token from STS GetWebIdentityToken."""
|
|
117
|
+
try:
|
|
118
|
+
if self._session is None:
|
|
119
|
+
self._session = boto3.Session()
|
|
120
|
+
|
|
121
|
+
sts_client = self._session.client('sts')
|
|
122
|
+
response = sts_client.get_web_identity_token(Audience=[audience])
|
|
123
|
+
token = response.get('WebIdentityToken')
|
|
124
|
+
if token:
|
|
125
|
+
self._logger.debug(f'Successfully fetched AWS identity token for audience: {audience}')
|
|
126
|
+
return token
|
|
127
|
+
|
|
128
|
+
except Exception as e:
|
|
129
|
+
self._logger.warning(f'Failed to fetch AWS identity token: {e}')
|
|
130
|
+
return None
|
|
131
|
+
|
|
132
|
+
|
|
92
133
|
class CloudMetadataConfig(BaseModel):
|
|
93
134
|
"""Configuration model for cloud metadata provider."""
|
|
94
135
|
timeout: int = Field(5, ge=1, le=30, description="Timeout for metadata service request (1-30 seconds).")
|
|
@@ -98,6 +139,7 @@ class CloudProviderFactory:
|
|
|
98
139
|
"""Factory for creating cloud metadata providers."""
|
|
99
140
|
_providers = {
|
|
100
141
|
CloudProvider.GCP: GCPMetadataProvider,
|
|
142
|
+
CloudProvider.AWS: AWSMetadataProvider,
|
|
101
143
|
}
|
|
102
144
|
|
|
103
145
|
@classmethod
|
{dnastack_client_library-3.1.207.dist-info → dnastack_client_library-3.1.209.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dnastack-client-library
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.209
|
|
4
4
|
Summary: DNAstack's GA4GH library and CLI
|
|
5
5
|
Author-email: DNAstack <devs@dnastack.com>
|
|
6
6
|
License: Apache License, Version 2.0
|
|
@@ -36,6 +36,7 @@ Requires-Dist: python-dotenv
|
|
|
36
36
|
Requires-Dist: pip>=21.3.1
|
|
37
37
|
Requires-Dist: packaging>=21.3
|
|
38
38
|
Requires-Dist: selenium>=4.1.0
|
|
39
|
+
Requires-Dist: boto3>=1.42.30
|
|
39
40
|
Provides-Extra: test
|
|
40
41
|
Requires-Dist: selenium>=3.141.0; extra == "test"
|
|
41
42
|
Requires-Dist: pyjwt>=2.1.0; extra == "test"
|
{dnastack_client_library-3.1.207.dist-info → dnastack_client_library-3.1.209.dist-info}/RECORD
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
dnastack/__init__.py,sha256=mslf7se8vBSK_HkqWTGPdibeVhT4xyKXgzQBV7dEK1M,333
|
|
2
2
|
dnastack/__main__.py,sha256=EKmtIs4TBseQJi-OT_U6LqRyKLiyrGTBuTQg9zE-G2I,4376
|
|
3
|
-
dnastack/constants.py,sha256=
|
|
3
|
+
dnastack/constants.py,sha256=Cfd54tZ7BhkWKBRgpXZi0KUD7b5Kxn89WjwHArZw5nc,113
|
|
4
4
|
dnastack/feature_flags.py,sha256=UMNDB07R_ep6Fx3iClhzwOpkWfyYnb418FpoJo50CGs,1411
|
|
5
5
|
dnastack/json_path.py,sha256=TyghhDf7nGQmnsUWBhenU_fKsE_Ez-HLVER6HgH5-hU,2700
|
|
6
6
|
dnastack/omics_cli.py,sha256=ZppKZTHv_XjUUZyRIzSkx0Ug5ODAYrCOTsU0ezCOVrA,3694
|
|
@@ -189,18 +189,18 @@ dnastack/http/authenticators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
|
|
|
189
189
|
dnastack/http/authenticators/abstract.py,sha256=Q74LnZwsMKs5TfGI_4oZtXBCpgJKkkimkv_Y8YPHuoM,9246
|
|
190
190
|
dnastack/http/authenticators/constants.py,sha256=mSpBnm5lMMmMJwr13KIfCoOXXJLP4qGDkFprYXALu8o,1278
|
|
191
191
|
dnastack/http/authenticators/factory.py,sha256=zjV5xMZKlkKqUHA2QDXmut-2HxTnqAz8vwxTBEkMg60,2627
|
|
192
|
-
dnastack/http/authenticators/oauth2.py,sha256=
|
|
192
|
+
dnastack/http/authenticators/oauth2.py,sha256=6shpSY9v7Ccs6Iy4GjWgx22uq9r_wkEg3z4xeWlHlxE,20298
|
|
193
193
|
dnastack/http/authenticators/oauth2_adapter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
194
194
|
dnastack/http/authenticators/oauth2_adapter/abstract.py,sha256=Tm4Nnroo5_vp0UgZHhcEDVRRbhIrvVdfPr8nTyihoH4,2832
|
|
195
195
|
dnastack/http/authenticators/oauth2_adapter/client_credential.py,sha256=2iVOof4YZEVGizDRDBISbv8U_xIemtUnHzzxa3mxswc,2770
|
|
196
|
-
dnastack/http/authenticators/oauth2_adapter/cloud_providers.py,sha256=
|
|
196
|
+
dnastack/http/authenticators/oauth2_adapter/cloud_providers.py,sha256=sWto8WfK2-8xjx3SbrRMIaYg2V8cwohR1XIU6xTXzfA,5763
|
|
197
197
|
dnastack/http/authenticators/oauth2_adapter/device_code_flow.py,sha256=dXI5CyUcsqYg6gf5vDC_3eY6Cc-H1C8W7FeD_24j92A,6750
|
|
198
198
|
dnastack/http/authenticators/oauth2_adapter/factory.py,sha256=ZtNXOklWEim-26ooNoPp3ji_hRg1vf4fHHnY94F0wLI,1087
|
|
199
199
|
dnastack/http/authenticators/oauth2_adapter/models.py,sha256=7UsC8DkStMBx7Bz_xHQNi_J1UO_H4nfHme7oBhokj2I,1339
|
|
200
200
|
dnastack/http/authenticators/oauth2_adapter/token_exchange.py,sha256=nSuAsSKWa_UNqHSbPMOEk4komaFITYAnE04Sk5WOrLc,6332
|
|
201
|
-
dnastack_client_library-3.1.
|
|
202
|
-
dnastack_client_library-3.1.
|
|
203
|
-
dnastack_client_library-3.1.
|
|
204
|
-
dnastack_client_library-3.1.
|
|
205
|
-
dnastack_client_library-3.1.
|
|
206
|
-
dnastack_client_library-3.1.
|
|
201
|
+
dnastack_client_library-3.1.209.dist-info/licenses/LICENSE,sha256=uwybO-wUbQhxkosgjhJlxmYATMy-AzoULFO9FUedE34,11580
|
|
202
|
+
dnastack_client_library-3.1.209.dist-info/METADATA,sha256=wi1ZarZ4hhrHe-Lle2I5OpuE9fDFMUN_2CxB1Lb8z9k,1791
|
|
203
|
+
dnastack_client_library-3.1.209.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
204
|
+
dnastack_client_library-3.1.209.dist-info/entry_points.txt,sha256=Y6OeicsiyGn3-8D-SiV4NiKlJgXfkSqK88kFBR6R1rY,89
|
|
205
|
+
dnastack_client_library-3.1.209.dist-info/top_level.txt,sha256=P2RgRyqJ7hfNy1wLVRoVLJYEppUVkCX3syGK9zBqkt8,9
|
|
206
|
+
dnastack_client_library-3.1.209.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|