Skip to content

Commit 3c3247c

Browse files
committed
lint
1 parent 521461d commit 3c3247c

File tree

2 files changed

+60
-39
lines changed

2 files changed

+60
-39
lines changed

microSALT/utils/job_creator.py

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,45 @@
1111
import shutil
1212
import subprocess
1313
import sys
14-
from importlib.metadata import entry_points
1514
import time
1615
from datetime import datetime
16+
from importlib.metadata import entry_points
1717
from pathlib import Path
1818

1919
import yaml
2020

2121
from microSALT import __version__
22-
from microSALT.config import Folders, Threshold, SlurmHeader, Regex, PubMLSTCredentials, PasteurCredentials, Singularity, Containers
22+
from microSALT.config import (
23+
Containers,
24+
Folders,
25+
PasteurCredentials,
26+
PubMLSTCredentials,
27+
Regex,
28+
Singularity,
29+
SlurmHeader,
30+
Threshold,
31+
)
2332
from microSALT.store.db_manipulator import DB_Manipulator
2433
from microSALT.utils.referencer import Referencer
2534

2635

2736
class Job_Creator:
28-
def __init__(self, log, folders: Folders, slurm_header: SlurmHeader, regex: Regex, dry: bool, config_path: str, threshold: Threshold, pubmlst: PubMLSTCredentials, pasteur: PasteurCredentials, singularity: Singularity, containers: Containers, sampleinfo={}, run_settings={}):
37+
def __init__(
38+
self,
39+
log,
40+
folders: Folders,
41+
slurm_header: SlurmHeader,
42+
regex: Regex,
43+
dry: bool,
44+
config_path: str,
45+
threshold: Threshold,
46+
pubmlst: PubMLSTCredentials,
47+
pasteur: PasteurCredentials,
48+
singularity: Singularity,
49+
containers: Containers,
50+
sampleinfo={},
51+
run_settings={},
52+
):
2953
self.folders = folders
3054
self.slurm_header = slurm_header
3155
self.regex = regex
@@ -89,7 +113,15 @@ def __init__(self, log, folders: Folders, slurm_header: SlurmHeader, regex: Rege
89113
self.finishdir = f"{folders.results}/{self.name}_{self.now}"
90114
self.db_pusher = DB_Manipulator(log=log, folders=folders, threshold=threshold)
91115
self.concat_files = dict()
92-
self.ref_resolver = Referencer(log=log, folders=folders, threshold=threshold, pubmlst=pubmlst, pasteur=pasteur, singularity=singularity, containers=containers)
116+
self.ref_resolver = Referencer(
117+
log=log,
118+
folders=folders,
119+
threshold=threshold,
120+
pubmlst=pubmlst,
121+
pasteur=pasteur,
122+
singularity=singularity,
123+
containers=containers,
124+
)
93125

94126
def get_sbatch(self):
95127
"""Returns sbatchfile, slightly superflous"""
@@ -141,15 +173,13 @@ def verify_fastq(self):
141173
else:
142174
pairno = 2 - 1 % int(file_match[1]) # 1->2, 2->1
143175
# Construct mate name
144-
pairname = f"{file_match.string[:file_match.end(1) - 1]}{pairno}{file_match.string[file_match.end(1):file_match.end()]}"
176+
pairname = f"{file_match.string[: file_match.end(1) - 1]}{pairno}{file_match.string[file_match.end(1) : file_match.end()]}"
145177
if pairname in files:
146178
files.pop(files.index(pairname))
147179
verified_files.append(file_match[0])
148180
verified_files.append(pairname)
149181
else:
150-
raise Exception(
151-
f"Some fastq files have no mate in directory {self.indir}."
152-
)
182+
raise Exception(f"Some fastq files have no mate in directory {self.indir}.")
153183
if verified_files == []:
154184
raise Exception(
155185
f"No files in directory {self.indir} match file_pattern '{self.regex.file_pattern}'."
@@ -163,9 +193,7 @@ def verify_fastq(self):
163193
if bsize > 1000:
164194
self.logger.warning(f"Input fastq {vfile} exceeds 1000MB")
165195
except Exception:
166-
self.logger.warning(
167-
f"Unable to verify size of input file {self.indir}/{vfile}"
168-
)
196+
self.logger.warning(f"Unable to verify size of input file {self.indir}/{vfile}")
169197

170198
# Warn about invalid fastq files
171199
for vfile in verified_files:
@@ -198,9 +226,7 @@ def create_assemblysection(self):
198226
f"--contigs_out {contigs_file_raw} "
199227
f"--reads {self.concat_files['f']},{self.concat_files['r']}"
200228
)
201-
batchfile.write(
202-
f"mkdir -p {assembly_dir} &" f"{self._singularity_exec('skesa', skesa_cmd)}\n"
203-
)
229+
batchfile.write(f"mkdir -p {assembly_dir} &{self._singularity_exec('skesa', skesa_cmd)}\n")
204230

205231
# Convert sequence naming in Skesa output into Spades format in the contigs fasta file:
206232
# ----------------------------------------------
@@ -318,13 +344,10 @@ def create_variantsection(self):
318344
+ "\n"
319345
)
320346
batchfile.write(
321-
self._singularity_exec("samtools", f"samtools index {outbase}.bam_sort_rmdup")
322-
+ "\n"
347+
self._singularity_exec("samtools", f"samtools index {outbase}.bam_sort_rmdup") + "\n"
323348
)
324349
batchfile.write(
325-
self._singularity_exec(
326-
"samtools", f"samtools idxstats {outbase}.bam_sort_rmdup"
327-
)
350+
self._singularity_exec("samtools", f"samtools idxstats {outbase}.bam_sort_rmdup")
328351
+ f" &> {outbase}.stats.ref\n"
329352
)
330353
# Removal of temp aligment files
@@ -579,9 +602,7 @@ def project_job(self, single_sample=False):
579602
else:
580603
self.create_project(self.name)
581604
except Exception:
582-
self.logger.error(
583-
f"LIMS interaction failed. Unable to read/write project {self.name}"
584-
)
605+
self.logger.error(f"LIMS interaction failed. Unable to read/write project {self.name}")
585606
# Writes the job creation sbatch
586607
if single_sample:
587608
try:
@@ -648,7 +669,9 @@ def project_job(self, single_sample=False):
648669

