seqslab-cli 3.3.2.post1__tar.gz → 3.3.3__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.
Files changed (108) hide show
  1. {seqslab-cli-3.3.2.post1/python/seqslab_cli.egg-info → seqslab-cli-3.3.3}/PKG-INFO +1 -1
  2. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/__init__.py +1 -1
  3. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/api/azure.py +12 -0
  4. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/api/base.py +2 -2
  5. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/commands.py +3 -3
  6. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/template/base.py +28 -1
  7. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/user/resource/base.py +3 -1
  8. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/wes/commands.py +100 -5
  9. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/wes/internal/parameters.py +26 -6
  10. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/wes/resource/base.py +34 -0
  11. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/wes/template/base.py +7 -2
  12. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3/python/seqslab_cli.egg-info}/PKG-INFO +1 -1
  13. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab_cli.egg-info/requires.txt +5 -5
  14. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/requirements.txt +5 -5
  15. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/LICENSE +0 -0
  16. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/MANIFEST.in +0 -0
  17. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/README.md +0 -0
  18. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/auth/__init__.py +0 -0
  19. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/auth/azuread.py +0 -0
  20. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/auth/commands.py +0 -0
  21. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/cli.py +0 -0
  22. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/context.py +0 -0
  23. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/__init__.py +0 -0
  24. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/api/__init__.py +0 -0
  25. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/api/common.py +0 -0
  26. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/api/template.py +0 -0
  27. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/internal/__init__.py +0 -0
  28. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/internal/aiocopy.py +0 -0
  29. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/internal/common.py +0 -0
  30. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/internal/utils.py +0 -0
  31. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/storage/__init__.py +0 -0
  32. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/storage/azure.py +0 -0
  33. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/storage/base.py +0 -0
  34. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/utils/__init__.py +0 -0
  35. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/utils/atgxmetadata.py +0 -0
  36. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/utils/biomimetype.py +0 -0
  37. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/drs/utils/progressbar.py +0 -0
  38. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/exceptions.py +0 -0
  39. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/organization/__init__.py +0 -0
  40. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/organization/commands.py +0 -0
  41. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/organization/resource/__init__.py +0 -0
  42. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/organization/resource/base.py +0 -0
  43. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/plugin.py +0 -0
  44. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/role/__init__.py +0 -0
  45. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/role/commands.py +0 -0
  46. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/role/internal/__init__.py +0 -0
  47. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/role/internal/common.py +0 -0
  48. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/role/resource/__init__.py +0 -0
  49. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/role/resource/azure.py +0 -0
  50. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/role/resource/base.py +0 -0
  51. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/runsheet/__init__.py +0 -0
  52. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/runsheet/runsheet.py +0 -0
  53. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/sample_sheet/__init__.py +0 -0
  54. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/sample_sheet/_version.py +0 -0
  55. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/sample_sheet/util.py +0 -0
  56. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/scr/__init__.py +0 -0
  57. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/scr/commands.py +0 -0
  58. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/scr/internal/__init__.py +0 -0
  59. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/scr/internal/common.py +0 -0
  60. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/scr/resource/__init__.py +0 -0
  61. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/scr/resource/azure.py +0 -0
  62. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/scr/resource/base.py +0 -0
  63. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/session_logger.py +0 -0
  64. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/settings.py +0 -0
  65. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/statusbar.py +0 -0
  66. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/__init__.py +0 -0
  67. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/commands.py +0 -0
  68. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/internal/__init__.py +0 -0
  69. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/internal/utils.py +0 -0
  70. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/register/__init__.py +0 -0
  71. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/register/azure.py +0 -0
  72. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/register/base.py +0 -0
  73. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/register/common.py +0 -0
  74. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/register/template.py +0 -0
  75. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/resource/__init__.py +0 -0
  76. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/resource/azure.py +0 -0
  77. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/resource/base.py +0 -0
  78. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/resource/common.py +0 -0
  79. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/template/__init__.py +0 -0
  80. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/trs/template/template.py +0 -0
  81. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/usage_logger.py +0 -0
  82. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/user/__init__.py +0 -0
  83. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/user/commands.py +0 -0
  84. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/user/internal/__init__.py +0 -0
  85. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/user/internal/common.py +0 -0
  86. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/user/resource/__init__.py +0 -0
  87. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/user/resource/azure.py +0 -0
  88. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/wes/__init__.py +0 -0
  89. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/wes/internal/__init__.py +0 -0
  90. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/wes/internal/common.py +0 -0
  91. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/wes/resource/__init__.py +0 -0
  92. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/wes/resource/azure.py +0 -0
  93. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/wes/template/__init__.py +0 -0
  94. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/wes/template/template.py +0 -0
  95. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/workspace/__init__.py +0 -0
  96. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/workspace/commands.py +0 -0
  97. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/workspace/internal/__init__.py +0 -0
  98. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/workspace/internal/common.py +0 -0
  99. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/workspace/resource/__init__.py +0 -0
  100. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/workspace/resource/azure.py +0 -0
  101. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab/workspace/resource/base.py +0 -0
  102. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab_cli.egg-info/SOURCES.txt +0 -0
  103. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab_cli.egg-info/dependency_links.txt +0 -0
  104. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab_cli.egg-info/entry_points.txt +0 -0
  105. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab_cli.egg-info/top_level.txt +0 -0
  106. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/python/seqslab_cli.egg-info/zip-safe +0 -0
  107. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/setup.cfg +0 -0
  108. {seqslab-cli-3.3.2.post1 → seqslab-cli-3.3.3}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: seqslab-cli
