dnastack-client-library 3.1.204__py3-none-any.whl → 3.1.207__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.
@@ -174,17 +174,9 @@ def init_collections_commands(group: Group):
174
174
  name='status',
175
175
  specs=[
176
176
  COLLECTION_ID_ARG,
177
- ArgumentSpec(
178
- name='missing_items',
179
- arg_names=['--missing-items'],
180
- help='To find missing files and/or folders while adding or removing to the collection.',
181
- type=bool,
182
- required=False,
183
- ),
184
177
  ]
185
178
  )
186
- def get_collection_status(collection: str,
187
- missing_items: Optional[bool] = False):
179
+ def get_collection_status(collection: str):
188
180
  """ Check status of a collection """
189
181
 
190
182
  def format_datetime(dt: Optional[datetime]) -> str:
@@ -193,6 +185,16 @@ def init_collections_commands(group: Group):
193
185
  return dt.strftime("%Y-%m-%d %H:%M:%S")
194
186
  return "N/A"
195
187
 
188
+ def get_status_color(status: CollectionValidationStatus) -> str:
189
+ """Get color for status based on validation state"""
190
+ status_colors = {
191
+ CollectionValidationStatus.VALIDATED: 'green',
192
+ CollectionValidationStatus.VALIDATION_STOPPED: 'red',
193
+ CollectionValidationStatus.VALIDATION_IN_PROGRESS: 'yellow',
194
+ CollectionValidationStatus.MISSING_ITEMS: 'yellow'
195
+ }
196
+ return status_colors.get(status, 'white')
197
+
196
198
  def format_validation_status(status: CollectionValidationStatus) -> str:
197
199
  """Convert enum status to user-friendly message"""
198
200
  status_messages = {
@@ -207,29 +209,27 @@ def init_collections_commands(group: Group):
207
209
  """Print hint about missing items to stderr"""
208
210
  hint = (
209
211
  "# Run the following command to see details.\n"
210
- f"omics publisher collections status --collection {collection_id} --missing-items"
212
+ f"omics publisher collections items list --collection {collection_id} --missing-items"
211
213
  )
212
- click.echo(hint, err=True)
214
+ click.secho(hint, dim=True, err=True)
213
215
 
214
216
  def format_collection_status(status: CollectionStatus, collection_id: str) -> None:
215
217
  """Format and print collection status according to requirements"""
216
- # Print main status
217
- click.echo(f"Validation Status: {format_validation_status(status.validationsStatus)}")
218
+ # Print main status with color
219
+ status_color = get_status_color(status.validationsStatus)
220
+ click.echo("Validation Status: ", nl=False)
221
+ click.secho(format_validation_status(status.validationsStatus), fg=status_color)
218
222
 
219
223
  if status.lastChecked:
220
224
  click.echo(f"Last Checked: {format_datetime(status.lastChecked)}")
221
225
 
222
- # Print missing items if any
226
+ # Print missing items count if any
223
227
  if status.validationsStatus == CollectionValidationStatus.MISSING_ITEMS and status.missingItems:
224
- click.echo("\nMissing Items:")
225
- if status.missingItems.tables:
226
- click.echo(f" Tables: {status.missingItems.tables}")
227
- if status.missingItems.files:
228
- click.echo(f" Files: {status.missingItems.files}")
228
+ click.echo("\nNumber of Missing Items: ", nl=False)
229
+ click.secho(str(status.missingItems), fg='yellow', bold=True)
229
230
  click.echo() # Add empty line before stderr message
230
231
  print_missing_items_hint(collection_id)
231
232
 
232
233
  client = _get_collection_service_client()
233
234
  status = client.get_collection_status(collection_id_or_slug_name_or_db_schema_name=collection)
234
-
235
235
  format_collection_status(status, collection)
@@ -40,6 +40,13 @@ def items_command_group():
40
40
  help='The type of items to list.',
41
41
  required=False,
42
42
  ),
43
+ ArgumentSpec(
44
+ name='missing_items',
45
+ arg_names=['--missing-items'],
46
+ help='List only missing items from the collection.',
47
+ type=bool,
48
+ required=False,
49
+ ),
43
50
  MAX_RESULTS_ARG,
