looper 1.5.0__tar.gz → 1.6.0a1__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. {looper-1.5.0/looper.egg-info → looper-1.6.0a1}/PKG-INFO +14 -1
  2. looper-1.6.0a1/looper/__init__.py +44 -0
  3. {looper-1.5.0 → looper-1.6.0a1}/looper/__main__.py +2 -2
  4. looper-1.6.0a1/looper/_version.py +1 -0
  5. looper-1.6.0a1/looper/cli_divvy.py +182 -0
  6. looper-1.5.0/looper/__init__.py → looper-1.6.0a1/looper/cli_looper.py +302 -65
  7. {looper-1.5.0 → looper-1.6.0a1}/looper/conductor.py +53 -206
  8. {looper-1.5.0 → looper-1.6.0a1}/looper/const.py +51 -3
  9. {looper-1.5.0 → looper-1.6.0a1}/looper/divvy.py +28 -196
  10. {looper-1.5.0 → looper-1.6.0a1}/looper/exceptions.py +18 -0
  11. looper-1.6.0a1/looper/looper.py +777 -0
  12. looper-1.6.0a1/looper/plugins.py +160 -0
  13. {looper-1.5.0 → looper-1.6.0a1}/looper/processed_project.py +1 -1
  14. {looper-1.5.0 → looper-1.6.0a1}/looper/project.py +229 -117
  15. {looper-1.5.0 → looper-1.6.0a1}/looper/utils.py +119 -43
  16. {looper-1.5.0 → looper-1.6.0a1/looper.egg-info}/PKG-INFO +14 -1
  17. {looper-1.5.0 → looper-1.6.0a1}/looper.egg-info/SOURCES.txt +7 -4
  18. {looper-1.5.0 → looper-1.6.0a1}/looper.egg-info/requires.txt +5 -5
  19. {looper-1.5.0 → looper-1.6.0a1}/requirements/requirements-all.txt +5 -5
  20. looper-1.6.0a1/tests/test_clean.py +37 -0
  21. looper-1.6.0a1/tests/test_desired_sample_range.py +61 -0
  22. looper-1.6.0a1/tests/test_natural_range.py +196 -0
  23. looper-1.5.0/looper/_version.py +0 -1
  24. looper-1.5.0/looper/html_reports.py +0 -1057
  25. looper-1.5.0/looper/html_reports_pipestat.py +0 -924
  26. looper-1.5.0/looper/html_reports_project_pipestat.py +0 -269
  27. looper-1.5.0/looper/looper.py +0 -1212
  28. {looper-1.5.0 → looper-1.6.0a1}/LICENSE.txt +0 -0
  29. {looper-1.5.0 → looper-1.6.0a1}/MANIFEST.in +0 -0
  30. {looper-1.5.0 → looper-1.6.0a1}/README.md +0 -0
  31. {looper-1.5.0 → looper-1.6.0a1}/logo_looper.svg +0 -0
  32. {looper-1.5.0 → looper-1.6.0a1}/looper/default_config/divvy_config.yaml +0 -0
  33. {looper-1.5.0 → looper-1.6.0a1}/looper/default_config/divvy_templates/localhost_bulker_template.sub +0 -0
  34. {looper-1.5.0 → looper-1.6.0a1}/looper/default_config/divvy_templates/localhost_docker_template.sub +0 -0
  35. {looper-1.5.0 → looper-1.6.0a1}/looper/default_config/divvy_templates/localhost_singularity_template.sub +0 -0
  36. {looper-1.5.0 → looper-1.6.0a1}/looper/default_config/divvy_templates/localhost_template.sub +0 -0
  37. {looper-1.5.0 → looper-1.6.0a1}/looper/default_config/divvy_templates/lsf_template.sub +0 -0
  38. {looper-1.5.0 → looper-1.6.0a1}/looper/default_config/divvy_templates/sge_template.sub +0 -0
  39. {looper-1.5.0 → looper-1.6.0a1}/looper/default_config/divvy_templates/slurm_singularity_template.sub +0 -0
  40. {looper-1.5.0 → looper-1.6.0a1}/looper/default_config/divvy_templates/slurm_template.sub +0 -0
  41. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/footer.html +0 -0
  42. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/footer_index.html +0 -0
  43. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/head.html +0 -0
  44. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/index.html +0 -0
  45. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/logo.html +0 -0
  46. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/navbar.html +0 -0
  47. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/navbar_links.html +0 -0
  48. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/navbar_list_parent.html +0 -0
  49. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/object.html +0 -0
  50. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/project_object.html +0 -0
  51. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/sample.html +0 -0
  52. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/status.html +0 -0
  53. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/status_table.html +0 -0
  54. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates/status_table_no_links.html +0 -0
  55. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/footer.html +0 -0
  56. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/footer_index.html +0 -0
  57. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/head.html +0 -0
  58. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/index.html +0 -0
  59. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/logo.html +0 -0
  60. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/navbar.html +0 -0
  61. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/navbar_links.html +0 -0
  62. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/navbar_list_parent.html +0 -0
  63. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/object.html +0 -0
  64. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/project_object.html +0 -0
  65. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/sample.html +0 -0
  66. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/status.html +0 -0
  67. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/status_table.html +0 -0
  68. {looper-1.5.0 → looper-1.6.0a1}/looper/jinja_templates_old/status_table_no_links.html +0 -0
  69. {looper-1.5.0 → looper-1.6.0a1}/looper/parser_types.py +0 -0
  70. {looper-1.5.0 → looper-1.6.0a1}/looper/pipeline_interface.py +0 -0
  71. {looper-1.5.0 → looper-1.6.0a1}/looper/schemas/divvy_config_schema.yaml +0 -0
  72. {looper-1.5.0 → looper-1.6.0a1}/looper/schemas/pipeline_interface_schema_generic.yaml +0 -0
  73. {looper-1.5.0 → looper-1.6.0a1}/looper/schemas/pipeline_interface_schema_project.yaml +0 -0
  74. {looper-1.5.0 → looper-1.6.0a1}/looper/schemas/pipeline_interface_schema_sample.yaml +0 -0
  75. {looper-1.5.0 → looper-1.6.0a1}/looper.egg-info/dependency_links.txt +0 -0
  76. {looper-1.5.0 → looper-1.6.0a1}/looper.egg-info/entry_points.txt +0 -0
  77. {looper-1.5.0 → looper-1.6.0a1}/looper.egg-info/top_level.txt +0 -0
  78. {looper-1.5.0 → looper-1.6.0a1}/requirements/requirements-doc.txt +0 -0
  79. {looper-1.5.0 → looper-1.6.0a1}/requirements/requirements-test.txt +0 -0
  80. {looper-1.5.0 → looper-1.6.0a1}/setup.cfg +0 -0
  81. {looper-1.5.0 → looper-1.6.0a1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: looper
3
- Version: 1.5.0
3
+ Version: 1.6.0a1
4
4
  Summary: A pipeline submission engine that parses sample inputs and submits pipelines for each sample.
5
5
  Home-page: https://github.com/pepkit/looper
6
6
  Author: Nathan Sheffield, Vince Reuter, Michal Stolarczyk, Johanna Klughammer, Andre Rendeiro
@@ -15,6 +15,19 @@ Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE.txt
18
+ Requires-Dist: colorama>=0.3.9
19
+ Requires-Dist: divvy>=0.5.0
20
+ Requires-Dist: eido>=0.2.1
21
+ Requires-Dist: jinja2
22
+ Requires-Dist: logmuse>=0.2.0
23
+ Requires-Dist: pandas>=2.0.2
24
+ Requires-Dist: pephubclient>=0.1.2
25
+ Requires-Dist: peppy>=0.40.0.a4
26
+ Requires-Dist: pipestat>=v0.6.0a9
27
+ Requires-Dist: pyyaml>=3.12
28
+ Requires-Dist: rich>=9.10.0
29
+ Requires-Dist: ubiquerg>=0.5.2
30
+ Requires-Dist: yacman>=0.9.2
18
31
 
19
32
  # <img src="docs/img/looper_logo.svg" alt="looper logo" height="70">
20
33
 
@@ -0,0 +1,44 @@
1
+ """Project configuration, particularly for logging.
2
+
3
+ Project-scope constants may reside here, but more importantly, some setup here
4
+ will provide a logging infrastructure for all of the project's modules.
5
+ Individual modules and classes may provide separate configuration on a more
6
+ local level, but this will at least provide a foundation.
7
+
8
+ """
9
+
10
+ import logmuse
11
+
12
+ logmuse.init_logger("looper")
13
+
14
+ from .divvy import ComputingConfiguration, select_divvy_config
15
+ from .divvy import DEFAULT_COMPUTE_RESOURCES_NAME
16
+ from .divvy import NEW_COMPUTE_KEY as COMPUTE_KEY
17
+
18
+ from ._version import __version__
19
+ from .conductor import (
20
+ SubmissionConductor,
21
+ write_submission_yaml,
22
+ )
23
+ from .plugins import (
24
+ write_sample_yaml,
25
+ write_sample_yaml_cwl,
26
+ write_sample_yaml_prj,
27
+ write_custom_template,
28
+ )
29
+ from .const import *
30
+ from .pipeline_interface import PipelineInterface
31
+ from .project import Project
32
+
33
+ # Not used here, but make this the main import interface between peppy and
34
+ # looper, so that other modules within this package need not worry about
35
+ # the locations of some of the peppy declarations. Effectively, concentrate
36
+ # the connection between peppy and looper here, to the extent possible.
37
+
38
+ __all__ = [
39
+ "Project",
40
+ "PipelineInterface",
41
+ "SubmissionConductor",
42
+ "ComputingConfiguration",
43
+ "select_divvy_config",
44
+ ]
@@ -1,7 +1,7 @@
1
1
  import sys
2
2
 
3
- from .looper import main
4
- from .divvy import main as divvy_main
3
+ from .cli_looper import main
4
+ from .cli_divvy import main as divvy_main
5
5
 
6
6
  if __name__ == "__main__":
7
7
  try:
@@ -0,0 +1 @@
1
+ __version__ = "1.6.0a1"
@@ -0,0 +1,182 @@
1
+ import logmuse
2
+ import os
3
+ import sys
4
+ import yaml
5
+ from yaml import SafeLoader
6
+ from ubiquerg import is_writable, VersionInHelpParser
7
+ from .const import (
8
+ DEFAULT_COMPUTE_RESOURCES_NAME,
9
+ DEFAULT_CONFIG_FILEPATH,
10
+ )
11
+ from .divvy import select_divvy_config, ComputingConfiguration, divvy_init
12
+
13
+
14
+ def build_argparser():
15
+ """
16
+ Builds argument parser.
17
+
18
+ :return argparse.ArgumentParser
19
+ """
20
+
21
+ banner = (
22
+ "%(prog)s - write compute job scripts that can be submitted to "
23
+ "any computing resource"
24
+ )
25
+ additional_description = "\nhttps://divvy.databio.org"
26
+
27
+ parser = VersionInHelpParser(
28
+ prog="divvy",
29
+ description=banner,
30
+ epilog=additional_description,
31
+ # version=__version__,
32
+ )
33
+
34
+ subparsers = parser.add_subparsers(dest="command")
35
+
36
+ def add_subparser(cmd, description):
37
+ return subparsers.add_parser(cmd, description=description, help=description)
38
+
39
+ subparser_messages = {
40
+ "init": "Initialize a new divvy config file",
41
+ "list": "List available compute packages",
42
+ "write": "Write a job script",
43
+ "submit": "Write and then submit a job script",
44
+ "inspect": "Inspect compute package",
45
+ }
46
+
47
+ sps = {}
48
+ for cmd, desc in subparser_messages.items():
49
+ sps[cmd] = add_subparser(cmd, desc)
50
+ # sps[cmd].add_argument(
51
+ # "config", nargs="?", default=None,
52
+ # help="Divvy configuration file.")
53
+
54
+ for sp in [sps["list"], sps["write"], sps["submit"], sps["inspect"]]:
55
+ sp.add_argument(
56
+ "config", nargs="?", default=None, help="Divvy configuration file."
57
+ )
58
+
59
+ sps["init"].add_argument("config", default=None, help="Divvy configuration file.")
60
+
61
+ for sp in [sps["inspect"]]:
62
+ sp.add_argument(
63
+ "-p",
64
+ "--package",
65
+ default=DEFAULT_COMPUTE_RESOURCES_NAME,
66
+ help="Select from available compute packages",
67
+ )
68
+
69
+ for sp in [sps["write"], sps["submit"]]:
70
+ sp.add_argument(
71
+ "-s",
72
+ "--settings",
73
+ help="YAML file with job settings to populate the template",
74
+ )
75
+
76
+ sp.add_argument(
77
+ "-p",
78
+ "--package",
79
+ default=DEFAULT_COMPUTE_RESOURCES_NAME,
80
+ help="Select from available compute packages",
81
+ )
82
+
83
+ sp.add_argument(
84
+ "-c",
85
+ "--compute",
86
+ nargs="+",
87
+ default=None,
88
+ help="Extra key=value variable pairs",
89
+ )
90
+
91
+ # sp.add_argument(
92
+ # "-t", "--template",
93
+ # help="Provide a template file (not yet implemented).")
94
+
95
+ sp.add_argument(
96
+ "-o", "--outfile", required=False, default=None, help="Output filepath"
97
+ )
98
+
99
+ return parser
100
+
101
+
102
+ def main():
103
+ """Primary workflow for divvy CLI"""
104
+
105
+ parser = logmuse.add_logging_options(build_argparser())
106
+ # args, remaining_args = parser.parse_known_args()
107
+ args = parser.parse_args()
108
+
109
+ logger_kwargs = {"level": args.verbosity, "devmode": args.logdev}
110
+ logmuse.init_logger("yacman", **logger_kwargs)
111
+ global _LOGGER
112
+ _LOGGER = logmuse.logger_via_cli(args)
113
+
114
+ if not args.command:
115
+ parser.print_help()
116
+ _LOGGER.error("No command given")
117
+ sys.exit(1)
118
+
119
+ if args.command == "init":
120
+ divcfg = args.config
121
+ _LOGGER.debug("Initializing divvy configuration")
122
+ is_writable(os.path.dirname(divcfg), check_exist=False)
123
+ divvy_init(divcfg, DEFAULT_CONFIG_FILEPATH)
124
+ sys.exit(0)
125
+
126
+ _LOGGER.debug("Divvy config: {}".format(args.config))
127
+ divcfg = select_divvy_config(args.config)
128
+ _LOGGER.info("Using divvy config: {}".format(divcfg))
129
+ dcc = ComputingConfiguration(filepath=divcfg)
130
+
131
+ if args.command == "list":
132
+ # Output header via logger and content via print so the user can
133
+ # redirect the list from stdout if desired without the header as clutter
134
+ _LOGGER.info("Available compute packages:\n")
135
+ print("{}".format("\n".join(dcc.list_compute_packages())))
136
+ sys.exit(1)
137
+
138
+ if args.command == "inspect":
139
+ # Output contents of selected compute package
140
+ _LOGGER.info("Your compute package template for: " + args.package + "\n")
141
+ found = False
142
+ for pkg_name, pkg in dcc.compute_packages.items():
143
+ if pkg_name == args.package:
144
+ found = True
145
+ with open(pkg.submission_template, "r") as f:
146
+ print(f.read())
147
+ _LOGGER.info("Submission command is: " + pkg.submission_command + "\n")
148
+ if pkg_name == "docker":
149
+ print("Docker args are: " + pkg.docker_args)
150
+
151
+ if not found:
152
+ _LOGGER.info("Package not found. Use 'divvy list' to see list of packages.")
153
+ sys.exit(1)
154
+
155
+ # Any non-divvy arguments will be passed along as key-value pairs
156
+ # that can be used to populate the template.
157
+ # keys = [str.replace(x, "--", "") for x in remaining_args[::2]]
158
+ # cli_vars = dict(zip(keys, remaining_args[1::2]))
159
+ if args.compute:
160
+ cli_vars = {y[0]: y[1] for y in [x.split("=") for x in args.compute]}
161
+ else:
162
+ cli_vars = {}
163
+
164
+ if args.command == "write" or args.command == "submit":
165
+ try:
166
+ dcc.activate_package(args.package)
167
+ except AttributeError:
168
+ parser.print_help(sys.stderr)
169
+ sys.exit(1)
170
+
171
+ if args.settings:
172
+ _LOGGER.info("Loading settings file: %s", args.settings)
173
+ with open(args.settings, "r") as f:
174
+ vars_groups = [cli_vars, yaml.load(f, SafeLoader)]
175
+ else:
176
+ vars_groups = [cli_vars]
177
+
178
+ _LOGGER.debug(vars_groups)
179
+ if args.command == "write":
180
+ dcc.write_script(args.outfile, vars_groups)
181
+ elif args.command == "submit":
182
+ dcc.submit(args.outfile, vars_groups)