3
- Version: 3.3.2.post1
3
+ Version: 3.3.3
4
4
  Summary: Atgenomix SeqsLab Command Line Tool
5
5
  Home-page: https://github.com/AnomeGAP/seqslab-cli
6
6
  Author: Allen Chang
@@ -21,6 +21,6 @@ name = "seqslab"
21
21
  __all__ = []
22
22
 
23
23
 
24
- __version__ = "3.3.2.post1"
24
+ __version__ = "3.3.3"
25
25
 
26
26
  LOGGING = {"DIR_PATH": "/var/log/seqslab"}
@@ -8,6 +8,7 @@ from typing import List
8
8
  import requests
9
9
  from nubia import context
10
10
  from seqslab.auth.commands import BaseAuth
11
+ from seqslab.drs.storage.azure import BlobStorage
11
12
  from seqslab.drs.utils.biomimetype import get_mime_type
12
13
  from tenacity import retry, stop_after_attempt, wait_fixed
13
14
  from termcolor import cprint
@@ -396,3 +397,14 @@ class AzureDRSregister(DRSregister):
396
397
  )
397
398
 
398
399
  return dsts_list
400
+
401
+ def common_root(self, dsts: List[URL], **kwargs) -> str:
402
+ root_dst = super().common_root(dsts)
403
+ blob_root = BlobStorage(kwargs.get("workspace")).get_token(path=None)[
404
+ "register_url"
405
+ ]
406
+ if URL(root_dst).path == URL(blob_root).path:
407
+ raise ValueError(
408
+ "access_url pointing to cloud storage root path is not allowed"
409
+ )
410
+ return root_dst
@@ -335,7 +335,7 @@ class DRSregister:
335
335
  folder_stdin["access_methods"].append(access_method_infos[i])
336
336
  folder_stdin["access_methods"][i]["access_url"][
337
337
  "url"
338
- ] = self.common_root(dsts=dsts)
338
+ ] = self.common_root(dsts=dsts, workspace=kwargs.get("workspace"))
339
339
 