44
51
  RESOURCE_OUTPUT_ARG
45
52
  ]
@@ -48,6 +55,7 @@ def list(collection: str,
48
55
  limit: Optional[int],
49
56
  max_results: Optional[int],
50
57
  item_type: Optional[str],
58
+ missing_items: Optional[bool] = False,
51
59
  output: Optional[str] = None):
52
60
  """ List items of the given collection """
53
61
  assert limit >= 0, 'The limit (--limit) should be either ZERO (item query WITHOUT limit) ' \
@@ -56,6 +64,7 @@ def list(collection: str,
56
64
  list_options = CollectionItemListOptions(
57
65
  type=item_type,
58
66
  limit=limit,
67
+ onlyMissing=missing_items if missing_items else None,
59
68
  )
60
69
 
61
70
  collection_service_client = _get_collection_service_client()
@@ -105,6 +105,7 @@ class CollectionItemListResponse(BaseModel):
105
105
  class CollectionItemListOptions(BaseModel):
106
106
  type: Optional[str] = None
107
107
  limit: Optional[int] = None
108
+ onlyMissing: Optional[bool] = None
108
109
 
109
110
 
110
111
  class CreateCollectionItemsRequest(BaseModel):
dnastack/constants.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import os
2
2
 
3
- __version__ = "3.1.204"
3
+ __version__ = "3.1.207"
4
4
 
5
5
  LOCAL_STORAGE_DIRECTORY = os.path.join(os.path.expanduser("~"), '.dnastack')
@@ -1,10 +1,11 @@
1
1
  from typing import List, Any, Dict, Optional
2
+ import logging
2
3
 
3
4
  from dnastack.client.models import ServiceEndpoint
4
5
  from dnastack.common.model_mixin import JsonModelMixin
5
6
  from dnastack.http.authenticators.abstract import Authenticator
6
7
  from dnastack.http.authenticators.oauth2 import OAuth2Authenticator
7
- from dnastack.http.authenticators.oauth2_adapter.models import OAuth2Authentication
8
+ from dnastack.http.authenticators.oauth2_adapter.models import OAuth2Authentication, SUPPORTED_GRANT_TYPES
8
9
 
9
10
 
10
11
  class UnsupportedAuthenticationInformationError(RuntimeError):
@@ -43,10 +44,21 @@ class HttpAuthenticatorFactory:
43
44
 
44
45
  @staticmethod
45
46
  def get_unique_auth_info_list(endpoints: List[ServiceEndpoint]) -> List[Dict[str, Any]]:
47
+ logger = logging.getLogger(__name__)
46
48
  unique_auth_info_map: Dict[str, Dict[str, Any]] = {}
47
49
 
48
50
  for endpoint in endpoints:
49
51
  for auth_info in endpoint.get_authentications():
52
+ grant_type = auth_info.get('grant_type')
53
+
54
+ # Skip authentication methods with unsupported grant types
55
+ if grant_type and grant_type not in SUPPORTED_GRANT_TYPES:
56
+ logger.debug("Skipping authentication with unsupported grant type '{}' for resource '{}'".format(
57
+ grant_type,
58
+ auth_info.get('resource_url', 'unknown')
59
+ ))
60
+ continue
61
+
50
62
  unique_auth_info_map[JsonModelMixin.hash(auth_info)] = auth_info
51
63
 
52
64
  return sorted(unique_auth_info_map.values(), key=lambda a: a.get('resource_url') or a.get('type'))
@@ -130,7 +130,7 @@ class OAuth2Authenticator(Authenticator):
130
130
  self.events.dispatch('authentication-failure', event_details)
131
131
 
132
132
  raise OAuth2MisconfigurationError('Cannot determine the type of authentication '
133
- f'({auth_info.json(sort_keys=True, exclude_none=True)})')
133
+ f'({auth_info.model_dump_json(exclude_none=True)})')
134
134
 
135
135
  adapter.check_config_readiness()
136
136
  for auth_event_type in ['blocking-response-required', 'blocking-response-ok', 'blocking-response-failed']:
@@ -6,6 +6,15 @@ from dnastack.common.model_mixin import JsonModelMixin as HashableModel
6
6
 
