pybioos 0.0.10__py3-none-any.whl → 0.0.11__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.
Potentially problematic release.
This version of pybioos might be problematic. Click here for more details.
- bioos/__about__.py +1 -1
- bioos/bw_import.py +145 -0
- bioos/resource/workflows.py +70 -20
- {pybioos-0.0.10.dist-info → pybioos-0.0.11.dist-info}/METADATA +1 -1
- {pybioos-0.0.10.dist-info → pybioos-0.0.11.dist-info}/RECORD +9 -8
- {pybioos-0.0.10.dist-info → pybioos-0.0.11.dist-info}/entry_points.txt +1 -0
- {pybioos-0.0.10.dist-info → pybioos-0.0.11.dist-info}/LICENSE +0 -0
- {pybioos-0.0.10.dist-info → pybioos-0.0.11.dist-info}/WHEEL +0 -0
- {pybioos-0.0.10.dist-info → pybioos-0.0.11.dist-info}/top_level.txt +0 -0
bioos/__about__.py
CHANGED
bioos/bw_import.py
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding: utf-8
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
from bioos import bioos
|
|
11
|
+
from bioos.config import Config
|
|
12
|
+
from bioos.resource.workflows import WorkflowResource
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_logger():
|
|
16
|
+
"""Setup logger"""
|
|
17
|
+
logger = logging.getLogger('bw_import')
|
|
18
|
+
if not logger.handlers:
|
|
19
|
+
handler = logging.StreamHandler()
|
|
20
|
+
formatter = logging.Formatter(
|
|
21
|
+
'%(asctime)s - %(levelname)s - %(message)s')
|
|
22
|
+
handler.setFormatter(formatter)
|
|
23
|
+
logger.addHandler(handler)
|
|
24
|
+
logger.setLevel(logging.INFO)
|
|
25
|
+
return logger
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def bioos_workflow_import():
|
|
29
|
+
"""Command line entry point"""
|
|
30
|
+
parser = argparse.ArgumentParser(
|
|
31
|
+
description='Bio-OS Workflow Import Tool',
|
|
32
|
+
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
33
|
+
|
|
34
|
+
# 必需参数
|
|
35
|
+
parser.add_argument(
|
|
36
|
+
'--ak',
|
|
37
|
+
required=True,
|
|
38
|
+
help='Access key for your Bio-OS instance platform account')
|
|
39
|
+
parser.add_argument(
|
|
40
|
+
'--sk',
|
|
41
|
+
required=True,
|
|
42
|
+
help='Secret key for your Bio-OS instance platform account')
|
|
43
|
+
parser.add_argument('--workspace_name',
|
|
44
|
+
required=True,
|
|
45
|
+
help='Target workspace name')
|
|
46
|
+
parser.add_argument('--workflow_name',
|
|
47
|
+
required=True,
|
|
48
|
+
help='Name for the workflow to be imported')
|
|
49
|
+
parser.add_argument('--workflow_source',
|
|
50
|
+
required=True,
|
|
51
|
+
help='Local WDL file path or git repository URL')
|
|
52
|
+
|
|
53
|
+
# 可选参数
|
|
54
|
+
parser.add_argument('--workflow_desc',
|
|
55
|
+
help='Description for the workflow',
|
|
56
|
+
default='')
|
|
57
|
+
parser.add_argument(
|
|
58
|
+
'--main_path',
|
|
59
|
+
help='Main workflow file path (required for git repository)',
|
|
60
|
+
default='')
|
|
61
|
+
|
|
62
|
+
args = parser.parse_args()
|
|
63
|
+
logger = get_logger()
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
# 配置Bio-OS
|
|
67
|
+
Config.set_access_key(args.ak)
|
|
68
|
+
Config.set_secret_key(args.sk)
|
|
69
|
+
Config.set_endpoint("https://bio-top.miracle.ac.cn")
|
|
70
|
+
|
|
71
|
+
# 获取workspace ID
|
|
72
|
+
workspaces = bioos.list_workspaces()
|
|
73
|
+
workspace_info = workspaces.query(f"Name=='{args.workspace_name}'")
|
|
74
|
+
if workspace_info.empty:
|
|
75
|
+
logger.error(f"Workspace {args.workspace_name} not found")
|
|
76
|
+
sys.exit(1)
|
|
77
|
+
workspace_id = workspace_info["ID"].iloc[0]
|
|
78
|
+
|
|
79
|
+
# 创建WorkflowResource实例
|
|
80
|
+
workflow_resource = WorkflowResource(workspace_id)
|
|
81
|
+
|
|
82
|
+
# 导入workflow
|
|
83
|
+
try:
|
|
84
|
+
result = workflow_resource.import_workflow(
|
|
85
|
+
source=args.workflow_source,
|
|
86
|
+
name=args.workflow_name,
|
|
87
|
+
description=args.workflow_desc,
|
|
88
|
+
language="WDL",
|
|
89
|
+
main_workflow_path=args.main_path)
|
|
90
|
+
logger.info(
|
|
91
|
+
f"Successfully uploaded workflow: {result}, validating..., please wait..."
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# 循环检查工作流状态
|
|
95
|
+
max_retries = 10 # 最大重试次数
|
|
96
|
+
retry_count = 0
|
|
97
|
+
|
|
98
|
+
while retry_count < max_retries:
|
|
99
|
+
df = workflow_resource.list()
|
|
100
|
+
workflow_info = df[df.Name == args.workflow_name]
|
|
101
|
+
|
|
102
|
+
if len(workflow_info) == 1:
|
|
103
|
+
status = workflow_info.iloc[0]["Status"]["Phase"]
|
|
104
|
+
|
|
105
|
+
if status == "Succeeded":
|
|
106
|
+
logger.info(
|
|
107
|
+
f"Workflow {args.workflow_name} validated successfully"
|
|
108
|
+
)
|
|
109
|
+
sys.exit(0)
|
|
110
|
+
elif status == "Failed":
|
|
111
|
+
logger.error(
|
|
112
|
+
f"Workflow {args.workflow_name} validation failed")
|
|
113
|
+
sys.exit(1)
|
|
114
|
+
elif status == "Importing":
|
|
115
|
+
logger.info(
|
|
116
|
+
f"Workflow {args.workflow_name} is still validating, please wait..."
|
|
117
|
+
)
|
|
118
|
+
time.sleep(30)
|
|
119
|
+
retry_count += 1
|
|
120
|
+
else:
|
|
121
|
+
logger.error(
|
|
122
|
+
f"Workflow {args.workflow_name} has unknown status: {status}"
|
|
123
|
+
)
|
|
124
|
+
sys.exit(1)
|
|
125
|
+
else:
|
|
126
|
+
logger.error(
|
|
127
|
+
f"Workflow {args.workflow_name} not found after upload"
|
|
128
|
+
)
|
|
129
|
+
sys.exit(1)
|
|
130
|
+
|
|
131
|
+
logger.error(
|
|
132
|
+
f"Workflow validation timeout after {max_retries} retries")
|
|
133
|
+
sys.exit(1)
|
|
134
|
+
|
|
135
|
+
except Exception as e:
|
|
136
|
+
logger.error(f"Failed to import workflow: {str(e)}")
|
|
137
|
+
sys.exit(1)
|
|
138
|
+
|
|
139
|
+
except Exception as e:
|
|
140
|
+
logger.error(f"Error: {str(e)}")
|
|
141
|
+
sys.exit(1)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
if __name__ == '__main__':
|
|
145
|
+
bioos_workflow_import()
|
bioos/resource/workflows.py
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import os
|
|
3
|
+
import zipfile
|
|
1
4
|
from datetime import datetime
|
|
5
|
+
from io import BytesIO
|
|
2
6
|
from typing import List
|
|
3
7
|
|
|
4
8
|
import pandas as pd
|
|
@@ -18,6 +22,31 @@ RUN_STATUS = Literal["Succeeded", "Failed", "Running", "Pending"]
|
|
|
18
22
|
WORKFLOW_LANGUAGE = Literal["WDL"]
|
|
19
23
|
|
|
20
24
|
|
|
25
|
+
def zip_files(source_files, zip_type='base64'):
|
|
26
|
+
# 创建一个内存中的字节流对象
|
|
27
|
+
buffer = BytesIO()
|
|
28
|
+
|
|
29
|
+
# 使用 zipfile 模块创建一个 ZIP 文件对象
|
|
30
|
+
with zipfile.ZipFile(buffer, 'w', zipfile.ZIP_DEFLATED,
|
|
31
|
+
compresslevel=9) as zip_file:
|
|
32
|
+
for f in source_files:
|
|
33
|
+
# 将文件添加到 ZIP 中
|
|
34
|
+
# 假设每个 f 是一个字典,包含 'name' 和 'originFile' 键
|
|
35
|
+
zip_file.writestr(f['name'], f['originFile'])
|
|
36
|
+
|
|
37
|
+
# 获取 ZIP 数据
|
|
38
|
+
zip_data = buffer.getvalue()
|
|
39
|
+
|
|
40
|
+
if zip_type == 'base64':
|
|
41
|
+
# 将 ZIP 数据编码为 base64
|
|
42
|
+
return base64.b64encode(zip_data).decode('utf-8')
|
|
43
|
+
elif zip_type == 'blob':
|
|
44
|
+
# 直接返回二进制数据
|
|
45
|
+
return zip_data
|
|
46
|
+
else:
|
|
47
|
+
raise ValueError("zip_type must be 'base64' or 'blob'")
|
|
48
|
+
|
|
49
|
+
|
|
21
50
|
class Run(metaclass=SingletonType): # 单例模式,why
|
|
22
51
|
"""Represents a specific run of submission .
|
|
23
52
|
"""
|
|
@@ -345,11 +374,11 @@ class WorkflowResource(metaclass=SingletonType):
|
|
|
345
374
|
def import_workflow(self,
|
|
346
375
|
source: str,
|
|
347
376
|
name: str,
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
token: str = "") ->
|
|
377
|
+
description: str,
|
|
378
|
+
language: WORKFLOW_LANGUAGE = "WDL",
|
|
379
|
+
tag: str = "",
|
|
380
|
+
main_workflow_path: str = "",
|
|
381
|
+
token: str = "") -> dict:
|
|
353
382
|
"""Imports a workflow .
|
|
354
383
|
|
|
355
384
|
*Example*:
|
|
@@ -387,23 +416,44 @@ class WorkflowResource(metaclass=SingletonType):
|
|
|
387
416
|
else:
|
|
388
417
|
raise ParameterError("name", name)
|
|
389
418
|
|
|
390
|
-
if not (source.startswith("http://") or source.startswith("https://")):
|
|
391
|
-
raise ParameterError("source", source)
|
|
392
419
|
if language != "WDL":
|
|
393
420
|
raise ParameterError("language", language)
|
|
394
421
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
422
|
+
if source.startswith("http://") or source.startswith("https://"):
|
|
423
|
+
params = {
|
|
424
|
+
"WorkspaceID": self.workspace_id,
|
|
425
|
+
"Name": name,
|
|
426
|
+
"Description": description,
|
|
427
|
+
"Language": language,
|
|
428
|
+
"Source": source,
|
|
429
|
+
"Tag": tag,
|
|
430
|
+
"MainWorkflowPath": main_workflow_path,
|
|
431
|
+
"SourceType": "git",
|
|
432
|
+
}
|
|
433
|
+
if token:
|
|
434
|
+
params["Token"] = token
|
|
435
|
+
elif os.path.exists(source):
|
|
436
|
+
source_files = [{
|
|
437
|
+
"name": os.path.basename(source),
|
|
438
|
+
"originFile": open(source, "rb").read()
|
|
439
|
+
}]
|
|
440
|
+
zip_base64 = zip_files(source_files, 'base64')
|
|
441
|
+
|
|
442
|
+
main_workflow_path = os.path.basename(source)
|
|
443
|
+
params = {
|
|
444
|
+
"WorkspaceID": self.workspace_id,
|
|
445
|
+
"Name": name,
|
|
446
|
+
"Description": description,
|
|
447
|
+
"Language": language,
|
|
448
|
+
# "Source": source,
|
|
449
|
+
"SourceType": "file",
|
|
450
|
+
"Content": zip_base64,
|
|
451
|
+
"MainWorkflowPath": main_workflow_path,
|
|
452
|
+
}
|
|
453
|
+
else:
|
|
454
|
+
raise ParameterError("source", source)
|
|
455
|
+
|
|
456
|
+
return Config.service().create_workflow(params)
|
|
407
457
|
|
|
408
458
|
def list(self) -> DataFrame:
|
|
409
459
|
"""Lists all workflows' information .
|
|
@@ -430,7 +480,7 @@ class WorkflowResource(metaclass=SingletonType):
|
|
|
430
480
|
res_df['UpdateTime'] = pd.to_datetime(
|
|
431
481
|
res_df['UpdateTime'], unit='ms', origin=pd.Timestamp('2018-07-01'))
|
|
432
482
|
|
|
433
|
-
return res_df
|
|
483
|
+
return res_df
|
|
434
484
|
|
|
435
485
|
def delete(self, target: str):
|
|
436
486
|
"""Deletes a workflow from the workspace .
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
bioos/__about__.py,sha256=
|
|
1
|
+
bioos/__about__.py,sha256=CQkBh68geNlt0TyhyDWhAJZD8BGTGXo4PMLurVugwKo,57
|
|
2
2
|
bioos/__init__.py,sha256=4GZKi13lDTD25YBkGakhZyEQZWTER_OWQMNPoH_UM2c,22
|
|
3
3
|
bioos/bioos.py,sha256=fHzOb1l5wYxw6NVYYZDiFcgk4V28BAgWEc3ev12reWs,2409
|
|
4
4
|
bioos/bioos_workflow.py,sha256=LbKxK7Otzj9apJciI3jg_cfh92x9aZGlUyN5ZRAdZeU,14127
|
|
5
|
+
bioos/bw_import.py,sha256=VFG-RWZL_0cuZPYCxapzDn8EFqT2mFFsykBt6hG9wGM,4860
|
|
5
6
|
bioos/config.py,sha256=CvFabYqV1BkFWO8fnr5vBf6xNtNzA8hAEVeEIbvAOm8,4307
|
|
6
7
|
bioos/errors.py,sha256=Lzz2rkjDOTR2X9CnVkmsmqeOgmNqbi46WAxnC6LEGm0,2459
|
|
7
8
|
bioos/log.py,sha256=twiCvf5IgJB7uvzANwBluSlztJN8ZrxbGZUBGlZ0vps,3204
|
|
@@ -13,7 +14,7 @@ bioos/resource/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
|
13
14
|
bioos/resource/data_models.py,sha256=enKp8yyQI8IbRqe--0Xtyg1XzOwQQPQzoQsx_hNuZ6E,5089
|
|
14
15
|
bioos/resource/files.py,sha256=1HY0IHvq8H843VM2XZIHDdCuXXNcMrlEFhSNqWXmFzE,8456
|
|
15
16
|
bioos/resource/utility.py,sha256=emY7qVLLLvGmQYlVj-_bLAxU7i1GfQOUybdRkfEDwVA,1300
|
|
16
|
-
bioos/resource/workflows.py,sha256=
|
|
17
|
+
bioos/resource/workflows.py,sha256=DUAwq0AE7FZbnb5iJUGEKC5XzGFl_CcJy7Sh0KO-EvM,21387
|
|
17
18
|
bioos/resource/workspaces.py,sha256=Gmr8y_sjK7TQbhMhQ_7rxqR1KFcwU72I95YYCFrrLBQ,3995
|
|
18
19
|
bioos/service/BioOsService.py,sha256=HuYUEwomHCLpA1MYgVqGyWAQWHM-_BHB-jmy9VsOlnQ,6724
|
|
19
20
|
bioos/service/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
@@ -30,9 +31,9 @@ bioos/tests/workspaces.py,sha256=LuuRrTs2XqfE5mGQyJNl9RBtuMb4NZHBJFoO8HMZVYQ,522
|
|
|
30
31
|
bioos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
32
|
bioos/utils/common_tools.py,sha256=fgMoE_-qZjgfQtUj_pmCTyYDtbJasyfH4Gm3VQsbgBQ,1651
|
|
32
33
|
bioos/utils/workflows.py,sha256=zRbwTUigoM5V5LFOgzQPm3kwxt5Ogz95OFfefJc6Fjo,133
|
|
33
|
-
pybioos-0.0.
|
|
34
|
-
pybioos-0.0.
|
|
35
|
-
pybioos-0.0.
|
|
36
|
-
pybioos-0.0.
|
|
37
|
-
pybioos-0.0.
|
|
38
|
-
pybioos-0.0.
|
|
34
|
+
pybioos-0.0.11.dist-info/LICENSE,sha256=cPkGXsgfPgEhIns7Lt3Avxx0Uy-VbdsoP8jvNGuj3cE,1063
|
|
35
|
+
pybioos-0.0.11.dist-info/METADATA,sha256=30fgMYG5pN8_Jn_bY-utOWWXW7TmzgBzmsc3Mz3GCfA,830
|
|
36
|
+
pybioos-0.0.11.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92
|
|
37
|
+
pybioos-0.0.11.dist-info/entry_points.txt,sha256=G8eh4umiCimlV9nNNeyA3vqLyG3jfUj8uVNrgvAuhAM,110
|
|
38
|
+
pybioos-0.0.11.dist-info/top_level.txt,sha256=llpzydkKVDSaWZgz3bsTUsQmhoQpc_JcRJg2-H-5a2U,6
|
|
39
|
+
pybioos-0.0.11.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|