340
340
  folder_stdin["name"] = kwargs.get(
341
341
  "name",
@@ -360,7 +360,7 @@ class DRSregister:
360
360
  raise ValueError("Make sure all the sizes are filled.")
361
361
  return sum(sizes)
362
362
 
363
- def common_root(self, dsts: List[URL]) -> str:
363
+ def common_root(self, dsts: List[URL], **kwargs) -> str:
364
364
  """
365
365
  e.g. http://user:password@example.com:8042/over/there?name=ferret#nose
366
366
  URL.scheme: http
@@ -173,7 +173,7 @@ class BaseDatahub:
173
173
  "dst",
174
174
  type=str,
175
175
  positional=False,
176
- description="Specify the destination directory, file path, or DRS URL (optional, default =' /'). ",
176
+ description="Specify the destination directory, file path, or DRS URL (optional, default ='MyDir/'). ",
177
177
  )
178
178
  @argument(
179
179
  "recursive",
@@ -223,7 +223,7 @@ class BaseDatahub:
223
223
  self,
224
224
  workspace: str,
225
225
  src: str,
226
- dst: str = "/",
226
+ dst: str = "MyDir/",
227
227
  recursive: bool = False,
228
228
  output: str = "json",
229
229
  concurrency: int = 0,
@@ -706,7 +706,7 @@ class BaseDatahub:
706
706
  backend = drs_register().load_register(workspace)
707
707
  if stdin:
708
708
  payloads = backend.create_payload(
709
- stdin=BaseDatahub._stdin(), type=drs_type, **kwargs
709
+ stdin=BaseDatahub._stdin(), type=drs_type, workspace=workspace, **kwargs
710
710
  )
711
711
  else:
712
712
  if not kwargs["is_integrity"]:
@@ -1,4 +1,5 @@
1
1
  # Standard Library
2
+ import re
2
3
  from typing import List
3
4
 
4
5
  import pydot
@@ -21,7 +22,7 @@ class TrsCreateTemplate:
21
22
  primary_descriptor=primary_descriptor, zip_file=zip_file
22
23
  )
23
24
  workflow = self.desc_template(parameter)
24
- calls = self.call_template(parameter)
25
+ calls = self.workflow_call_template(parameter)
25
26
  inputs_connections = self.inputs_connections(
26
27
  parameter=parameter, inputs_json=inputs_json
27
28
  )
@@ -58,6 +59,32 @@ class TrsCreateTemplate:
58
59
  calls.add(node.get_name().replace("CALL_", ""))
59
60
  return calls
60
61
 
62
+ def workflow_call_template(self, parameter: dict) -> list:
63
+ # adding main workflow
64
+ runtime_cell_select = [
65
+ pydot.graph_from_dot_data(
66
+ TrsCreateTemplate.dot_cleaning(parameter["graph"])
67
+ )[0].get_name()
68
+ ]
69
+
70
+ # parsing workflow>call information from graph string
71
+ graphRex = re.compile(r'graph\s\w+|}|label="call\s\w+', re.IGNORECASE)
72
+ wnames = []
73
+ matches = graphRex.findall(parameter.get("graph"))
74
+ if matches:
75
+ for e in matches:
76
+ if e.startswith("graph "):
77
+ wnames.append(e.split(" ")[1].replace("cluster_", ""))
78
+ elif e.startswith("}"):
79
+ wnames.pop()
80
+ elif e.startswith("label="):
81
+ call = e.replace('label="', "").strip('"')
82
+ if call.lower().startswith("call"):
83
+ runtime_cell_select.append(
84
+ "" + wnames[-1] + ">" + call.replace("call ", "")
85
+ )
86
+ return runtime_cell_select
87
+
61
88
  def call_template(self, parameter: dict) -> list:
62
89
  calls = [
63
90
  pydot.graph_from_dot_data(
@@ -112,7 +112,9 @@ class BaseResource:
112
112
  def is_global_admin(self, **kwargs) -> bool:
113
113
  token = BaseAuth.get_token()
114
114
  response = self.get_user(token.get("attrs").get("user_id"))
115
- if "Global administrator" in response.get("roles"):
115
+ if "Global administrator" in [
116
+ item.get("name") for item in response.get("roles")
117
+ ]:
116
118
  return True
117
119
 
118
120
  return False
@@ -458,11 +458,11 @@ class BaseJobs:
458
458
  @argument(
459
459
  "runtimes",
460
460
  type=str,
461
- description="Key:value pairs indicating the workflow name -> SeqsLab supported runtime_options names. "
462
- "Multiple configuration pairs can be provided using ':' as separator, "
463
- "e.g. main=m4-cluster:subworkflow=m4-8xcluster "
464
- "(optional, default = None, which indicates running the whole workflow.wdl using m4-cluster for "
465
- "a single node cluster on the Azure backend).",
461
+ description="String of key-value pairs using : as a separator, indicating the execution runtimes for each task "
462
+ "or workflow defined in workflow-url. For example, Main=m4-cluster:Main>Fq2Bam=m4-8xcluster. To "
463
+ "list tasks/workflows for a given workflow, use the execs command. To find available runtime "
464
+ "options, use the request runtimes_options command. (Optional, defaults to None, which runs the "
465
+ "entire workflow using m4-cluster.)",
466
466
  )
467
467
  @argument(
468
468
  "integrity",
@@ -661,6 +661,101 @@ class BaseJobs:
661
661
 
662
662
  return 0
663
663
 
664
+ @command(aliases=["rt"])
665
+ @argument(
666
+ "page",
667
+ type=int,
668
+ positional=False,
669
+ description="Specify the page number in the set of paginated records (optional, default = 1).",
670
+ )
671
+ @argument(
672
+ "page_size",
673
+ type=int,
674
+ positional=False,
675
+ description="Specify the number of records to return in each page (optional, default = 10).",
676
+ )
677
+ @command
678
+ @argument(
679
+ "output",
680
+ type=str,
681
+ positional=False,
682
+ description="Specify the output format of the stdout file (optional, default = json).",
683
+ choices=["json", "table"],
684
+ )
685
+ def runtime_options(
686
+ self, workspace: str, page: int = 1, page_size: int = 10, output="json"
687
+ ) -> int:
688
+ """
689
+ List registered cluster runtimes settings.
690
+ """
691
+ resource = get_factory().load_resource(workspace)
692
+ r = resource.list_runtime_options(page=page, page_size=page_size)
693
+
694
+ if isinstance(r, int):
695
+ return r
696
+
697
+ self._stdout(r["results"], output)
698
+ return 0
699
+
700
+ @command(aliases=["op"])
701
+ @argument(
702
+ "page",
703
+ type=int,
704
+ positional=False,
705
+ description="Specify the page number in the set of paginated records (optional, default = 1).",
706
+ )
707
+ @argument(
708
+ "page_size",
709
+ type=int,
710
+ positional=False,
711
+ description="Specify the number of records to return in each page (optional, default = 10).",
712
+ )
713
+ @command
714
+ @argument(
715
+ "output",
716
+ type=str,
717
+ positional=False,
718
+ description="Specify the output format of the stdout file (optional, default = json).",
719
+ choices=["json", "table"],
720
+ )
721
+ def operator_pipelines(
722
+ self, workspace: str, page: int = 1, page_size: int = 10, output="json"
723
+ ) -> int:
724
+ """
725
+ List registered operator pipelines.
726
+ """
727
+ resource = get_factory().load_resource(workspace)
728
+ r = resource.list_runtime_options(page=page, page_size=page_size)
729
+
730
+ if isinstance(r, int):
731
+ return r
732
+
733
+ self._stdout(r["results"], output)
734
+ return 0
735
+
736
+ @staticmethod
737
+ def _stdout(results, output: str) -> int:
738
+ # Standard Library
739
+ import csv
740
+ from io import StringIO
741
+
742
+ from tabulate import tabulate
743
+
744
+ """
745
+ stdout:: TODO: support different format ex: json, tsv, table
746
+ """
747
+ if output == "json":
748
+ cprint(json.dumps(results, indent=4))
749
+ elif output == "table":
750
+ table_header = list(results[0].keys())
751
+ table_datas = [result.values() for result in results]
752
+ cprint(
753
+ tabulate(
754
+ tabular_data=table_datas, headers=table_header, tablefmt="pipe"
755
+ )
756
+ )
757
+ return 0
758
+
664
759
 
665
760
  @command
666
761
  class Jobs(BaseJobs):
@@ -230,13 +230,33 @@ def workflow_backend_params(
230
230
  raise RuntimeError(
231
231
  f"given call name {k} not in TRS registered call name list {calls}!"
232
232
  )
233
- clusters.append(
234
- WorkflowBackendParamsClusterTemplate(
235
- run_time=resource.get_runtime_setting(v),
236
- workflow_name=k,
237
- kernel_version=kernel_version,
233
+
234
+ # general workflow>call handling
235
+ ids = k.split(">")
236
+ if len(ids) == 2:
237
+ clusters.append(
238
+ WorkflowBackendParamsClusterTemplate(
239
+ run_time=resource.get_runtime_setting(v),
240
+ call_name=ids[1],
241
+ workflow_name=ids[0],
242
+ kernel_version=kernel_version,
243
+ )
238
244
  )
239
- )
245
+ else:
246
+ # main workflow name
247
+ if k == primary_workflow_name:
248
+ clusters.append(
249
+ WorkflowBackendParamsClusterTemplate(
250
+ run_time=resource.get_runtime_setting(v),
251
+ call_name=k,
252
+ kernel_version=kernel_version,
253
+ )
254
+ )
255
+ else:
256
+ # raise exception for incorrect format of k
257
+ raise RuntimeError(
258
+ f"given identifier {k} does not in format of in TRS registered call name list {calls}!"
259
+ )
240
260
 
241
261
  bk_template = WorkflowBackendParamsTemplate(
242
262
  graph=execs.get("graph"),
@@ -50,6 +50,8 @@ class BaseResource(ABC):
50
50
  WES_RUNS_DRY_URL = f"{WES_BASE_URL}runs/dryrun/?backend={{backend}}"
51
51
  WES_RUNS_FILE_URL = f"{WES_BASE_URL}runs/{{id}}/files/?backend={{backend}}"
52
52
  WES_RUNS_STATUS_URL = f"{WES_BASE_URL}runs/{{id}}/status/?backend={{backend}}"
53
+ WES_RUNTIME_OPTIONS_BASE_URL = f"{WES_BASE_URL}runtime-options/"
54
+ WES_OPERATOR_PIPELINES_BASE_URL = f"{WES_BASE_URL}operator-pipelines/"
53
55
  WES_RUNTIME_OPTIONS_URL = (
54
56
  f"{WES_BASE_URL}runtime-options/{{name}}?backend={{backend}}"
55
57
  )
@@ -310,3 +312,35 @@ class BaseResource(ABC):
310
312
  if response.status_code not in [requests.codes.ok]:
311
313
  raise requests.HTTPError(response.text)
312
314
  return json.loads(response.content)
315
+
316
+ def list_runtime_options(self, page=1, page_size=10):
317
+ try:
318
+ token = BaseAuth.get_token().get("tokens").get("access")
319
+ with requests.get(
320
+ url=f"{self.WES_RUNTIME_OPTIONS_BASE_URL}?page={page}&page_size={page_size}",
321
+ headers={"Authorization": f"Bearer {token}"},
322
+ ) as response:
323
+ if response.status_code not in [requests.codes.ok]:
324
+ raise requests.HTTPError(
325
+ f"{response.status_code}: {repr(response.text)}"
326
+ )
327
+ except Exception as err:
328
+ print(err)
329
+ raise err
330
+ return response.json()
331
+
332
+ def list_operator_pipelines(self, page=1, page_size=10):
333
+ try:
334
+ token = BaseAuth.get_token().get("tokens").get("access")
335
+ with requests.get(
336
+ url=f"{self.WES_OPERATOR_PIPELINES_BASE_URL}?page={page}&page_size={page_size}",
337
+ headers={"Authorization": f"Bearer {token}"},
338
+ ) as response:
339
+ if response.status_code not in [requests.codes.ok]:
340
+ raise requests.HTTPError(
341
+ f"{response.status_code}: {repr(response.text)}"
342
+ )
343
+ except Exception as err:
344
+ print(err)
345
+ raise err
346
+ return response.json()
@@ -34,6 +34,8 @@ class WorkflowParamsTemplate:
34
34
  tasks = {}
35
35
  pl_keys = [pipeline["id"] for pipeline in ex_template["operator_pipelines"]]
36
36
  for k, v in dict(ex_template["i_configs"], **ex_template["o_configs"]).items():
37
+ if not v:
38
+ continue
37
39
  assert (
38
40
  v in pl_keys
39
41
  ), f"given operator pipeline ID {v} for FQN {k} not in operator pipeline list from execs: {pl_keys}"
@@ -113,11 +115,14 @@ def WorkflowBackendParamsTemplate(
113
115
 
114
116
 
115
117
  def WorkflowBackendParamsClusterTemplate(
116
- run_time: dict, workflow_name: str, kernel_version: str
118
+ run_time: dict, call_name: str, kernel_version: str, workflow_name: str = ""
117
119
  ) -> dict:
118
120
  if kernel_version:
119
121
  opts = run_time["options"]
120
122
  opts.append(f"seqslab.kernel.version {kernel_version}")
121
123
  run_time.update({"options": opts})
122
- run_time.update({"call": workflow_name})
124
+ if workflow_name:
125
+ run_time.update({"call": call_name, "workflow": workflow_name})
126
+ else:
127
+ run_time.update({"call": call_name})
123
128
  return run_time
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: seqslab-cli
3
- Version: 3.3.2.post1
3
+ Version: 3.3.3
4
4
  Summary: Atgenomix SeqsLab Command Line Tool
5
5
  Home-page: https://github.com/AnomeGAP/seqslab-cli
6
6
  Author: Allen Chang
@@ -2,7 +2,7 @@ pip>=22.0.4
2
2
  click==8.1.7
3
3
  tabulate==0.9.0
4
4
  terminaltables==3.1.10
5
- cryptography==41.0.7
5
+ cryptography==42.0.6
6
6
  jeepney==0.8.0
7
7
  secretstorage==3.3.3
8
8
  dbus-python==1.2.16
@@ -12,7 +12,7 @@ python-nubia==0.2b5
12
12
  msal==1.26.0
13
13
  tenacity==8.2.3
14
14
  aiofiles==23.2.1
15
- aiohttp[speedups]==3.9.1
15
+ aiohttp[speedups]==3.9.5
16
16
  aioretry==5.0.2
17
17
  uvloop==0.19.0
18
18
  arrow==1.3.0
@@ -22,9 +22,9 @@ PyJWT==2.8.0
22
22
  django-environ==0.11.2
23
23
  validators==0.22.0
24
24
  pydot==2.0.0
25
- orjson==3.9.10
26
- pydantic~=2.5.3
25
+ orjson==3.10.3
26
+ pydantic~=2.7.1
27
27
  aiohttp_retry==2.8.3
28
28
  requests~=2.31.0
29
- setuptools~=69.0.3
29
+ setuptools~=69.5.1
30
30
  jsonpath-ng==1.6.0
@@ -1,4 +1,4 @@
1
- cryptography==41.0.7
1
+ cryptography==42.0.6
2
2
  jeepney==0.8.0
3
3
  secretstorage==3.3.3
4
4
  dbus-python==1.2.16
@@ -8,7 +8,7 @@ python-nubia==0.2b5
8
8
  msal==1.26.0
9
9
  tenacity==8.2.3
10
10
  aiofiles==23.2.1
11
- aiohttp[speedups]==3.9.1
11
+ aiohttp[speedups]==3.9.5
12
12
  aioretry==5.0.2
13
13
  uvloop==0.19.0
14
14
  arrow==1.3.0
@@ -18,9 +18,9 @@ PyJWT==2.8.0
18
18
  django-environ==0.11.2
19
19
  validators==0.22.0
20
20
  pydot==2.0.0
21
- orjson==3.9.10
22
- pydantic~=2.5.3
21
+ orjson==3.10.3
22
+ pydantic~=2.7.1
23
23
  aiohttp_retry==2.8.3
24
24
  requests~=2.31.0
25
- setuptools~=69.0.3
25
+ setuptools~=69.5.1
26
26
  jsonpath-ng==1.6.0
File without changes
File without changes
File without changes
File without changes