virtool-workflow 6.0.0a2__py3-none-any.whl → 6.0.0a4__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.
@@ -5,6 +5,7 @@ from pathlib import Path
5
5
 
6
6
  import aiofiles
7
7
  from pyfixtures import fixture
8
+ from structlog import get_logger
8
9
  from virtool_core.models.analysis import Analysis
9
10
  from virtool_core.models.index import Index
10
11
  from virtool_core.models.job import Job
@@ -15,6 +16,8 @@ from virtool_workflow.api.client import APIClient
15
16
  from virtool_workflow.files import VirtoolFileFormat
16
17
  from virtool_workflow.errors import MissingJobArgument
17
18
 
19
+ logger = get_logger("api")
20
+
18
21
 
19
22
  @dataclass
20
23
  class WFIndex:
@@ -125,7 +128,12 @@ class WFIndex:
125
128
 
126
129
  class WFNewIndex:
127
130
  def __init__(
128
- self, api: APIClient, index_id: str, manifest: dict[str, int | str], path: Path
131
+ self,
132
+ api: APIClient,
133
+ index_id: str,
134
+ manifest: dict[str, int | str],
135
+ path: Path,
136
+ reference: ReferenceNested,
129
137
  ):
130
138
  self._api = api
131
139
 
@@ -138,6 +146,9 @@ class WFNewIndex:
138
146
  self.path = path
139
147
  """The path to the index directory in the workflow's work directory."""
140
148
 
149
+ self.reference = reference
150
+ """The parent reference."""
151
+
141
152
  async def delete(self):
142
153
  await self._api.delete(f"/indexes/{self.id}")
143
154
 
@@ -174,7 +185,7 @@ class WFNewIndex:
174
185
  )
175
186
 
176
187
  @property
177
- def json_path(self) -> Path:
188
+ def otus_json_path(self) -> Path:
178
189
  """
179
190
  The path to the JSON representation of the reference index in the workflow's
180
191
  work directory.
@@ -193,12 +204,20 @@ async def index(
193
204
  """The :class:`WFIndex` for the current analysis job."""
194
205
  id_ = analysis.index.id
195
206
 
207
+ log = logger.bind(id=id_, resource="index")
208
+
209
+ log.info("loading index")
210
+
196
211
  index_json = await _api.get_json(f"/indexes/{id_}")
197
212
  index_ = Index(**index_json)
198
213
 
214
+ log.info("got index json")
215
+
199
216
  index_work_path = work_path / "indexes" / index_.id
200
217
  await asyncio.to_thread(index_work_path.mkdir, parents=True, exist_ok=True)
201
218
 
219
+ log.info("created index directory")
220
+
202
221
  for name in (
203
222
  "otus.json.gz",
204
223
  "reference.json.gz",
@@ -211,6 +230,7 @@ async def index(
211
230
  "reference.rev.2.bt2",
212
231
  ):
213
232
  await _api.get_file(f"/indexes/{id_}/files/{name}", index_work_path / name)
233
+ log.info("downloaded index file", name=name)
214
234
 
215
235
  await asyncio.to_thread(
216
236
  decompress_file,
@@ -219,6 +239,8 @@ async def index(
219
239
  proc,
220
240
  )
221
241
 
242
+ log.info("decompressed reference fasta")
243
+
222
244
  json_path = index_work_path / "otus.json"
223
245
 
224
246
  await asyncio.to_thread(
@@ -228,6 +250,8 @@ async def index(
228
250
  proc,
229
251
  )
230
252
 
253
+ log.info("decompressed reference otus json")
254
+
231
255
  async with aiofiles.open(json_path) as f:
232
256
  data = json.loads(await f.read())
233
257
 
@@ -242,6 +266,8 @@ async def index(
242
266
  sequence_otu_map[sequence_id] = otu["_id"]
243
267
  sequence_lengths[sequence_id] = len(sequence["sequence"])
244
268
 
269
+ log.info("parsed and loaded maps from otus json")
270
+
245
271
  return WFIndex(
246
272
  id=id_,
247
273
  path=index_work_path,
@@ -253,7 +279,9 @@ async def index(
253
279
 
254
280
 
255
281
  @fixture
256
- async def new_index(_api: APIClient, job: Job, work_path: Path) -> WFNewIndex:
282
+ async def new_index(
283
+ _api: APIClient, job: Job, proc: int, work_path: Path
284
+ ) -> WFNewIndex:
257
285
  """
