dnastack-client-library 3.1.178__py3-none-any.whl → 3.1.204__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/alpha/app/explorer.py +1 -1
- dnastack/alpha/app/workbench.py +4 -4
- dnastack/alpha/cli/wes.py +3 -3
- dnastack/alpha/client/collections/client.py +2 -3
- dnastack/alpha/client/wes/client.py +5 -8
- dnastack/cli/commands/collections/commands.py +3 -4
- dnastack/cli/commands/collections/tables.py +1 -1
- dnastack/cli/commands/collections/utils.py +1 -1
- dnastack/cli/commands/config/commands.py +1 -1
- dnastack/cli/commands/config/endpoints.py +39 -20
- dnastack/cli/commands/config/registries.py +2 -2
- dnastack/cli/commands/dataconnect/tables.py +1 -1
- dnastack/cli/commands/drs/commands.py +1 -1
- dnastack/cli/commands/explorer/questions/commands.py +12 -6
- dnastack/cli/commands/explorer/questions/utils.py +16 -7
- dnastack/cli/commands/publisher/collections/tables.py +1 -1
- dnastack/cli/commands/publisher/collections/utils.py +1 -1
- dnastack/cli/commands/publisher/datasources/commands.py +1 -1
- dnastack/cli/commands/workbench/runs/commands.py +11 -3
- dnastack/cli/commands/workbench/samples/commands.py +1 -2
- dnastack/cli/commands/workbench/workflows/versions/dependencies/commands.py +3 -3
- dnastack/cli/commands/workbench/workflows/versions/transformations.py +5 -9
- dnastack/cli/helpers/exporter.py +1 -1
- dnastack/client/base_exceptions.py +2 -2
- dnastack/client/collections/client.py +4 -4
- dnastack/client/collections/model.py +29 -29
- dnastack/client/data_connect.py +5 -9
- dnastack/client/datasources/model.py +3 -3
- dnastack/client/drs.py +4 -4
- dnastack/client/explorer/client.py +1 -1
- dnastack/client/explorer/models.py +3 -7
- dnastack/client/factory.py +1 -1
- dnastack/client/models.py +6 -6
- dnastack/client/service_registry/factory.py +3 -3
- dnastack/client/service_registry/helper.py +7 -14
- dnastack/client/service_registry/manager.py +4 -4
- dnastack/client/workbench/base_client.py +2 -2
- dnastack/client/workbench/ewes/client.py +3 -3
- dnastack/client/workbench/ewes/models.py +246 -181
- dnastack/client/workbench/models.py +7 -7
- dnastack/client/workbench/samples/models.py +41 -41
- dnastack/client/workbench/storage/client.py +2 -2
- dnastack/client/workbench/storage/models.py +24 -24
- dnastack/client/workbench/workflow/client.py +7 -7
- dnastack/client/workbench/workflow/models.py +64 -64
- dnastack/client/workbench/workflow/utils.py +5 -5
- dnastack/common/auth_manager.py +6 -13
- dnastack/common/class_decorator.py +3 -3
- dnastack/common/events.py +7 -7
- dnastack/common/json_argument_parser.py +4 -4
- dnastack/common/model_mixin.py +1 -1
- dnastack/common/parser.py +3 -3
- dnastack/common/simple_stream.py +1 -1
- dnastack/configuration/manager.py +8 -4
- dnastack/configuration/models.py +2 -2
- dnastack/constants.py +1 -1
- dnastack/context/manager.py +2 -2
- dnastack/context/models.py +2 -2
- dnastack/feature_flags.py +2 -2
- dnastack/http/authenticators/abstract.py +2 -2
- dnastack/http/authenticators/factory.py +2 -2
- dnastack/http/authenticators/oauth2.py +8 -8
- dnastack/http/authenticators/oauth2_adapter/client_credential.py +5 -14
- dnastack/http/authenticators/oauth2_adapter/models.py +15 -15
- dnastack/http/session.py +3 -3
- dnastack/http/session_info.py +3 -3
- {dnastack_client_library-3.1.178.dist-info → dnastack_client_library-3.1.204.dist-info}/METADATA +2 -2
- {dnastack_client_library-3.1.178.dist-info → dnastack_client_library-3.1.204.dist-info}/RECORD +72 -72
- {dnastack_client_library-3.1.178.dist-info → dnastack_client_library-3.1.204.dist-info}/WHEEL +0 -0
- {dnastack_client_library-3.1.178.dist-info → dnastack_client_library-3.1.204.dist-info}/entry_points.txt +0 -0
- {dnastack_client_library-3.1.178.dist-info → dnastack_client_library-3.1.204.dist-info}/licenses/LICENSE +0 -0
- {dnastack_client_library-3.1.178.dist-info → dnastack_client_library-3.1.204.dist-info}/top_level.txt +0 -0
|
@@ -58,7 +58,7 @@ class CollectionItemListResultLoader(ResultLoader):
|
|
|
58
58
|
self.__max_results = int(max_results) if max_results else None
|
|
59
59
|
self.__loaded_results = 0
|
|
60
60
|
self.__active = True
|
|
61
|
-
self.__visited_urls: List[str] =
|
|
61
|
+
self.__visited_urls: List[str] = []
|
|
62
62
|
self.__trace = trace
|
|
63
63
|
self.__next_page_url = None
|
|
64
64
|
|
|
@@ -119,7 +119,7 @@ class CollectionItemListResultLoader(ResultLoader):
|
|
|
119
119
|
response_text = response.text
|
|
120
120
|
|
|
121
121
|
try:
|
|
122
|
-
response_body = response.json() if response_text else
|
|
122
|
+
response_body = response.json() if response_text else {}
|
|
123
123
|
except Exception:
|
|
124
124
|
self.logger.error(f'{self.__service_url}: Unexpectedly non-JSON response body from {current_url}')
|
|
125
125
|
raise PageableApiError(
|
|
@@ -208,7 +208,7 @@ class CollectionServiceClient(BaseServiceClient):
|
|
|
208
208
|
trace = trace or Span(origin=self)
|
|
209
209
|
with self.create_http_session() as session:
|
|
210
210
|
res = session.post(urljoin(self.url, 'collections') + '?includeInternalItemsQuery=true',
|
|
211
|
-
json=collection.
|
|
211
|
+
json=collection.model_dump(),
|
|
212
212
|
trace_context=trace)
|
|
213
213
|
return Collection(**res.json())
|
|
214
214
|
|
|
@@ -245,7 +245,7 @@ class CollectionServiceClient(BaseServiceClient):
|
|
|
245
245
|
trace = trace or Span(origin=self)
|
|
246
246
|
with self.create_http_session() as session:
|
|
247
247
|
session.post(urljoin(self.url, f'collections/{collection_id_or_slug_name_or_db_schema_name}/items'),
|
|
248
|
-
json=create_items_request.
|
|
248
|
+
json=create_items_request.model_dump(), trace_context=trace)
|
|
249
249
|
return None
|
|
250
250
|
|
|
251
251
|
def delete_collection_items(self,
|
|
@@ -10,7 +10,7 @@ from dnastack.client.base_exceptions import ApiError
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class Tag(BaseModel):
|
|
13
|
-
id: Optional[str]
|
|
13
|
+
id: Optional[str] = None
|
|
14
14
|
label: str
|
|
15
15
|
|
|
16
16
|
|
|
@@ -40,9 +40,9 @@ class Collection(BaseModel):
|
|
|
40
40
|
slugName: str
|
|
41
41
|
metadata: Optional[Dict[str, Any]] = Field(default_factory=dict)
|
|
42
42
|
description: Optional[str] = None
|
|
43
|
-
itemsQuery: Optional[str]
|
|
43
|
+
itemsQuery: Optional[str] = None
|
|
44
44
|
tags: Optional[List[Tag]] = Field(default_factory=list)
|
|
45
|
-
createdAt: Optional[datetime]
|
|
45
|
+
createdAt: Optional[datetime] = None
|
|
46
46
|
updatedAt: Optional[datetime] = None
|
|
47
47
|
dbSchemaName: Optional[str] = None
|
|
48
48
|
itemsChangedAt: Optional[datetime] = None
|
|
@@ -69,53 +69,53 @@ class PageableApiError(ApiError):
|
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
class Pagination(BaseModel):
|
|
72
|
-
nextPageUrl: Optional[str]
|
|
72
|
+
nextPageUrl: Optional[str] = None
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
class PaginatedResource(BaseModel):
|
|
76
|
-
pagination: Optional[Pagination]
|
|
76
|
+
pagination: Optional[Pagination] = None
|
|
77
77
|
|
|
78
78
|
def items(self) -> List[Any]:
|
|
79
79
|
pass
|
|
80
80
|
|
|
81
81
|
class CollectionItem(BaseModel):
|
|
82
82
|
id: str
|
|
83
|
-
collectionId: Optional[str]
|
|
84
|
-
type: Optional[str]
|
|
85
|
-
name: Optional[str]
|
|
86
|
-
displayName: Optional[str]
|
|
87
|
-
dataSourceName: Optional[str]
|
|
88
|
-
dataSourceType: Optional[str]
|
|
89
|
-
cachedAt: Optional[str]
|
|
90
|
-
createdTime: Optional[str]
|
|
91
|
-
updatedTime: Optional[str]
|
|
92
|
-
itemUpdatedTime: Optional[str]
|
|
93
|
-
sourceKey: Optional[str]
|
|
94
|
-
metadataUrl: Optional[str]
|
|
95
|
-
dataSourceUrl: Optional[str]
|
|
96
|
-
sizeUnit: Optional[str]
|
|
97
|
-
size: Optional[int]
|
|
83
|
+
collectionId: Optional[str] = None
|
|
84
|
+
type: Optional[str] = None
|
|
85
|
+
name: Optional[str] = None
|
|
86
|
+
displayName: Optional[str] = None
|
|
87
|
+
dataSourceName: Optional[str] = None
|
|
88
|
+
dataSourceType: Optional[str] = None
|
|
89
|
+
cachedAt: Optional[str] = None
|
|
90
|
+
createdTime: Optional[str] = None
|
|
91
|
+
updatedTime: Optional[str] = None
|
|
92
|
+
itemUpdatedTime: Optional[str] = None
|
|
93
|
+
sourceKey: Optional[str] = None
|
|
94
|
+
metadataUrl: Optional[str] = None
|
|
95
|
+
dataSourceUrl: Optional[str] = None
|
|
96
|
+
sizeUnit: Optional[str] = None
|
|
97
|
+
size: Optional[int] = None
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
class CollectionItemListResponse(BaseModel):
|
|
101
101
|
items: List[CollectionItem]
|
|
102
|
-
pagination: Optional[Pagination]
|
|
102
|
+
pagination: Optional[Pagination] = None
|
|
103
103
|
|
|
104
104
|
|
|
105
105
|
class CollectionItemListOptions(BaseModel):
|
|
106
|
-
type: Optional[str]
|
|
107
|
-
limit: Optional[int]
|
|
106
|
+
type: Optional[str] = None
|
|
107
|
+
limit: Optional[int] = None
|
|
108
108
|
|
|
109
109
|
|
|
110
110
|
class CreateCollectionItemsRequest(BaseModel):
|
|
111
111
|
dataSourceId: str
|
|
112
|
-
dataSourceType: Optional[str]
|
|
112
|
+
dataSourceType: Optional[str] = None
|
|
113
113
|
sourceKeys: List[str]
|
|
114
114
|
|
|
115
115
|
|
|
116
116
|
class DeleteCollectionItemRequest(BaseModel):
|
|
117
117
|
dataSourceId: str
|
|
118
|
-
dataSourceType: Optional[str]
|
|
118
|
+
dataSourceType: Optional[str] = None
|
|
119
119
|
sourceKey: str
|
|
120
120
|
|
|
121
121
|
|
|
@@ -127,11 +127,11 @@ class CollectionValidationStatus(str, Enum):
|
|
|
127
127
|
|
|
128
128
|
|
|
129
129
|
class CollectionValidationMissingItems(BaseModel):
|
|
130
|
-
files: Optional[int]
|
|
131
|
-
tables: Optional[int]
|
|
130
|
+
files: Optional[int] = None
|
|
131
|
+
tables: Optional[int] = None
|
|
132
132
|
|
|
133
133
|
|
|
134
134
|
class CollectionStatus(BaseModel):
|
|
135
135
|
validationsStatus: CollectionValidationStatus
|
|
136
|
-
lastChecked: Optional[datetime]
|
|
137
|
-
missingItems: Optional[int]
|
|
136
|
+
lastChecked: Optional[datetime] = None
|
|
137
|
+
missingItems: Optional[int] = None
|
dnastack/client/data_connect.py
CHANGED
|
@@ -40,7 +40,7 @@ class DataConversionError(RuntimeError):
|
|
|
40
40
|
|
|
41
41
|
class Error(BaseModel):
|
|
42
42
|
""" Error representation """
|
|
43
|
-
status: Any
|
|
43
|
+
status: Any = None
|
|
44
44
|
title: str
|
|
45
45
|
details: Optional[str] = None
|
|
46
46
|
|
|
@@ -91,7 +91,7 @@ class PageableResultLoader(ResultLoader):
|
|
|
91
91
|
self._initial_url = initial_url
|
|
92
92
|
self._current_url: Optional[str] = None
|
|
93
93
|
self._active = True
|
|
94
|
-
self._visited_urls: List[str] =
|
|
94
|
+
self._visited_urls: List[str] = []
|
|
95
95
|
|
|
96
96
|
def _post_request(self, api_response: Union[ListTablesResponse, TableDataResponse]):
|
|
97
97
|
if api_response.errors:
|
|
@@ -161,7 +161,7 @@ class TableListLoader(PageableResultLoader):
|
|
|
161
161
|
response_text = response.text
|
|
162
162
|
|
|
163
163
|
try:
|
|
164
|
-
response_body = response.json() if response_text else
|
|
164
|
+
response_body = response.json() if response_text else {}
|
|
165
165
|
except Exception:
|
|
166
166
|
self.logger.error(f'{self._initial_url}: Unexpectedly non-JSON response body from {current_url}')
|
|
167
167
|
raise DataConnectError(
|
|
@@ -425,7 +425,7 @@ class QueryLoader(PageableResultLoader):
|
|
|
425
425
|
super(QueryLoader, self).__init__(initial_url=initial_url, http_session=http_session)
|
|
426
426
|
|
|
427
427
|
self.__query = query
|
|
428
|
-
self.__schema: Dict[str, Any] =
|
|
428
|
+
self.__schema: Dict[str, Any] = {}
|
|
429
429
|
self.__trace = trace
|
|
430
430
|
|
|
431
431
|
def load(self) -> List[Dict[str, Any]]:
|
|
@@ -456,11 +456,7 @@ class QueryLoader(PageableResultLoader):
|
|
|
456
456
|
self._visited_urls.append(self._current_url)
|
|
457
457
|
except ClientError as e:
|
|
458
458
|
status_code = e.response.status_code
|
|
459
|
-
common_error_properties =
|
|
460
|
-
visited_urls=self._visited_urls,
|
|
461
|
-
response=e.response,
|
|
462
|
-
trace=e.trace,
|
|
463
|
-
)
|
|
459
|
+
common_error_properties = {'visited_urls': self._visited_urls, 'response': e.response, 'trace': e.trace}
|
|
464
460
|
if status_code == 400:
|
|
465
461
|
if not self._current_url:
|
|
466
462
|
if self.__query:
|
dnastack/client/drs.py
CHANGED
|
@@ -141,8 +141,8 @@ class DrsObjectAccessMethod(BaseModel):
|
|
|
141
141
|
|
|
142
142
|
|
|
143
143
|
class DrsObjectChecksum(BaseModel):
|
|
144
|
-
checksum: Optional[str]
|
|
145
|
-
type: Optional[str]
|
|
144
|
+
checksum: Optional[str] = None
|
|
145
|
+
type: Optional[str] = None
|
|
146
146
|
|
|
147
147
|
|
|
148
148
|
class DrsObject(BaseModel):
|
|
@@ -314,7 +314,7 @@ class Blob(AbstractContextManager):
|
|
|
314
314
|
def get_access_url_object(self) -> DrsObjectAccessUrl:
|
|
315
315
|
""" Get the DRS Access URL Object """
|
|
316
316
|
drs_obj = self.get_object()
|
|
317
|
-
self._logger.debug(f'DRS Object:\n\n{drs_obj.
|
|
317
|
+
self._logger.debug(f'DRS Object:\n\n{drs_obj.model_dump_json(indent=2)}\n')
|
|
318
318
|
|
|
319
319
|
if drs_obj.access_methods:
|
|
320
320
|
for access_method in drs_obj.access_methods:
|
|
@@ -538,7 +538,7 @@ class DrsClient(BaseServiceClient):
|
|
|
538
538
|
if max_worker_count < 2:
|
|
539
539
|
max_worker_count = 2
|
|
540
540
|
|
|
541
|
-
future_to_url_map: Dict[Future, str] =
|
|
541
|
+
future_to_url_map: Dict[Future, str] = {}
|
|
542
542
|
|
|
543
543
|
with ThreadPoolExecutor(max_workers=max_worker_count) as pool:
|
|
544
544
|
for url in unique_urls:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from typing import List, Optional, Dict, Any
|
|
2
|
-
from pydantic import BaseModel, Field
|
|
2
|
+
from pydantic import ConfigDict, BaseModel, Field
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class QuestionParam(BaseModel):
|
|
@@ -21,9 +21,7 @@ class QuestionParam(BaseModel):
|
|
|
21
21
|
table: Optional[str] = None
|
|
22
22
|
column: Optional[str] = None
|
|
23
23
|
values: Optional[str] = None
|
|
24
|
-
|
|
25
|
-
class Config:
|
|
26
|
-
allow_population_by_field_name = True
|
|
24
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
27
25
|
|
|
28
26
|
|
|
29
27
|
class QuestionCollection(BaseModel):
|
|
@@ -34,9 +32,7 @@ class QuestionCollection(BaseModel):
|
|
|
34
32
|
slug: str
|
|
35
33
|
name: str
|
|
36
34
|
question_id: str = Field(alias="questionId")
|
|
37
|
-
|
|
38
|
-
class Config:
|
|
39
|
-
allow_population_by_field_name = True
|
|
35
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
40
36
|
|
|
41
37
|
|
|
42
38
|
class FederatedQuestion(BaseModel):
|
dnastack/client/factory.py
CHANGED
|
@@ -65,7 +65,7 @@ class EndpointRepository:
|
|
|
65
65
|
self.__cacheable = cacheable
|
|
66
66
|
self.__endpoints = self.__set_endpoints(endpoints)
|
|
67
67
|
self.__additional_service_client_classes = additional_service_client_classes
|
|
68
|
-
self.__default_event_interceptors = default_event_interceptors or
|
|
68
|
+
self.__default_event_interceptors = default_event_interceptors or {}
|
|
69
69
|
|
|
70
70
|
self.__logger.debug('Initialized')
|
|
71
71
|
|
dnastack/client/models.py
CHANGED
|
@@ -41,21 +41,21 @@ class ServiceEndpoint(BaseModel, HashableModel):
|
|
|
41
41
|
This is in junction with GA4GH Service Information.
|
|
42
42
|
"""
|
|
43
43
|
|
|
44
|
-
type: Optional[ServiceType]
|
|
44
|
+
type: Optional[ServiceType] = None
|
|
45
45
|
""" Service Type """
|
|
46
46
|
|
|
47
47
|
url: str
|
|
48
48
|
""" Base URL """
|
|
49
49
|
|
|
50
50
|
# DEPRECATED: It is here only for the migration.
|
|
51
|
-
mode: Optional[str]
|
|
51
|
+
mode: Optional[str] = None
|
|
52
52
|
""" Client mode ("standard" or "explorer") - only applicable if the client supports.
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
DO NOT USE THIS. This is replaced by "type" in model version 2.0.
|
|
55
55
|
"""
|
|
56
56
|
|
|
57
57
|
# DEPRECATED: It is here only for the migration.
|
|
58
|
-
source: Optional[EndpointSource]
|
|
58
|
+
source: Optional[EndpointSource] = None
|
|
59
59
|
""" The source of the endpoint configuration (e.g., service registry) """
|
|
60
60
|
|
|
61
61
|
def get_authentications(self) -> List[Dict[str, Any]]:
|
|
@@ -70,12 +70,12 @@ class ServiceEndpoint(BaseModel, HashableModel):
|
|
|
70
70
|
return [self.__convert_to_dict(raw_auth) for raw_auth in raw_auths]
|
|
71
71
|
|
|
72
72
|
def __convert_to_dict(self, model: Union[Dict[str, Any], BaseModel]) -> Dict[str, Any]:
|
|
73
|
-
converted_model: Dict[str, Any] =
|
|
73
|
+
converted_model: Dict[str, Any] = {}
|
|
74
74
|
|
|
75
75
|
if isinstance(model, dict):
|
|
76
76
|
converted_model.update(model)
|
|
77
77
|
elif isinstance(model, BaseModel):
|
|
78
|
-
converted_model.update(model.
|
|
78
|
+
converted_model.update(model.model_dump())
|
|
79
79
|
else:
|
|
80
80
|
raise NotImplementedError(f'No interpretation for {model}')
|
|
81
81
|
|
|
@@ -88,7 +88,7 @@ class ClientFactory:
|
|
|
88
88
|
yield entry
|
|
89
89
|
|
|
90
90
|
def _merge_auth_info_list(self, entries: List[RegisteredServiceInfo]):
|
|
91
|
-
auth_info_groups: Dict[str, List[Dict[str, Any]]] =
|
|
91
|
+
auth_info_groups: Dict[str, List[Dict[str, Any]]] = {}
|
|
92
92
|
for entry in entries:
|
|
93
93
|
for auth_info in (entry.info.authentication or []):
|
|
94
94
|
if auth_info.get('type') is None or auth_info.get('type') == 'oauth2':
|
|
@@ -103,7 +103,7 @@ class ClientFactory:
|
|
|
103
103
|
|
|
104
104
|
group_key = self._make_auth_info_group_key(auth_info)
|
|
105
105
|
if group_key not in auth_info_groups:
|
|
106
|
-
auth_info_groups[group_key] =
|
|
106
|
+
auth_info_groups[group_key] = []
|
|
107
107
|
auth_info_groups[group_key].append(auth_info)
|
|
108
108
|
|
|
109
109
|
for group_key, auth_info_list in auth_info_groups.items():
|
|
@@ -118,7 +118,7 @@ class ClientFactory:
|
|
|
118
118
|
# The current implementation makes an optimistic assumption that when the client has authorization for
|
|
119
119
|
# a resource at the root level, i.e., https://foo.io/, it will have access to all resources as long as
|
|
120
120
|
# all necessary scopes are requested.
|
|
121
|
-
url_to_scopes_map: Dict[str, Set[str]] =
|
|
121
|
+
url_to_scopes_map: Dict[str, Set[str]] = {}
|
|
122
122
|
|
|
123
123
|
# Separate scopes per domain
|
|
124
124
|
for auth_info in auth_info_list:
|
|
@@ -15,7 +15,7 @@ def parse_ga4gh_service_info(service: Service, alternate_service_id: Optional[st
|
|
|
15
15
|
|
|
16
16
|
authentications = [
|
|
17
17
|
_parse_authentication_info(auth_info)
|
|
18
|
-
for auth_info in (service.authentication or
|
|
18
|
+
for auth_info in (service.authentication or [])
|
|
19
19
|
]
|
|
20
20
|
|
|
21
21
|
if authentications:
|
|
@@ -26,16 +26,9 @@ def parse_ga4gh_service_info(service: Service, alternate_service_id: Optional[st
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def _parse_authentication_info(auth_info: Dict[str, Any]) -> Dict[str, Any]:
|
|
29
|
-
return
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
grant_type=auth_info.get('grantType'),
|
|
36
|
-
redirect_url=auth_info.get('redirectUrl'),
|
|
37
|
-
resource_url=auth_info.get('resource'),
|
|
38
|
-
scope=auth_info.get('scope'),
|
|
39
|
-
token_endpoint=auth_info.get('accessTokenUrl'),
|
|
40
|
-
platform_credentials=auth_info.get('grantType') == GRANT_TYPE_TOKEN_EXCHANGE,
|
|
41
|
-
)
|
|
29
|
+
return {'type': 'oauth2', 'authorization_endpoint': auth_info.get('authorizationUrl'),
|
|
30
|
+
'client_id': auth_info.get('clientId'), 'client_secret': auth_info.get('clientSecret'),
|
|
31
|
+
'device_code_endpoint': auth_info.get('deviceCodeUrl'), 'grant_type': auth_info.get('grantType'),
|
|
32
|
+
'redirect_url': auth_info.get('redirectUrl'), 'resource_url': auth_info.get('resource'),
|
|
33
|
+
'scope': auth_info.get('scope'), 'token_endpoint': auth_info.get('accessTokenUrl'),
|
|
34
|
+
'platform_credentials': auth_info.get('grantType') == GRANT_TYPE_TOKEN_EXCHANGE}
|
|
@@ -75,7 +75,7 @@ class ServiceRegistryManager:
|
|
|
75
75
|
|
|
76
76
|
# Add the registry endpoint.
|
|
77
77
|
self.__context.endpoints.append(registry_endpoint)
|
|
78
|
-
self.events.dispatch('endpoint-sync',
|
|
78
|
+
self.events.dispatch('endpoint-sync', {'action': 'add', 'endpoint': registry_endpoint})
|
|
79
79
|
|
|
80
80
|
# Initiate the first sync.
|
|
81
81
|
return self.__synchronize_endpoints_with(ServiceRegistry.make(registry_endpoint))
|
|
@@ -133,7 +133,7 @@ class ServiceRegistryManager:
|
|
|
133
133
|
if sync_operation.action in ('add', 'update', 'keep'):
|
|
134
134
|
new_endpoint_list.append(endpoint)
|
|
135
135
|
|
|
136
|
-
self.events.dispatch('endpoint-sync',
|
|
136
|
+
self.events.dispatch('endpoint-sync', {'action': sync_operation.action, 'endpoint': endpoint})
|
|
137
137
|
|
|
138
138
|
endpoints.clear()
|
|
139
139
|
endpoints.extend(sorted([endpoint for endpoint in new_endpoint_list], key=lambda e: e.id))
|
|
@@ -183,11 +183,11 @@ class ServiceRegistryManager:
|
|
|
183
183
|
endpoint.id == registry_endpoint_id
|
|
184
184
|
or (endpoint.source and endpoint.source.source_id == registry_endpoint_id)
|
|
185
185
|
):
|
|
186
|
-
self.events.dispatch('endpoint-sync',
|
|
186
|
+
self.events.dispatch('endpoint-sync', {'action': 'remove', 'endpoint': endpoint})
|
|
187
187
|
continue
|
|
188
188
|
else:
|
|
189
189
|
new_endpoint_list.append(endpoint)
|
|
190
|
-
self.events.dispatch('endpoint-sync',
|
|
190
|
+
self.events.dispatch('endpoint-sync', {'action': 'keep', 'endpoint': endpoint})
|
|
191
191
|
|
|
192
192
|
endpoints.clear()
|
|
193
193
|
endpoints.extend(new_endpoint_list)
|
|
@@ -74,7 +74,7 @@ class WorkbenchResultLoader(ResultLoader):
|
|
|
74
74
|
self.__max_results = int(max_results) if max_results else None
|
|
75
75
|
self.__loaded_results = 0
|
|
76
76
|
self.__active = True
|
|
77
|
-
self.__visited_urls: List[str] =
|
|
77
|
+
self.__visited_urls: List[str] = []
|
|
78
78
|
self.__trace = trace
|
|
79
79
|
self.__next_page_url = None
|
|
80
80
|
|
|
@@ -135,7 +135,7 @@ class WorkbenchResultLoader(ResultLoader):
|
|
|
135
135
|
response_text = response.text
|
|
136
136
|
|
|
137
137
|
try:
|
|
138
|
-
response_body = response.json() if response_text else
|
|
138
|
+
response_body = response.json() if response_text else {}
|
|
139
139
|
except Exception:
|
|
140
140
|
self.logger.error(f'{self.__service_url}: Unexpectedly non-JSON response body from {current_url}')
|
|
141
141
|
raise PageableApiError(
|
|
@@ -195,14 +195,14 @@ class EWesClient(BaseWorkbenchClient):
|
|
|
195
195
|
trace = trace or Span(origin=self)
|
|
196
196
|
with self.create_http_session() as session:
|
|
197
197
|
response = session.post(urljoin(self.endpoint.url, f'{self.namespace}/ga4gh/wes/v1/runs'),
|
|
198
|
-
json=data.
|
|
198
|
+
json=data.model_dump(),
|
|
199
199
|
trace_context=trace)
|
|
200
200
|
return MinimalExtendedRun(**response.json())
|
|
201
201
|
|
|
202
202
|
def submit_batch(self, data: BatchRunRequest, trace: Optional[Span] = None) -> BatchRunResponse:
|
|
203
203
|
with self.create_http_session() as session:
|
|
204
204
|
response = session.post(urljoin(self.endpoint.url, f'{self.namespace}/ga4gh/wes/v1/batch'),
|
|
205
|
-
json=data.
|
|
205
|
+
json=data.model_dump(),
|
|
206
206
|
trace_context=trace)
|
|
207
207
|
return BatchRunResponse(**response.json())
|
|
208
208
|
|
|
@@ -240,7 +240,7 @@ class EWesClient(BaseWorkbenchClient):
|
|
|
240
240
|
trace: Optional[Span] = None) -> Iterable[bytes]:
|
|
241
241
|
trace = trace or Span()
|
|
242
242
|
|
|
243
|
-
params =
|
|
243
|
+
params = {}
|
|
244
244
|
if max_bytes:
|
|
245
245
|
params['max'] = max_bytes
|
|
246
246
|
|