7
7
 
8
8
  GRANT_TYPE_TOKEN_EXCHANGE = 'urn:ietf:params:oauth:grant-type:token-exchange'
9
+ GRANT_TYPE_DEVICE_CODE = 'urn:ietf:params:oauth:grant-type:device_code'
10
+ GRANT_TYPE_CLIENT_CREDENTIALS = 'client_credentials'
11
+
12
+ # List of grant types supported by the CLI
13
+ SUPPORTED_GRANT_TYPES = [
14
+ GRANT_TYPE_DEVICE_CODE,
15
+ GRANT_TYPE_CLIENT_CREDENTIALS,
16
+ GRANT_TYPE_TOKEN_EXCHANGE,
17
+ ]
9
18
 
10
19
 
11
20
  class OAuth2Authentication(BaseModel, HashableModel):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dnastack-client-library
3
- Version: 3.1.204
3
+ Version: 3.1.207
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
@@ -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=K3XY21O6eakBvFiJHP9tzHHSBP4YLYDzlBPE3IdCfcY,113
3
+ dnastack/constants.py,sha256=ATOtsE118-FzkYW3GE1qbxQMUBSg9xDjPCGSqbHtQtA,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
@@ -57,8 +57,8 @@ dnastack/cli/commands/explorer/questions/tables.py,sha256=cb8YKqY7Qxrm2ROz7z8H6b
57
57
  dnastack/cli/commands/explorer/questions/utils.py,sha256=Np3AARD6ZSl2Ywvpsa4UJxw1Ark7D5NqgwPp1OopL54,8000
58
58
  dnastack/cli/commands/publisher/__init__.py,sha256=G8WNdx1UwanoA4X349ghv8Zyv5YizB8ryeJmwu9px8o,443
59
59
  dnastack/cli/commands/publisher/collections/__init__.py,sha256=KmclN_KY3ctVhtv-i8rxXpWTshPCj1tY6yhud4vrXYQ,636
60
- dnastack/cli/commands/publisher/collections/commands.py,sha256=A82NphvnD-9JuN2dVU_07EbAvB1NE7Em07IU7eDhagc,9454
61
- dnastack/cli/commands/publisher/collections/items.py,sha256=6V8w0wugRYQIwBSqHoYhkzJyiA5Bp5uDhg7tvxMa-9A,6040
60
+ dnastack/cli/commands/publisher/collections/commands.py,sha256=dM6l8ickhoxBYgAiGbLHNnej-UwjhmBvEAGbBALftLA,9622
61
+ dnastack/cli/commands/publisher/collections/items.py,sha256=JKmoZn6yOJdf2TzjCXV1aq5mNtE4SKU7RW3P9OQSMvo,6376
62
62
  dnastack/cli/commands/publisher/collections/tables.py,sha256=8_lKjpSyhqJ8EzYzF3Qcht7hErp8kOfZykpAJDg3uUo,2136
63
63
  dnastack/cli/commands/publisher/collections/utils.py,sha256=6_w7lX5LyEagdKt1DLWz84cTviZF9SN-VIe2JPti_XE,6250
64
64
  dnastack/cli/commands/publisher/datasources/__init__.py,sha256=90suC61lfFF1WzIU9f8lO0_DiLWIQF2Dy46_Yad3CD8,327
@@ -122,7 +122,7 @@ dnastack/client/models.py,sha256=_vOVpyfCaO0tQBIbESG3IUxAFv0Cix8jfXRn1ul1Rb4,290
122
122
  dnastack/client/result_iterator.py,sha256=00zEs7YbPJyt8d-6j7eHnmSVurP8hIOarj4FwsiR7xc,1908
123
123
  dnastack/client/collections/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
124
124
  dnastack/client/collections/client.py,sha256=fg3qVyVRqufW8kwM3jtQVz4zzNoHjuW9DtCzSykg-mw,16011