258
286
  The :class:`.WFNewIndex` for an index being created by the current job.
259
287
  """
@@ -262,19 +290,36 @@ async def new_index(_api: APIClient, job: Job, work_path: Path) -> WFNewIndex:
262
290
  except KeyError:
263
291
  raise MissingJobArgument("Missing jobs args key 'index_id'")
264
292
 
293
+ log = logger.bind(resource="new_index", id=id_, job_id=job.id)
294
+ log.info("loading index")
295
+
265
296
  index_json = await _api.get_json(f"/indexes/{id_}")
266
297
  index_ = Index(**index_json)
267
298
 
299
+ log.info("got index json")
300
+
268
301
  index_work_path = work_path / "indexes" / index_.id
269
302
  await asyncio.to_thread(index_work_path.mkdir, parents=True, exist_ok=True)
270
303
 
271
- await _api.get_file(
272
- f"/indexes/{id_}/files/otus.json.gz", index_work_path / "otus.json.gz"
304
+ log.info("created index directory")
305
+
306
+ compressed_otus_json_path = index_work_path / "otus.json.gz"
307
+ await _api.get_file(f"/indexes/{id_}/files/otus.json.gz", compressed_otus_json_path)
308
+ log.info("downloaded otus json")
309
+
310
+ await asyncio.to_thread(
311
+ decompress_file,
312
+ compressed_otus_json_path,
313
+ index_work_path / "otus.json",
314
+ processes=proc,
273
315
  )
274
316
 
317
+ log.info("decompressed otus json")
318
+
275
319
  return WFNewIndex(
276
320
  api=_api,
277
321
  index_id=id_,
278
322
  manifest=index_.manifest,
279
323
  path=index_work_path,
324
+ reference=index_.reference,
280
325
  )
@@ -49,7 +49,7 @@ async def push_status(
49
49
  payload = {
50
50
  "error": error,
51
51
  "progress": progress,
52
- "stage": _step.function.__name__ if _step is not None else None,
52
+ "stage": _step.function.__name__ if _step is not None else "",
53
53
  "state": _state.value,
54
54
  "step_description": _step.description if _step is not None else "",
55
55
  "step_name": step_name,
@@ -133,16 +133,24 @@ async def new_sample(
133
133
  _api: APIClient, job: Job, uploads: WFUploads, work_path: Path
134
134
  ) -> WFNewSample:
135
135
  """The sample associated with the current job."""
136
+
136
137
  id_ = job.args["sample_id"]
137
138
 
139
+ log = logger.bind(resource="sample", id=id_)
140
+ log.info("loading sample for sample creation")
141
+
138
142
  base_url_path = f"/samples/{id_}"
139
143
 
140
144
  sample_dict = await _api.get_json(base_url_path)
141
145
  sample = Sample(**sample_dict)
142
146
 
147
+ log.info("got sample json")
148
+
143
149
  uploads_path = work_path / "uploads"
144
150
  await asyncio.to_thread(uploads_path.mkdir, exist_ok=True, parents=True)
145
151
 
152
+ log.info("created uploads directory")
153
+
146
154
  files = tuple(
147
155
  WFNewSampleUpload(
148
156
  id=f["id"],
@@ -155,6 +163,8 @@ async def new_sample(
155
163
 
156
164
  await asyncio.gather(*[uploads.download(f.id, f.path) for f in files])
157
165
 
166
+ log.info("downloaded sample files")
167
+
158
168
  async def finalize(quality: dict[str, Any]):
159
169
  await _api.patch_json(base_url_path, data={"quality": quality})
160
170
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: virtool-workflow
3
- Version: 6.0.0a2
3
+ Version: 6.0.0a4
4
4
  Summary: A framework for developing bioinformatics workflows for Virtool.
5
5
  Home-page: https://github.com/virtool/virtool-workflow
6
6
  License: MIT
@@ -12,10 +12,10 @@ virtool_workflow/cli.py,sha256=yEl1LziABKbjc5MCOoUGLy-iuqehOou37x9ox4LA92M,1441
12
12
  virtool_workflow/data/__init__.py,sha256=L2bQ5rMpnCMuLWDMwel4-wPchfQCTHH3EEwxDqwGOsY,610
13
13
  virtool_workflow/data/analyses.py,sha256=UdNrQWAvWHZwPLJinx_2_OK5eBeRlObVEx2QHcbFuRk,3150
14
14
  virtool_workflow/data/hmms.py,sha256=-ANZkM3C7p25zCEeS4WJFskBvHZWcpKjFDBZC2Z9HEA,3271
15
- virtool_workflow/data/indexes.py,sha256=xYBANmOT6Sr0GXWfw4WWNcxnITpnX3cKjj4zmu00jdg,8004
16
- virtool_workflow/data/jobs.py,sha256=LIKTX4jWm5cbNbdf9Foxmur0uf7_BeJY0aLT5Hr0Pp0,1669
15
+ virtool_workflow/data/indexes.py,sha256=woF5iKb011nj5Sq37wasKb-xf8gH-xugJSusqcV6Avk,9072
16
+ virtool_workflow/data/jobs.py,sha256=VALeDaaT0WWqDyGsiNxbeKIcdklYZljWhu0zBhUPZs0,1667
17
17
  virtool_workflow/data/ml.py,sha256=Yoc4ePH-J_4BKi-wjCKFD6vuI58g3Jw7SKk4ri9ymQ4,1891
18
- virtool_workflow/data/samples.py,sha256=tysGIGFssX4APlcQU52NIvjbtn6uX77ATLYS7Qhcgfg,4696
18
+ virtool_workflow/data/samples.py,sha256=p58-qwHsaPoa3oGiDM5yibVibuvH5JPhfx8zNuTq9KE,4915
19
19
  virtool_workflow/data/subtractions.py,sha256=X-R8t5gIboHVE7kHyziWntuoyb1SbTjSV9UETB0Tt38,7282
20
20
  virtool_workflow/data/uploads.py,sha256=sIpuS2AtJ5yvZWitkzqb6hG1iLVe7K4q6UIsEDizFCE,899
21
21
  virtool_workflow/decorators.py,sha256=mh4_wBVLcAQYkn_aPonYEb2TP7NxORVdjBVgfehjHwQ,1285
@@ -35,8 +35,8 @@ virtool_workflow/runtime/run_subprocess.py,sha256=AviofEsOvp0buXRST-IxAW2txLwoTV
35
35
  virtool_workflow/runtime/sentry.py,sha256=6WNUYeQCoofP49cCmEy5bn_JRc3CSQmy7pnDW3XnAbc,748
36
36
  virtool_workflow/utils.py,sha256=wJHdTcuwC3wzYfJVM32MJo1Xdn-6r7V1bJRoLr9mhU0,520
37
37
  virtool_workflow/workflow.py,sha256=RxboCKLyCpfikPLIw7QFss77ERNlw8tJZhIXFB88DBs,2678
38
- virtool_workflow-6.0.0a2.dist-info/LICENSE,sha256=nkoVQw9W4aoQM9zgtNzHDmztap5TuXZ1L2-87vNr3w8,1097
39
- virtool_workflow-6.0.0a2.dist-info/METADATA,sha256=5ai445zZ9mx32gzOES_OnSBLjYVNZ3vpS8HcAPGjF0Y,4321
40
- virtool_workflow-6.0.0a2.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
41
- virtool_workflow-6.0.0a2.dist-info/entry_points.txt,sha256=d4MA8ZDTJOU0jKZ3ymtHZbfLVoRPgItEIN5U4uIqay8,62
42
- virtool_workflow-6.0.0a2.dist-info/RECORD,,
38
+ virtool_workflow-6.0.0a4.dist-info/LICENSE,sha256=nkoVQw9W4aoQM9zgtNzHDmztap5TuXZ1L2-87vNr3w8,1097
39
+ virtool_workflow-6.0.0a4.dist-info/METADATA,sha256=QTa4cL-Od0i4l9lw78gSIP0s5HoVMv1_y6XeMY4j2vo,4321
40
+ virtool_workflow-6.0.0a4.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
41
+ virtool_workflow-6.0.0a4.dist-info/entry_points.txt,sha256=d4MA8ZDTJOU0jKZ3ymtHZbfLVoRPgItEIN5U4uIqay8,62
42
+ virtool_workflow-6.0.0a4.dist-info/RECORD,,