649670
def _write_mailjob(self, mailfile: str, report: str, custom_conf: str) -> None:
650671
"""Write the mailjob.sh script that runs `microsalt utils finish` after all jobs complete."""
651-
_ep = next(ep for ep in entry_points(group="console_scripts") if ep.value == "microSALT.cli:root")
672+
_ep = next(
673+
ep for ep in entry_points(group="console_scripts") if ep.value == "microSALT.cli:root"
674+
)
652675
microsalt_bin = Path(sys.executable).parent / _ep.name
653676
with open(mailfile, "w+") as mb:
654677
mb.write("#!/usr/bin/env bash\n\n")
@@ -788,9 +811,7 @@ def sample_job(self):
788811
except Exception:
789812
self.logger.error(f"Unable to access LIMS info for sample {self.name}")
790813
except Exception as e:
791-
self.logger.error(
792-
f"Unable to create job for sample {self.name}\nSource: {e!s}"
793-
)
814+
self.logger.error(f"Unable to create job for sample {self.name}\nSource: {e!s}")
794815
shutil.rmtree(self.finishdir, ignore_errors=True)
795816
raise
796817

@@ -824,9 +845,7 @@ def snp_job(self):
824845
batchfile = open(self.batchfile, "a+")
825846
batchfile.close()
826847