125
- dnastack/client/collections/model.py,sha256=NUDCXt2WcT8RTQoRtzHzFpWKK-GztkasdeyeyYkGUu8,3695
125
+ dnastack/client/collections/model.py,sha256=VFuzE7ebWvuyR52RFa3Bod2Twje1JUBTz_7jLnsA5ms,3734
126
126
  dnastack/client/datasources/__init__.py,sha256=HxDIHuQX8KMWr3o70ucL3x79pXKaIHbBq7JqmyoRGxM,179
127
127
  dnastack/client/datasources/client.py,sha256=jfVzCSKuQJsggbvfJVbftYJ0hd6gAPsBZMgvINOgjRE,4671
128
128
  dnastack/client/datasources/model.py,sha256=QdZ7tn0Zn4BJPGdyRSwGDu2AmsBCg74j7stGZL0pIuU,235
@@ -188,19 +188,19 @@ dnastack/http/session_info.py,sha256=7Fny2U1Zixab4CFGwNsn8Am4tNKYYHF7C1ERG3BhHBI
188
188
  dnastack/http/authenticators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
189
189
  dnastack/http/authenticators/abstract.py,sha256=Q74LnZwsMKs5TfGI_4oZtXBCpgJKkkimkv_Y8YPHuoM,9246
190
190
  dnastack/http/authenticators/constants.py,sha256=mSpBnm5lMMmMJwr13KIfCoOXXJLP4qGDkFprYXALu8o,1278
191
- dnastack/http/authenticators/factory.py,sha256=Kt6PH0-Umfa4ah-Jn8fZthUp2XXKyguhebj3-B0fAZc,2064
192
- dnastack/http/authenticators/oauth2.py,sha256=yZ_bBaIVscDZC25f2vwBptkdcLwX47nFakhL6PW28lM,20071
191
+ dnastack/http/authenticators/factory.py,sha256=zjV5xMZKlkKqUHA2QDXmut-2HxTnqAz8vwxTBEkMg60,2627
192
+ dnastack/http/authenticators/oauth2.py,sha256=FKAoCCt_s9XmtVcOJpdll09XSU-lqxne_VO3zqm2DkE,20066
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
196
  dnastack/http/authenticators/oauth2_adapter/cloud_providers.py,sha256=UHQ-YHHr5ipqSQVzCfr95Uv3zkFcop_RCpK4q6a2yJg,4317
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
- dnastack/http/authenticators/oauth2_adapter/models.py,sha256=Dry1supZCVe4aR_0mGdVry5Ctwnvz_mpa1wsGZYloCw,1048
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.204.dist-info/licenses/LICENSE,sha256=uwybO-wUbQhxkosgjhJlxmYATMy-AzoULFO9FUedE34,11580
202
- dnastack_client_library-3.1.204.dist-info/METADATA,sha256=AhgGt7wY9BE1btWg41L806nbYLLS8LtOAtuD8o4URx0,1761
203
- dnastack_client_library-3.1.204.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
204
- dnastack_client_library-3.1.204.dist-info/entry_points.txt,sha256=Y6OeicsiyGn3-8D-SiV4NiKlJgXfkSqK88kFBR6R1rY,89
205
- dnastack_client_library-3.1.204.dist-info/top_level.txt,sha256=P2RgRyqJ7hfNy1wLVRoVLJYEppUVkCX3syGK9zBqkt8,9
206
- dnastack_client_library-3.1.204.dist-info/RECORD,,
201
+ dnastack_client_library-3.1.207.dist-info/licenses/LICENSE,sha256=uwybO-wUbQhxkosgjhJlxmYATMy-AzoULFO9FUedE34,11580
202
+ dnastack_client_library-3.1.207.dist-info/METADATA,sha256=plCNoaEWQp1W31XbH_9uJFvo-N1vqxKTVHjg0YYfddo,1761
203
+ dnastack_client_library-3.1.207.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
204
+ dnastack_client_library-3.1.207.dist-info/entry_points.txt,sha256=Y6OeicsiyGn3-8D-SiV4NiKlJgXfkSqK88kFBR6R1rY,89
205
+ dnastack_client_library-3.1.207.dist-info/top_level.txt,sha256=P2RgRyqJ7hfNy1wLVRoVLJYEppUVkCX3syGK9zBqkt8,9
206
+ dnastack_client_library-3.1.207.dist-info/RECORD,,