looper 1.5.0__py3-none-any.whl → 1.6.0a1__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.
- looper/__init__.py +3 -498
- looper/__main__.py +2 -2
- looper/_version.py +1 -1
- looper/cli_divvy.py +182 -0
- looper/cli_looper.py +776 -0
- looper/conductor.py +53 -206
- looper/const.py +51 -3
- looper/divvy.py +28 -196
- looper/exceptions.py +18 -0
- looper/looper.py +177 -612
- looper/plugins.py +160 -0
- looper/processed_project.py +1 -1
- looper/project.py +229 -117
- looper/utils.py +119 -43
- {looper-1.5.0.dist-info → looper-1.6.0a1.dist-info}/METADATA +6 -6
- {looper-1.5.0.dist-info → looper-1.6.0a1.dist-info}/RECORD +20 -20
- {looper-1.5.0.dist-info → looper-1.6.0a1.dist-info}/WHEEL +1 -1
- looper/html_reports.py +0 -1057
- looper/html_reports_pipestat.py +0 -924
- looper/html_reports_project_pipestat.py +0 -269
- {looper-1.5.0.dist-info → looper-1.6.0a1.dist-info}/LICENSE.txt +0 -0
- {looper-1.5.0.dist-info → looper-1.6.0a1.dist-info}/entry_points.txt +0 -0
- {looper-1.5.0.dist-info → looper-1.6.0a1.dist-info}/top_level.txt +0 -0
looper/__init__.py
CHANGED
@@ -11,26 +11,22 @@ import logmuse
|
|
11
11
|
|
12
12
|
logmuse.init_logger("looper")
|
13
13
|
|
14
|
-
import argparse
|
15
|
-
import logging
|
16
|
-
import os
|
17
|
-
from typing import *
|
18
14
|
from .divvy import ComputingConfiguration, select_divvy_config
|
19
15
|
from .divvy import DEFAULT_COMPUTE_RESOURCES_NAME
|
20
16
|
from .divvy import NEW_COMPUTE_KEY as COMPUTE_KEY
|
21
|
-
from ubiquerg import VersionInHelpParser
|
22
17
|
|
23
18
|
from ._version import __version__
|
24
19
|
from .conductor import (
|
25
20
|
SubmissionConductor,
|
21
|
+
write_submission_yaml,
|
22
|
+
)
|
23
|
+
from .plugins import (
|
26
24
|
write_sample_yaml,
|
27
25
|
write_sample_yaml_cwl,
|
28
26
|
write_sample_yaml_prj,
|
29
|
-
write_submission_yaml,
|
30
27
|
write_custom_template,
|
31
28
|
)
|
32
29
|
from .const import *
|
33
|
-
from .parser_types import *
|
34
30
|
from .pipeline_interface import PipelineInterface
|
35
31
|
from .project import Project
|
36
32
|
|
@@ -46,494 +42,3 @@ __all__ = [
|
|
46
42
|
"ComputingConfiguration",
|
47
43
|
"select_divvy_config",
|
48
44
|
]
|
49
|
-
|
50
|
-
|
51
|
-
SAMPLE_SELECTION_ATTRIBUTE_OPTNAME = "sel-attr"
|
52
|
-
SAMPLE_EXCLUSION_OPTNAME = "sel-excl"
|
53
|
-
SAMPLE_INCLUSION_OPTNAME = "sel-incl"
|
54
|
-
|
55
|
-
|
56
|
-
class _StoreBoolActionType(argparse.Action):
|
57
|
-
"""
|
58
|
-
Enables the storage of a boolean const and custom type definition needed
|
59
|
-
for systematic html interface generation. To get the _StoreTrueAction
|
60
|
-
output use default=False in the add_argument function
|
61
|
-
and default=True to get _StoreFalseAction output.
|
62
|
-
"""
|
63
|
-
|
64
|
-
def __init__(self, option_strings, dest, type, default, required=False, help=None):
|
65
|
-
super(_StoreBoolActionType, self).__init__(
|
66
|
-
option_strings=option_strings,
|
67
|
-
dest=dest,
|
68
|
-
nargs=0,
|
69
|
-
const=not default,
|
70
|
-
default=default,
|
71
|
-
type=type,
|
72
|
-
required=required,
|
73
|
-
help=help,
|
74
|
-
)
|
75
|
-
|
76
|
-
def __call__(self, parser, namespace, values, option_string=None):
|
77
|
-
setattr(namespace, self.dest, self.const)
|
78
|
-
|
79
|
-
|
80
|
-
MESSAGE_BY_SUBCOMMAND = {
|
81
|
-
"run": "Run or submit sample jobs.",
|
82
|
-
"rerun": "Resubmit sample jobs with failed flags.",
|
83
|
-
"runp": "Run or submit project jobs.",
|
84
|
-
"table": "Write summary stats table for project samples.",
|
85
|
-
"report": "Create browsable HTML report of project results.",
|
86
|
-
"destroy": "Remove output files of the project.",
|
87
|
-
"check": "Check flag status of current runs.",
|
88
|
-
"clean": "Run clean scripts of already processed jobs.",
|
89
|
-
"inspect": "Print information about a project.",
|
90
|
-
"init": "Initialize looper dotfile.",
|
91
|
-
"init-piface": "Initialize generic pipeline interface.",
|
92
|
-
}
|
93
|
-
|
94
|
-
|
95
|
-
def build_parser():
|
96
|
-
"""
|
97
|
-
Building argument parser.
|
98
|
-
|
99
|
-
:return argparse.ArgumentParser
|
100
|
-
"""
|
101
|
-
# Main looper program help text messages
|
102
|
-
banner = "%(prog)s - A project job submission engine and project manager."
|
103
|
-
additional_description = (
|
104
|
-
"For subcommand-specific options, " "type: '%(prog)s <subcommand> -h'"
|
105
|
-
)
|
106
|
-
additional_description += "\nhttps://github.com/pepkit/looper"
|
107
|
-
|
108
|
-
parser = VersionInHelpParser(
|
109
|
-
prog="looper",
|
110
|
-
description=banner,
|
111
|
-
epilog=additional_description,
|
112
|
-
version=__version__,
|
113
|
-
)
|
114
|
-
|
115
|
-
aux_parser = VersionInHelpParser(
|
116
|
-
prog="looper",
|
117
|
-
description=banner,
|
118
|
-
epilog=additional_description,
|
119
|
-
version=__version__,
|
120
|
-
)
|
121
|
-
result = []
|
122
|
-
for parser in [parser, aux_parser]:
|
123
|
-
# Logging control
|
124
|
-
parser.add_argument(
|
125
|
-
"--logfile",
|
126
|
-
help="Optional output file for looper logs " "(default: %(default)s)",
|
127
|
-
)
|
128
|
-
parser.add_argument("--logging-level", help=argparse.SUPPRESS)
|
129
|
-
parser.add_argument(
|
130
|
-
"--dbg",
|
131
|
-
action="store_true",
|
132
|
-
help="Turn on debug mode (default: %(default)s)",
|
133
|
-
)
|
134
|
-
|
135
|
-
parser = logmuse.add_logging_options(parser)
|
136
|
-
subparsers = parser.add_subparsers(dest="command")
|
137
|
-
|
138
|
-
def add_subparser(cmd):
|
139
|
-
message = MESSAGE_BY_SUBCOMMAND[cmd]
|
140
|
-
return subparsers.add_parser(
|
141
|
-
cmd,
|
142
|
-
description=message,
|
143
|
-
help=message,
|
144
|
-
formatter_class=lambda prog: argparse.HelpFormatter(
|
145
|
-
prog, max_help_position=37, width=90
|
146
|
-
),
|
147
|
-
)
|
148
|
-
|
149
|
-
# Run and rerun command
|
150
|
-
run_subparser = add_subparser("run")
|
151
|
-
rerun_subparser = add_subparser("rerun")
|
152
|
-
collate_subparser = add_subparser("runp")
|
153
|
-
table_subparser = add_subparser("table")
|
154
|
-
report_subparser = add_subparser("report")
|
155
|
-
destroy_subparser = add_subparser("destroy")
|
156
|
-
check_subparser = add_subparser("check")
|
157
|
-
clean_subparser = add_subparser("clean")
|
158
|
-
inspect_subparser = add_subparser("inspect")
|
159
|
-
init_subparser = add_subparser("init")
|
160
|
-
init_piface = add_subparser("init-piface")
|
161
|
-
|
162
|
-
# Flag arguments
|
163
|
-
####################################################################
|
164
|
-
for subparser in [run_subparser, rerun_subparser, collate_subparser]:
|
165
|
-
subparser.add_argument(
|
166
|
-
"-i",
|
167
|
-
"--ignore-flags",
|
168
|
-
default=False,
|
169
|
-
action=_StoreBoolActionType,
|
170
|
-
type=html_checkbox(checked=False),
|
171
|
-
help="Ignore run status flags? Default=False",
|
172
|
-
)
|
173
|
-
|
174
|
-
for subparser in [
|
175
|
-
run_subparser,
|
176
|
-
rerun_subparser,
|
177
|
-
destroy_subparser,
|
178
|
-
clean_subparser,
|
179
|
-
collate_subparser,
|
180
|
-
]:
|
181
|
-
subparser.add_argument(
|
182
|
-
"-d",
|
183
|
-
"--dry-run",
|
184
|
-
action=_StoreBoolActionType,
|
185
|
-
default=False,
|
186
|
-
type=html_checkbox(checked=False),
|
187
|
-
help="Don't actually submit the jobs. Default=False",
|
188
|
-
)
|
189
|
-
|
190
|
-
# Parameter arguments
|
191
|
-
####################################################################
|
192
|
-
for subparser in [run_subparser, rerun_subparser, collate_subparser]:
|
193
|
-
subparser.add_argument(
|
194
|
-
"-t",
|
195
|
-
"--time-delay",
|
196
|
-
metavar="S",
|
197
|
-
type=html_range(min_val=0, max_val=30, value=0),
|
198
|
-
default=0,
|
199
|
-
help="Time delay in seconds between job submissions",
|
200
|
-
)
|
201
|
-
|
202
|
-
subparser.add_argument(
|
203
|
-
"-x",
|
204
|
-
"--command-extra",
|
205
|
-
default="",
|
206
|
-
metavar="S",
|
207
|
-
help="String to append to every command",
|
208
|
-
)
|
209
|
-
subparser.add_argument(
|
210
|
-
"-y",
|
211
|
-
"--command-extra-override",
|
212
|
-
metavar="S",
|
213
|
-
default="",
|
214
|
-
help="Same as command-extra, but overrides values in PEP",
|
215
|
-
)
|
216
|
-
subparser.add_argument(
|
217
|
-
"-f",
|
218
|
-
"--skip-file-checks",
|
219
|
-
action=_StoreBoolActionType,
|
220
|
-
default=False,
|
221
|
-
type=html_checkbox(checked=False),
|
222
|
-
help="Do not perform input file checks",
|
223
|
-
)
|
224
|
-
|
225
|
-
divvy_group = subparser.add_argument_group(
|
226
|
-
"divvy arguments", "Configure divvy to change computing settings"
|
227
|
-
)
|
228
|
-
divvy_group.add_argument(
|
229
|
-
"--divvy",
|
230
|
-
default=None,
|
231
|
-
metavar="DIVCFG",
|
232
|
-
help="Path to divvy configuration file. Default=$DIVCFG env "
|
233
|
-
"variable. Currently: {}".format(
|
234
|
-
os.getenv("DIVCFG", None) or "not set"
|
235
|
-
),
|
236
|
-
)
|
237
|
-
divvy_group.add_argument(
|
238
|
-
"-p",
|
239
|
-
"--package",
|
240
|
-
metavar="P",
|
241
|
-
help="Name of computing resource package to use",
|
242
|
-
)
|
243
|
-
divvy_group.add_argument(
|
244
|
-
"-s",
|
245
|
-
"--settings",
|
246
|
-
default="",
|
247
|
-
metavar="S",
|
248
|
-
help="Path to a YAML settings file with compute settings",
|
249
|
-
)
|
250
|
-
divvy_group.add_argument(
|
251
|
-
"-c",
|
252
|
-
"--compute",
|
253
|
-
metavar="K",
|
254
|
-
nargs="+",
|
255
|
-
help="List of key-value pairs (k1=v1)",
|
256
|
-
)
|
257
|
-
|
258
|
-
for subparser in [run_subparser, rerun_subparser]:
|
259
|
-
subparser.add_argument(
|
260
|
-
"-u",
|
261
|
-
"--lump",
|
262
|
-
default=None,
|
263
|
-
metavar="X",
|
264
|
-
type=html_range(min_val=0, max_val=100, step=0.1, value=0),
|
265
|
-
help="Total input file size (GB) to batch into one job",
|
266
|
-
)
|
267
|
-
subparser.add_argument(
|
268
|
-
"-n",
|
269
|
-
"--lumpn",
|
270
|
-
default=None,
|
271
|
-
metavar="N",
|
272
|
-
type=html_range(min_val=1, max_val="num_samples", value=1),
|
273
|
-
help="Number of commands to batch into one job",
|
274
|
-
)
|
275
|
-
|
276
|
-
check_subparser.add_argument(
|
277
|
-
"--describe-codes",
|
278
|
-
help="Show status codes description",
|
279
|
-
action="store_true",
|
280
|
-
default=False,
|
281
|
-
)
|
282
|
-
|
283
|
-
check_subparser.add_argument(
|
284
|
-
"--itemized",
|
285
|
-
help="Show a detailed, by sample statuses",
|
286
|
-
action="store_true",
|
287
|
-
default=False,
|
288
|
-
)
|
289
|
-
|
290
|
-
check_subparser.add_argument(
|
291
|
-
"-f",
|
292
|
-
"--flags",
|
293
|
-
nargs="*",
|
294
|
-
default=FLAGS,
|
295
|
-
type=html_select(choices=FLAGS),
|
296
|
-
metavar="F",
|
297
|
-
help="Check on only these flags/status values",
|
298
|
-
)
|
299
|
-
|
300
|
-
for subparser in [destroy_subparser, clean_subparser]:
|
301
|
-
subparser.add_argument(
|
302
|
-
"--force-yes",
|
303
|
-
action=_StoreBoolActionType,
|
304
|
-
default=False,
|
305
|
-
type=html_checkbox(checked=False),
|
306
|
-
help="Provide upfront confirmation of destruction intent, "
|
307
|
-
"to skip console query. Default=False",
|
308
|
-
)
|
309
|
-
|
310
|
-
init_subparser.add_argument(
|
311
|
-
"config_file", help="Project configuration file (YAML)"
|
312
|
-
)
|
313
|
-
|
314
|
-
init_subparser.add_argument(
|
315
|
-
"-f", "--force", help="Force overwrite", action="store_true", default=False
|
316
|
-
)
|
317
|
-
|
318
|
-
init_subparser.add_argument(
|
319
|
-
"-o",
|
320
|
-
"--output-dir",
|
321
|
-
dest="output_dir",
|
322
|
-
metavar="DIR",
|
323
|
-
default=None,
|
324
|
-
type=str,
|
325
|
-
)
|
326
|
-
|
327
|
-
init_subparser.add_argument(
|
328
|
-
"-S",
|
329
|
-
"--sample-pipeline-interfaces",
|
330
|
-
dest=SAMPLE_PL_ARG,
|
331
|
-
metavar="YAML",
|
332
|
-
default=None,
|
333
|
-
nargs="+",
|
334
|
-
type=str,
|
335
|
-
help="Path to looper sample config file",
|
336
|
-
)
|
337
|
-
init_subparser.add_argument(
|
338
|
-
"-P",
|
339
|
-
"--project-pipeline-interfaces",
|
340
|
-
dest=PROJECT_PL_ARG,
|
341
|
-
metavar="YAML",
|
342
|
-
default=None,
|
343
|
-
nargs="+",
|
344
|
-
type=str,
|
345
|
-
help="Path to looper project config file",
|
346
|
-
)
|
347
|
-
|
348
|
-
# TODO: add ouput dir, sample, project pifaces
|
349
|
-
|
350
|
-
init_subparser.add_argument(
|
351
|
-
"-p",
|
352
|
-
"--piface",
|
353
|
-
help="Generates generic pipeline interface",
|
354
|
-
action="store_true",
|
355
|
-
default=False,
|
356
|
-
)
|
357
|
-
|
358
|
-
# Common arguments
|
359
|
-
for subparser in [
|
360
|
-
run_subparser,
|
361
|
-
rerun_subparser,
|
362
|
-
table_subparser,
|
363
|
-
report_subparser,
|
364
|
-
destroy_subparser,
|
365
|
-
check_subparser,
|
366
|
-
clean_subparser,
|
367
|
-
collate_subparser,
|
368
|
-
inspect_subparser,
|
369
|
-
]:
|
370
|
-
subparser.add_argument(
|
371
|
-
"config_file",
|
372
|
-
nargs="?",
|
373
|
-
default=None,
|
374
|
-
help="Project configuration file (YAML) or pephub registry path.",
|
375
|
-
)
|
376
|
-
subparser.add_argument(
|
377
|
-
"--looper_config",
|
378
|
-
required=False,
|
379
|
-
default=None,
|
380
|
-
type=str,
|
381
|
-
help="Looper configuration file (YAML)",
|
382
|
-
)
|
383
|
-
# help="Path to the looper config file"
|
384
|
-
subparser.add_argument(
|
385
|
-
"-S",
|
386
|
-
"--sample-pipeline-interfaces",
|
387
|
-
dest=SAMPLE_PL_ARG,
|
388
|
-
metavar="YAML",
|
389
|
-
default=None,
|
390
|
-
nargs="+",
|
391
|
-
type=str,
|
392
|
-
help="Path to looper sample config file",
|
393
|
-
)
|
394
|
-
subparser.add_argument(
|
395
|
-
"-P",
|
396
|
-
"--project-pipeline-interfaces",
|
397
|
-
dest=PROJECT_PL_ARG,
|
398
|
-
metavar="YAML",
|
399
|
-
default=None,
|
400
|
-
nargs="+",
|
401
|
-
type=str,
|
402
|
-
help="Path to looper project config file",
|
403
|
-
)
|
404
|
-
# help="Path to the output directory"
|
405
|
-
subparser.add_argument(
|
406
|
-
"-o",
|
407
|
-
"--output-dir",
|
408
|
-
dest="output_dir",
|
409
|
-
metavar="DIR",
|
410
|
-
default=None,
|
411
|
-
type=str,
|
412
|
-
help=argparse.SUPPRESS,
|
413
|
-
)
|
414
|
-
# "Submission subdirectory name"
|
415
|
-
subparser.add_argument(
|
416
|
-
"--submission-subdir", metavar="DIR", help=argparse.SUPPRESS
|
417
|
-
)
|
418
|
-
# "Results subdirectory name"
|
419
|
-
subparser.add_argument(
|
420
|
-
"--results-subdir", metavar="DIR", help=argparse.SUPPRESS
|
421
|
-
)
|
422
|
-
# "Sample attribute for pipeline interface sources"
|
423
|
-
subparser.add_argument(
|
424
|
-
"--pipeline-interfaces-key", metavar="K", help=argparse.SUPPRESS
|
425
|
-
)
|
426
|
-
# "Paths to pipeline interface files"
|
427
|
-
subparser.add_argument(
|
428
|
-
"--pipeline-interfaces",
|
429
|
-
metavar="P",
|
430
|
-
nargs="+",
|
431
|
-
action="append",
|
432
|
-
help=argparse.SUPPRESS,
|
433
|
-
)
|
434
|
-
|
435
|
-
for subparser in [
|
436
|
-
run_subparser,
|
437
|
-
rerun_subparser,
|
438
|
-
table_subparser,
|
439
|
-
report_subparser,
|
440
|
-
destroy_subparser,
|
441
|
-
check_subparser,
|
442
|
-
clean_subparser,
|
443
|
-
collate_subparser,
|
444
|
-
inspect_subparser,
|
445
|
-
]:
|
446
|
-
fetch_samples_group = subparser.add_argument_group(
|
447
|
-
"sample selection arguments",
|
448
|
-
"Specify samples to include or exclude based on sample attribute values",
|
449
|
-
)
|
450
|
-
fetch_samples_group.add_argument(
|
451
|
-
"-l",
|
452
|
-
"--limit",
|
453
|
-
default=None,
|
454
|
-
metavar="N",
|
455
|
-
type=html_range(min_val=1, max_val="num_samples", value="num_samples"),
|
456
|
-
help="Limit to n samples",
|
457
|
-
)
|
458
|
-
fetch_samples_group.add_argument(
|
459
|
-
"-k",
|
460
|
-
"--skip",
|
461
|
-
default=None,
|
462
|
-
metavar="N",
|
463
|
-
type=html_range(min_val=1, max_val="num_samples", value="num_samples"),
|
464
|
-
help="Skip samples by numerical index",
|
465
|
-
)
|
466
|
-
|
467
|
-
fetch_samples_group.add_argument(
|
468
|
-
f"--{SAMPLE_SELECTION_ATTRIBUTE_OPTNAME}",
|
469
|
-
default="toggle",
|
470
|
-
metavar="ATTR",
|
471
|
-
help="Attribute for sample exclusion OR inclusion",
|
472
|
-
)
|
473
|
-
protocols = fetch_samples_group.add_mutually_exclusive_group()
|
474
|
-
protocols.add_argument(
|
475
|
-
f"--{SAMPLE_EXCLUSION_OPTNAME}",
|
476
|
-
nargs="*",
|
477
|
-
metavar="E",
|
478
|
-
help="Exclude samples with these values",
|
479
|
-
)
|
480
|
-
protocols.add_argument(
|
481
|
-
f"--{SAMPLE_INCLUSION_OPTNAME}",
|
482
|
-
nargs="*",
|
483
|
-
metavar="I",
|
484
|
-
help="Include only samples with these values",
|
485
|
-
)
|
486
|
-
subparser.add_argument(
|
487
|
-
"-a",
|
488
|
-
"--amend",
|
489
|
-
nargs="+",
|
490
|
-
metavar="A",
|
491
|
-
help="List of amendments to activate",
|
492
|
-
)
|
493
|
-
for subparser in [report_subparser, table_subparser, check_subparser]:
|
494
|
-
subparser.add_argument(
|
495
|
-
"--project",
|
496
|
-
help="Process project-level pipelines",
|
497
|
-
action="store_true",
|
498
|
-
default=False,
|
499
|
-
)
|
500
|
-
inspect_subparser.add_argument(
|
501
|
-
"--sample-names",
|
502
|
-
help="Names of the samples to inspect",
|
503
|
-
nargs="*",
|
504
|
-
default=None,
|
505
|
-
)
|
506
|
-
|
507
|
-
inspect_subparser.add_argument(
|
508
|
-
"--attr-limit",
|
509
|
-
help="Number of attributes to display",
|
510
|
-
type=int,
|
511
|
-
)
|
512
|
-
result.append(parser)
|
513
|
-
return result
|
514
|
-
|
515
|
-
|
516
|
-
def opt_attr_pair(name: str) -> Tuple[str, str]:
|
517
|
-
return f"--{name}", name.replace("-", "_")
|
518
|
-
|
519
|
-
|
520
|
-
def validate_post_parse(args: argparse.Namespace) -> List[str]:
|
521
|
-
problems = []
|
522
|
-
used_exclusives = [
|
523
|
-
opt
|
524
|
-
for opt, attr in map(
|
525
|
-
opt_attr_pair,
|
526
|
-
[
|
527
|
-
"skip",
|
528
|
-
"limit",
|
529
|
-
SAMPLE_EXCLUSION_OPTNAME,
|
530
|
-
SAMPLE_INCLUSION_OPTNAME,
|
531
|
-
],
|
532
|
-
)
|
533
|
-
if getattr(args, attr, None)
|
534
|
-
]
|
535
|
-
if len(used_exclusives) > 1:
|
536
|
-
problems.append(
|
537
|
-
f"Used multiple mutually exclusive options: {', '.join(used_exclusives)}"
|
538
|
-
)
|
539
|
-
return problems
|
looper/__main__.py
CHANGED
looper/_version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "1.
|
1
|
+
__version__ = "1.6.0a1"
|