827-
headerline = (
828-
f"-A {self.slurm_header.project} -p {self.slurm_header.type} -n 1 -t 24:00:00 -J {self.slurm_header.job_prefix}_{self.name} --qos {self.slurm_header.qos} --output {self.finishdir}/slurm_{self.name}.log"
829-
)
848+
headerline = f"-A {self.slurm_header.project} -p {self.slurm_header.type} -n 1 -t 24:00:00 -J {self.slurm_header.job_prefix}_{self.name} --qos {self.slurm_header.qos} --output {self.finishdir}/slurm_{self.name}.log"
830849
outfile = self.get_sbatch()
831850
bash_cmd = f"sbatch {headerline} {outfile}"
832851
samproc = subprocess.Popen(bash_cmd.split(), stdout=subprocess.PIPE)

tests/utils/test_jobcreator.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
#!/usr/bin/env python
2-
1+
from pathlib import Path
32
from unittest import mock
4-
53
from unittest.mock import patch
64

5+
import pytest
6+
7+
from microSALT.config import MicroSALTConfig
78
from microSALT.utils.job_creator import Job_Creator
89

910

@@ -136,6 +137,7 @@ def test_project_job(subproc, config, logger, testdata):
136137
)
137138
jc.project_job()
138139

140+
139141
def test_singularity_exec_binds_finishdir(config, logger, testdata):
140142
"""finishdir is automatically added to the --bind list of every singularity exec call."""
141143
jc = Job_Creator(
@@ -160,6 +162,7 @@ def test_singularity_exec_binds_finishdir(config, logger, testdata):
160162
def test_singularity_exec_does_not_duplicate_finishdir(config, logger, testdata):
161163
"""finishdir is not listed twice when it already appears in singularity.bind_paths."""
162164
from microSALT.config import Singularity
165+
163166
singularity = Singularity(bind_paths=["/tmp/test_runfolder", "/data"])
164167
jc = Job_Creator(
165168
log=logger,
@@ -180,7 +183,9 @@ def test_singularity_exec_does_not_duplicate_finishdir(config, logger, testdata)
180183
assert cmd.count("/tmp/test_runfolder") == 1
181184

182185

183-
def _make_jc(config, logger, testdata, tmp_path) -> Job_Creator:
186+
def _make_jc(
187+
config: MicroSALTConfig, logger: pytest.LogCaptureFixture, testdata: dict, tmp_path: Path
188+
) -> Job_Creator:
184189
return Job_Creator(
185190
log=logger,
186191
folders=config.folders,
@@ -201,24 +206,22 @@ def _make_jc(config, logger, testdata, tmp_path) -> Job_Creator:
201206
def test_write_mailjob_uses_existing_executable(config, logger, testdata, tmp_path):
202207
"""The binary embedded in mailjob.sh must exist on the filesystem."""
203208
import pathlib
209+
204210
jc = _make_jc(config, logger, testdata, tmp_path)
205211
mailfile = str(tmp_path / "mailjob.sh")
206212

207213
jc._write_mailjob(mailfile, "default", "")
208214

209215
content = pathlib.Path(mailfile).read_text()
210216
# Extract the first token of the finish command (the binary path)
211-
bin_path = next(
212-
line.split()[0]
213-
for line in content.splitlines()
214-
if "utils finish" in line
215-
)
217+
bin_path = next(line.split()[0] for line in content.splitlines() if "utils finish" in line)
216218
assert pathlib.Path(bin_path).exists(), f"Binary not found on disk: {bin_path}"
217219

218220

219221
def test_write_mailjob_contains_finish_command(config, logger, testdata, tmp_path):
220222
"""mailjob.sh must contain the expected microsalt utils finish invocation."""
221223
import pathlib
224+
222225
jc = _make_jc(config, logger, testdata, tmp_path)
223226
mailfile = str(tmp_path / "mailjob.sh")
224227

@@ -228,4 +231,3 @@ def test_write_mailjob_contains_finish_command(config, logger, testdata, tmp_pat
228231
assert "utils finish" in content
229232
assert "--report qc" in content
230233
assert str(tmp_path) in content
231-

0 commit comments

Comments
 (0)