virtool-workflow 7.2.0__py3-none-any.whl → 7.2.2__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.
- virtool_workflow/__init__.py +1 -0
- virtool_workflow/analysis/fastqc.py +2 -2
- virtool_workflow/api/client.py +22 -9
- virtool_workflow/api/utils.py +66 -32
- virtool_workflow/cli.py +1 -0
- virtool_workflow/data/hmms.py +4 -8
- virtool_workflow/data/indexes.py +1 -3
- virtool_workflow/runtime/discover.py +5 -1
- virtool_workflow/runtime/hook.py +3 -1
- virtool_workflow/runtime/ping.py +1 -0
- virtool_workflow/runtime/run.py +7 -4
- virtool_workflow/workflow.py +6 -3
- {virtool_workflow-7.2.0.dist-info → virtool_workflow-7.2.2.dist-info}/METADATA +6 -6
- {virtool_workflow-7.2.0.dist-info → virtool_workflow-7.2.2.dist-info}/RECORD +17 -17
- {virtool_workflow-7.2.0.dist-info → virtool_workflow-7.2.2.dist-info}/LICENSE +0 -0
- {virtool_workflow-7.2.0.dist-info → virtool_workflow-7.2.2.dist-info}/WHEEL +0 -0
- {virtool_workflow-7.2.0.dist-info → virtool_workflow-7.2.2.dist-info}/entry_points.txt +0 -0
virtool_workflow/__init__.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"""Utilities and fixtures for running FastQC."""
|
2
|
+
|
2
3
|
from __future__ import annotations
|
3
4
|
|
4
5
|
import asyncio
|
@@ -424,8 +425,7 @@ def _parse_fastqc(fastqc_path: Path, output_path: Path) -> dict:
|
|
424
425
|
class FastQCRunner(Protocol):
|
425
426
|
"""A protocol describing callables that can be used to run FastQC."""
|
426
427
|
|
427
|
-
async def __call__(self, paths: ReadPaths, output_path: Path) -> dict:
|
428
|
-
...
|
428
|
+
async def __call__(self, paths: ReadPaths, output_path: Path) -> dict: ...
|
429
429
|
|
430
430
|
|
431
431
|
@fixture
|
virtool_workflow/api/client.py
CHANGED
@@ -3,15 +3,18 @@ from pathlib import Path
|
|
3
3
|
|
4
4
|
import aiofiles
|
5
5
|
from aiohttp import BasicAuth, ClientSession
|
6
|
+
from structlog import get_logger
|
6
7
|
|
7
8
|
from virtool_workflow.api.utils import (
|
9
|
+
API_CHUNK_SIZE,
|
8
10
|
decode_json_response,
|
9
11
|
raise_exception_by_status_code,
|
12
|
+
retry,
|
10
13
|
)
|
11
14
|
from virtool_workflow.errors import JobsAPIError
|
12
15
|
from virtool_workflow.files import VirtoolFileFormat
|
13
16
|
|
14
|
-
|
17
|
+
logger = get_logger("http")
|
15
18
|
|
16
19
|
|
17
20
|
class APIClient:
|
@@ -19,26 +22,29 @@ class APIClient:
|
|
19
22
|
self.http = http
|
20
23
|
self.jobs_api_connection_string = jobs_api_connection_string
|
21
24
|
|
25
|
+
@retry
|
22
26
|
async def get_json(self, path: str) -> dict:
|
23
27
|
"""Get the JSON response from the provided API ``path``."""
|
24
28
|
async with self.http.get(f"{self.jobs_api_connection_string}{path}") as resp:
|
25
29
|
await raise_exception_by_status_code(resp)
|
26
30
|
return await decode_json_response(resp)
|
27
31
|
|
32
|
+
@retry
|
28
33
|
async def get_file(self, path: str, target_path: Path):
|
29
|
-
"""Download the file at URL ``path`` to the local
|
30
|
-
"""
|
34
|
+
"""Download the file at URL ``path`` to the local ``target_path``."""
|
31
35
|
async with self.http.get(f"{self.jobs_api_connection_string}{path}") as resp:
|
32
36
|
if resp.status != 200:
|
33
37
|
raise JobsAPIError(
|
34
38
|
f"Encountered {resp.status} while downloading '{path}'",
|
35
39
|
)
|
40
|
+
|
36
41
|
async with aiofiles.open(target_path, "wb") as f:
|
37
|
-
async for chunk in resp.content.iter_chunked(
|
42
|
+
async for chunk in resp.content.iter_chunked(API_CHUNK_SIZE):
|
38
43
|
await f.write(chunk)
|
39
44
|
|
40
45
|
return target_path
|
41
46
|
|
47
|
+
@retry
|
42
48
|
async def patch_json(self, path: str, data: dict) -> dict:
|
43
49
|
"""Make a patch request against the provided API ``path`` and return the response
|
44
50
|
as a dictionary of decoded JSON.
|
@@ -48,11 +54,13 @@ class APIClient:
|
|
48
54
|
:return: the response as a dictionary of decoded JSON
|
49
55
|
"""
|
50
56
|
async with self.http.patch(
|
51
|
-
f"{self.jobs_api_connection_string}{path}",
|
57
|
+
f"{self.jobs_api_connection_string}{path}",
|
58
|
+
json=data,
|
52
59
|
) as resp:
|
53
60
|
await raise_exception_by_status_code(resp)
|
54
61
|
return await decode_json_response(resp)
|
55
62
|
|
63
|
+
@retry
|
56
64
|
async def post_file(
|
57
65
|
self,
|
58
66
|
path: str,
|
@@ -73,13 +81,16 @@ class APIClient:
|
|
73
81
|
) as response:
|
74
82
|
await raise_exception_by_status_code(response)
|
75
83
|
|
84
|
+
@retry
|
76
85
|
async def post_json(self, path: str, data: dict) -> dict:
|
77
86
|
async with self.http.post(
|
78
|
-
f"{self.jobs_api_connection_string}{path}",
|
87
|
+
f"{self.jobs_api_connection_string}{path}",
|
88
|
+
json=data,
|
79
89
|
) as resp:
|
80
90
|
await raise_exception_by_status_code(resp)
|
81
91
|
return await decode_json_response(resp)
|
82
92
|
|
93
|
+
@retry
|
83
94
|
async def put_file(
|
84
95
|
self,
|
85
96
|
path: str,
|
@@ -100,13 +111,16 @@ class APIClient:
|
|
100
111
|
) as response:
|
101
112
|
await raise_exception_by_status_code(response)
|
102
113
|
|
114
|
+
@retry
|
103
115
|
async def put_json(self, path: str, data: dict) -> dict:
|
104
116
|
async with self.http.put(
|
105
|
-
f"{self.jobs_api_connection_string}{path}",
|
117
|
+
f"{self.jobs_api_connection_string}{path}",
|
118
|
+
json=data,
|
106
119
|
) as resp:
|
107
120
|
await raise_exception_by_status_code(resp)
|
108
121
|
return await decode_json_response(resp)
|
109
122
|
|
123
|
+
@retry
|
110
124
|
async def delete(self, path: str) -> dict | None:
|
111
125
|
"""Make a delete request against the provided API ``path``."""
|
112
126
|
async with self.http.delete(f"{self.jobs_api_connection_string}{path}") as resp:
|
@@ -124,8 +138,7 @@ async def api_client(
|
|
124
138
|
job_id: str,
|
125
139
|
key: str,
|
126
140
|
):
|
127
|
-
"""An authenticated :class:``APIClient`` to make requests against the jobs API.
|
128
|
-
"""
|
141
|
+
"""An authenticated :class:``APIClient`` to make requests against the jobs API."""
|
129
142
|
async with ClientSession(
|
130
143
|
auth=BasicAuth(login=f"job-{job_id}", password=key),
|
131
144
|
) as http:
|
virtool_workflow/api/utils.py
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
import asyncio
|
2
|
-
import
|
2
|
+
from functools import wraps
|
3
3
|
|
4
4
|
from aiohttp import (
|
5
|
-
|
5
|
+
ClientError,
|
6
6
|
ClientResponse,
|
7
7
|
ContentTypeError,
|
8
|
-
ServerDisconnectedError,
|
9
8
|
)
|
10
9
|
from structlog import get_logger
|
11
10
|
|
@@ -19,40 +18,76 @@ from virtool_workflow.errors import (
|
|
19
18
|
|
20
19
|
logger = get_logger("api")
|
21
20
|
|
21
|
+
API_CHUNK_SIZE = 1024 * 1024 * 2
|
22
|
+
"""The size of chunks to use when downloading files from the API in bytes."""
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
* ``ConnectionRefusedError``.
|
26
|
-
* ``ClientConnectorError``.
|
27
|
-
* ``ServerDisconnectedError``.
|
24
|
+
API_MAX_RETRIES = 5
|
25
|
+
"""The maximum number of retries for API requests."""
|
28
26
|
|
29
|
-
|
27
|
+
API_RETRY_BASE_DELAY = 5.0
|
28
|
+
"""The base delay in seconds between retries for API requests."""
|
30
29
|
|
30
|
+
|
31
|
+
def retry(
|
32
|
+
func=None,
|
33
|
+
*,
|
34
|
+
max_retries: int = API_MAX_RETRIES,
|
35
|
+
base_delay: float = API_RETRY_BASE_DELAY,
|
36
|
+
):
|
37
|
+
"""Retry the decorated function on connection errors.
|
38
|
+
|
39
|
+
:param func: The function to decorate (when used without parentheses)
|
40
|
+
:param max_retries: Maximum number of retry attempts before giving up (default: 5)
|
41
|
+
:param base_delay: Base delay in seconds between retries (default: 5.0)
|
31
42
|
"""
|
32
43
|
|
33
|
-
|
34
|
-
|
35
|
-
|
44
|
+
def decorator(f):
|
45
|
+
@wraps(f)
|
46
|
+
async def wrapper(*args, **kwargs):
|
47
|
+
last_exception = None
|
48
|
+
|
49
|
+
log = logger.bind(func_name=f.__name__, max_retries=max_retries)
|
50
|
+
|
51
|
+
for attempt in range(max_retries + 1):
|
52
|
+
try:
|
53
|
+
return await f(*args, **kwargs)
|
54
|
+
except (
|
55
|
+
ClientError,
|
56
|
+
ConnectionError,
|
57
|
+
) as e:
|
58
|
+
last_exception = e
|
59
|
+
|
60
|
+
if attempt == max_retries:
|
61
|
+
log.warning(
|
62
|
+
"max retries reached for function",
|
63
|
+
exception=str(e),
|
64
|
+
)
|
65
|
+
raise
|
36
66
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
) as err:
|
44
|
-
if attempts == 5:
|
45
|
-
raise
|
67
|
+
# Use exponential backoff if base_delay != 5.0, otherwise use
|
68
|
+
# fixed delay.
|
69
|
+
if base_delay == API_RETRY_BASE_DELAY:
|
70
|
+
delay = base_delay
|
71
|
+
else:
|
72
|
+
delay = base_delay * (2**attempt)
|
46
73
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
74
|
+
log.info(
|
75
|
+
"retrying after connection error",
|
76
|
+
exception=str(e),
|
77
|
+
retries=attempt,
|
78
|
+
retrying_in=delay,
|
79
|
+
)
|
52
80
|
|
53
|
-
|
81
|
+
await asyncio.sleep(delay)
|
54
82
|
|
55
|
-
|
83
|
+
raise last_exception
|
84
|
+
|
85
|
+
return wrapper
|
86
|
+
|
87
|
+
if func is None:
|
88
|
+
return decorator
|
89
|
+
|
90
|
+
return decorator(func)
|
56
91
|
|
57
92
|
|
58
93
|
async def decode_json_response(resp: ClientResponse) -> dict | list | None:
|
@@ -103,7 +138,6 @@ async def raise_exception_by_status_code(resp: ClientResponse):
|
|
103
138
|
|
104
139
|
if resp.status in status_exception_map:
|
105
140
|
raise status_exception_map[resp.status](message)
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
)
|
141
|
+
raise ValueError(
|
142
|
+
f"Status code {resp.status} not handled for response\n {resp}",
|
143
|
+
)
|
virtool_workflow/cli.py
CHANGED
virtool_workflow/data/hmms.py
CHANGED
@@ -7,7 +7,6 @@ from functools import cached_property
|
|
7
7
|
from pathlib import Path
|
8
8
|
from shutil import which
|
9
9
|
|
10
|
-
import aiofiles
|
11
10
|
from pyfixtures import fixture
|
12
11
|
from virtool.hmm.models import HMM
|
13
12
|
from virtool.utils import decompress_file
|
@@ -84,25 +83,22 @@ async def hmms(
|
|
84
83
|
hmms_path = work_path / "hmms"
|
85
84
|
await asyncio.to_thread(hmms_path.mkdir, parents=True, exist_ok=True)
|
86
85
|
|
86
|
+
annotations_path = hmms_path / "annotations.json"
|
87
87
|
compressed_annotations_path = hmms_path / "annotations.json.gz"
|
88
88
|
await _api.get_file("/hmms/files/annotations.json.gz", compressed_annotations_path)
|
89
|
-
|
90
|
-
annotations_path = hmms_path / "annotations.json"
|
91
89
|
await asyncio.to_thread(
|
92
90
|
decompress_file,
|
93
91
|
compressed_annotations_path,
|
94
92
|
annotations_path,
|
95
93
|
proc,
|
96
94
|
)
|
95
|
+
annotations = await asyncio.to_thread(
|
96
|
+
lambda: [HMM(**hmm) for hmm in json.loads(annotations_path.read_text())],
|
97
|
+
)
|
97
98
|
|
98
99
|
profiles_path = hmms_path / "profiles.hmm"
|
99
100
|
await _api.get_file("/hmms/files/profiles.hmm", profiles_path)
|
100
|
-
|
101
|
-
async with aiofiles.open(annotations_path) as f:
|
102
|
-
annotations = [HMM(**hmm) for hmm in json.loads(await f.read())]
|
103
|
-
|
104
101
|
p = await run_subprocess(["hmmpress", str(profiles_path)])
|
105
|
-
|
106
102
|
if p.returncode != 0:
|
107
103
|
raise RuntimeError("hmmpress command failed")
|
108
104
|
|
virtool_workflow/data/indexes.py
CHANGED
@@ -3,7 +3,6 @@ import json
|
|
3
3
|
from dataclasses import dataclass
|
4
4
|
from pathlib import Path
|
5
5
|
|
6
|
-
import aiofiles
|
7
6
|
from pyfixtures import fixture
|
8
7
|
from structlog import get_logger
|
9
8
|
from virtool.analyses.models import Analysis
|
@@ -245,8 +244,7 @@ async def index(
|
|
245
244
|
|
246
245
|
log.info("decompressed reference otus json")
|
247
246
|
|
248
|
-
|
249
|
-
data = json.loads(await f.read())
|
247
|
+
data = await asyncio.to_thread(lambda: json.loads(json_path.read_text()))
|
250
248
|
|
251
249
|
sequence_lengths = {}
|
252
250
|
sequence_otu_map = {}
|
@@ -88,7 +88,11 @@ def import_module_from_file(module_name: str, path: Path) -> ModuleType:
|
|
88
88
|
spec = spec_from_file_location(module_name, path)
|
89
89
|
if spec is None:
|
90
90
|
raise ImportError(f"could not import {path}")
|
91
|
-
|
91
|
+
|
92
|
+
module = module_from_spec(spec)
|
93
|
+
if spec.loader is None:
|
94
|
+
raise ImportError(f"could not load {path}")
|
95
|
+
spec.loader.exec_module(module)
|
92
96
|
|
93
97
|
sys.path.remove(module_parent)
|
94
98
|
|
virtool_workflow/runtime/hook.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"""The :class:`Hook` class is used to hook into the workflow lifecycle."""
|
2
|
+
|
2
3
|
from __future__ import annotations
|
3
4
|
|
4
5
|
from asyncio import gather
|
@@ -119,7 +120,8 @@ class Hook:
|
|
119
120
|
return await callback(*args, **kwargs)
|
120
121
|
|
121
122
|
results = await gather(
|
122
|
-
*[call_callback(callback) for callback in callbacks],
|
123
|
+
*[call_callback(callback) for callback in callbacks],
|
124
|
+
return_exceptions=True,
|
123
125
|
)
|
124
126
|
|
125
127
|
for error in results:
|
virtool_workflow/runtime/ping.py
CHANGED
virtool_workflow/runtime/run.py
CHANGED
@@ -42,8 +42,6 @@ from virtool_workflow.runtime.sentry import configure_sentry, set_workflow_conte
|
|
42
42
|
from virtool_workflow.utils import configure_logs, get_virtool_workflow_version
|
43
43
|
from virtool_workflow.workflow import Workflow
|
44
44
|
|
45
|
-
logger = get_logger("runtime")
|
46
|
-
|
47
45
|
|
48
46
|
def configure_status_hooks():
|
49
47
|
"""Configure built-in job status hooks.
|
@@ -73,11 +71,13 @@ def configure_status_hooks():
|
|
73
71
|
await push_status()
|
74
72
|
|
75
73
|
|
76
|
-
async def execute(workflow: Workflow, scope: FixtureScope, events: Events):
|
74
|
+
async def execute(workflow: Workflow, scope: FixtureScope, events: Events, logger):
|
77
75
|
"""Execute a workflow.
|
78
76
|
|
79
77
|
:param workflow: The workflow to execute
|
80
78
|
:param scope: The :class:`FixtureScope` to use for fixture injection
|
79
|
+
:param events: The events object for cancellation/termination
|
80
|
+
:param logger: The configured logger instance
|
81
81
|
|
82
82
|
"""
|
83
83
|
await on_workflow_start.trigger(scope)
|
@@ -151,6 +151,7 @@ async def run_workflow(
|
|
151
151
|
job_id: str,
|
152
152
|
workflow: Workflow,
|
153
153
|
events: Events,
|
154
|
+
logger,
|
154
155
|
):
|
155
156
|
# Configure hooks here so that they can be tested when using `run_workflow`.
|
156
157
|
configure_status_hooks()
|
@@ -189,7 +190,7 @@ async def run_workflow(
|
|
189
190
|
scope["work_path"] = work_path
|
190
191
|
|
191
192
|
async with ping_periodically(api, job_id):
|
192
|
-
await execute(workflow, scope, events)
|
193
|
+
await execute(workflow, scope, events, logger)
|
193
194
|
cleanup_builtin_status_hooks()
|
194
195
|
|
195
196
|
|
@@ -215,6 +216,7 @@ async def start_runtime(
|
|
215
216
|
"""
|
216
217
|
configure_logs(bool(sentry_dsn))
|
217
218
|
|
219
|
+
logger = get_logger("runtime")
|
218
220
|
logger.info(
|
219
221
|
"found virtool-workflow",
|
220
222
|
version=get_virtool_workflow_version(),
|
@@ -250,6 +252,7 @@ async def start_runtime(
|
|
250
252
|
job_id,
|
251
253
|
workflow,
|
252
254
|
events,
|
255
|
+
logger,
|
253
256
|
),
|
254
257
|
)
|
255
258
|
|
virtool_workflow/workflow.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"""Main definitions for Virtool Workflows."""
|
2
|
+
|
2
3
|
from __future__ import annotations
|
3
4
|
|
4
5
|
from dataclasses import dataclass, field
|
@@ -9,13 +10,15 @@ from virtool_workflow.utils import coerce_to_coroutine_function
|
|
9
10
|
|
10
11
|
@dataclass
|
11
12
|
class Workflow:
|
12
|
-
"""A step-wise, long-running operation.
|
13
|
-
"""
|
13
|
+
"""A step-wise, long-running operation."""
|
14
14
|
|
15
15
|
steps: list[WorkflowStep] = field(default_factory=list)
|
16
16
|
|
17
17
|
def step(
|
18
|
-
self,
|
18
|
+
self,
|
19
|
+
step: Optional[Callable] = None,
|
20
|
+
*,
|
21
|
+
name: str | None = None,
|
19
22
|
) -> Callable:
|
20
23
|
"""Decorator for adding a step to the workflow."""
|
21
24
|
if step is None:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: virtool-workflow
|
3
|
-
Version: 7.2.
|
3
|
+
Version: 7.2.2
|
4
4
|
Summary: A framework for developing bioinformatics workflows for Virtool.
|
5
5
|
License: MIT
|
6
6
|
Author: Ian Boyes
|
@@ -8,21 +8,21 @@ Maintainer: Ian Boyes
|
|
8
8
|
Requires-Python: >=3.12.3,<3.13.0
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
11
|
-
Requires-Dist: aiofiles (>=
|
12
|
-
Requires-Dist: aiohttp (>=3.
|
11
|
+
Requires-Dist: aiofiles (>=24.1.0,<25.0.0)
|
12
|
+
Requires-Dist: aiohttp (>=3.12.13,<4.0.0)
|
13
13
|
Requires-Dist: biopython (>=1.81,<2.0)
|
14
|
-
Requires-Dist: click (>=8.1
|
14
|
+
Requires-Dist: click (>=8.2.1,<9.0.0)
|
15
15
|
Requires-Dist: orjson (>=3.9.9,<4.0.0)
|
16
16
|
Requires-Dist: pydantic-factories (>=1.17.3,<2.0.0)
|
17
17
|
Requires-Dist: pyfixtures (>=1.0.0,<2.0.0)
|
18
18
|
Requires-Dist: sentry-sdk (>=2.30.0,<3.0.0)
|
19
19
|
Requires-Dist: structlog-sentry (>=2.2.1,<3.0.0)
|
20
|
-
Requires-Dist: virtool (>=31.
|
20
|
+
Requires-Dist: virtool (>=31.9.0,<32.0.0)
|
21
21
|
Description-Content-Type: text/markdown
|
22
22
|
|
23
23
|
# Virtool Workflow
|
24
24
|
|
25
|
-
](https://github.com/virtool/virtool-workflow/actions/workflows/ci.yml)
|
26
26
|
[](https://badge.fury.io/py/virtool-workflow)
|
27
27
|
|
28
28
|
A framework for developing bioinformatic workflows in Python.
|
@@ -1,18 +1,18 @@
|
|
1
|
-
virtool_workflow/__init__.py,sha256=
|
1
|
+
virtool_workflow/__init__.py,sha256=FhPRldtx5dRJftZ3pc3OMl5mWjnDqbX-qeFVQE2QApw,309
|
2
2
|
virtool_workflow/analysis/__init__.py,sha256=eRMQhKOxijlFlYI78FzmHZoF1qYevBXycpIcmlrgFqI,57
|
3
|
-
virtool_workflow/analysis/fastqc.py,sha256
|
3
|
+
virtool_workflow/analysis/fastqc.py,sha256=-D0_Py0e57mVmeA8VZQUB05AcgiCsAmxNQJWMvb2HXU,13142
|
4
4
|
virtool_workflow/analysis/skewer.py,sha256=TWUfiYeUIahHbIosNYo2sqMjS4kUkoFBTspr70eRloI,7186
|
5
5
|
virtool_workflow/analysis/trimming.py,sha256=3Dk0J322ZhBzhuplaVgxZv4l7MLu7ZhqNQHOtNi6CGM,1451
|
6
6
|
virtool_workflow/analysis/utils.py,sha256=YU1_yInZzTNl9nKQTebUz47kUEqZ__d0k-RMLX8DWOA,1108
|
7
7
|
virtool_workflow/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
virtool_workflow/api/acquire.py,sha256=M8Wf6ck6YOPQU_0dalAYxuQbukj6c4Uat1OPhV7Gj2w,2157
|
9
|
-
virtool_workflow/api/client.py,sha256=
|
10
|
-
virtool_workflow/api/utils.py,sha256=
|
11
|
-
virtool_workflow/cli.py,sha256=
|
9
|
+
virtool_workflow/api/client.py,sha256=fXCriMv0s2L5O78fn8uIBWWPtxtPz0tUk1XHb1L7RGU,4766
|
10
|
+
virtool_workflow/api/utils.py,sha256=Wzf1YseJKUBnUk0Ge8DMwgigWMS7Dn-VFNLlBFo6SW4,4341
|
11
|
+
virtool_workflow/cli.py,sha256=Ak--FvkVEtaaBqyuddUBXOot1cbo-W6OAJ94kgNBcFQ,1442
|
12
12
|
virtool_workflow/data/__init__.py,sha256=L2bQ5rMpnCMuLWDMwel4-wPchfQCTHH3EEwxDqwGOsY,610
|
13
13
|
virtool_workflow/data/analyses.py,sha256=tGUU3gLyk_4vn1Xb7FccvBc_HQzYW_AoU7Dh1OkWhAA,3105
|
14
|
-
virtool_workflow/data/hmms.py,sha256=
|
15
|
-
virtool_workflow/data/indexes.py,sha256=
|
14
|
+
virtool_workflow/data/hmms.py,sha256=qHtkQO0bF6V7GGVoGDpdhXXR9RxaetWiTL3of6Pd88Y,3210
|
15
|
+
virtool_workflow/data/indexes.py,sha256=vmrqZjndrTV9tUfVjudIzPa0clJHy1kWrxzRQH81Ess,8981
|
16
16
|
virtool_workflow/data/jobs.py,sha256=YYWxWoiVtHIBKkpOTpZl-Ute5rg-RAnMGAzBoixDNQo,1663
|
17
17
|
virtool_workflow/data/ml.py,sha256=haYHZfDbYOk0ftg6MCXbQpoDFl1VbdnQ_TuNvI9pmw0,2186
|
18
18
|
virtool_workflow/data/samples.py,sha256=fgyuQSavZiqwrqEH7Y_CoAR5gJIcO1ujrIyO5tDrXeI,4971
|
@@ -27,19 +27,19 @@ virtool_workflow/pytest_plugin/data.py,sha256=objP7cn_4u2MtsDaf0amG0EtBv3-jthj9l
|
|
27
27
|
virtool_workflow/pytest_plugin/utils.py,sha256=lxyWqHKWXGxQXBIbcYUCC6PvjSeruhSDnD-dPX1mL5Y,211
|
28
28
|
virtool_workflow/runtime/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
29
29
|
virtool_workflow/runtime/config.py,sha256=fHkprWxxqWeEWKOobxpVvSOS5Njk5Mq32sH-p5o_d8g,546
|
30
|
-
virtool_workflow/runtime/discover.py,sha256
|
30
|
+
virtool_workflow/runtime/discover.py,sha256=-ki36Z4tV0uH_HDP4iD94KT0-JIZ8kHGciuH6wxYDdg,3016
|
31
31
|
virtool_workflow/runtime/events.py,sha256=ZIX3veBfC_2yNTdClHJaYMPn4KAF9JZqpQ3qDq4ox_E,138
|
32
|
-
virtool_workflow/runtime/hook.py,sha256=
|
32
|
+
virtool_workflow/runtime/hook.py,sha256=zNRs6Xy2ZnGWIsAo_uFNh4ybOOWvsh6avc0A4__2FBg,4341
|
33
33
|
virtool_workflow/runtime/path.py,sha256=J8CsNMTg4XgDtib0gVSsLNvv17q793M-ydsxN6pkHrI,562
|
34
|
-
virtool_workflow/runtime/ping.py,sha256=
|
34
|
+
virtool_workflow/runtime/ping.py,sha256=OOqIY8zQujWmjMf4oFA6Ouqt1Uv7YCTPDXn2VXosKBk,1435
|
35
35
|
virtool_workflow/runtime/redis.py,sha256=m-Dtdpbho-Qa9W5IYJCeEEZ7vv04hYu5yALsxOJr0FY,1813
|
36
|
-
virtool_workflow/runtime/run.py,sha256=
|
36
|
+
virtool_workflow/runtime/run.py,sha256=O_XrnBPgWBfYbi70TjhN7C1hviget6kUcTGnADHmLyg,7892
|
37
37
|
virtool_workflow/runtime/run_subprocess.py,sha256=OFHVQ2ao16X8I9nl6Nm_f3IL7rHnmLH8ixtlAFKlOLk,4790
|
38
38
|
virtool_workflow/runtime/sentry.py,sha256=WJ9CI2fshJD5As6s3umUtJrUq4Z-hQRrSxAgbjceXrk,1326
|
39
39
|
virtool_workflow/utils.py,sha256=9rHSlcvZsV2qE1Wo-cUDqESIATswr1zR_P8V-wP6jdk,2545
|
40
|
-
virtool_workflow/workflow.py,sha256=
|
41
|
-
virtool_workflow-7.2.
|
42
|
-
virtool_workflow-7.2.
|
43
|
-
virtool_workflow-7.2.
|
44
|
-
virtool_workflow-7.2.
|
45
|
-
virtool_workflow-7.2.
|
40
|
+
virtool_workflow/workflow.py,sha256=6jUGggiLEsducXyo5owEYflzQb9qZQrAtpNS3t6z4Z4,2675
|
41
|
+
virtool_workflow-7.2.2.dist-info/LICENSE,sha256=nkoVQw9W4aoQM9zgtNzHDmztap5TuXZ1L2-87vNr3w8,1097
|
42
|
+
virtool_workflow-7.2.2.dist-info/METADATA,sha256=CWbWprKHo_pBUmrIQDhxB_8ySL8YLTDWHMnnBEuVVIA,1853
|
43
|
+
virtool_workflow-7.2.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
44
|
+
virtool_workflow-7.2.2.dist-info/entry_points.txt,sha256=d4MA8ZDTJOU0jKZ3ymtHZbfLVoRPgItEIN5U4uIqay8,62
|
45
|
+
virtool_workflow-7.2.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|