snk-cli 0.0.1__tar.gz → 0.1.1__tar.gz
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.
- snk_cli-0.1.1/.github/workflows/mkdocs.yml +23 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/PKG-INFO +7 -2
- snk_cli-0.1.1/README.md +6 -0
- snk_cli-0.1.1/docs/index.md +8 -0
- snk_cli-0.1.1/docs/reference/cli.md +2 -0
- snk_cli-0.1.1/docs/reference/config.md +4 -0
- snk_cli-0.1.1/docs/reference/dynamic_typer.md +2 -0
- snk_cli-0.1.1/docs/reference/options.md +4 -0
- snk_cli-0.1.1/docs/reference/subcommands.md +12 -0
- snk_cli-0.1.1/docs/reference/testing.md +2 -0
- snk_cli-0.1.1/docs/reference/utils.md +2 -0
- snk_cli-0.1.1/docs/reference/validate.md +2 -0
- snk_cli-0.1.1/docs/reference/workflow.md +2 -0
- snk_cli-0.1.1/mkdocs.yml +44 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/__about__.py +1 -1
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/cli.py +47 -29
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/config/config.py +45 -4
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/config/utils.py +13 -6
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/dynamic_typer.py +58 -14
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/options/utils.py +10 -5
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/subcommands/config.py +10 -5
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/subcommands/run.py +50 -26
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/testing.py +9 -1
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/utils.py +23 -3
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/validate.py +10 -6
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/workflow.py +35 -15
- snk_cli-0.1.1/tests/conftest.py +18 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/test_cli/test_run.py +8 -7
- snk_cli-0.1.1/tests/test_cli/test_snk_config.py +29 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/test_cli/test_workflow_cli.py +0 -1
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/test_dynamic_typer.py +8 -0
- snk_cli-0.1.1/tests/utils.py +22 -0
- snk_cli-0.0.1/README.md +0 -1
- snk_cli-0.0.1/tests/conftest.py +0 -38
- snk_cli-0.0.1/tests/test_cli/test_snk_config.py +0 -17
- snk_cli-0.0.1/tests/utils.py +0 -7
- {snk_cli-0.0.1 → snk_cli-0.1.1}/.github/workflows/publish.yml +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/.github/workflows/tests.yml +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/.gitignore +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/LICENSE.txt +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/pyproject.toml +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/__init__.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/config/__init__.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/options/__init__.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/options/option.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/subcommands/__init__.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/subcommands/env.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/subcommands/profile.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/subcommands/script.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/src/snk_cli/subcommands/utils.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/__init__.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/artic_v4.1.bed +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/config.yaml +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/cov.fasta +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/print_config/Snakefile +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/print_config/cli.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/print_config/config.yaml +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/print_config/snk.yaml +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/workflow/cli.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/workflow/config.yaml +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/workflow/resources/data.txt +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/workflow/snk.yaml +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/workflow/things/__about__.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/workflow/workflow/Snakefile +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/workflow/workflow/envs/python.yml +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/workflow/workflow/profiles/base/config.yaml +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/workflow/workflow/profiles/slurm/config.yaml +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/data/workflow/workflow/scripts/hello.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/test_cli/__init__.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/test_cli/test_dynamic_options.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/test_cli/test_subcommands.py +0 -0
- {snk_cli-0.0.1 → snk_cli-0.1.1}/tests/test_cli/test_validate.py +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
name: mkdocs
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
- main
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
jobs:
|
|
11
|
+
deploy:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v3
|
|
15
|
+
- uses: actions/setup-python@v4
|
|
16
|
+
with:
|
|
17
|
+
python-version: 3.x
|
|
18
|
+
- uses: actions/cache@v2
|
|
19
|
+
with:
|
|
20
|
+
key: ${{ github.ref }}
|
|
21
|
+
path: .cache
|
|
22
|
+
- run: pip install "mkdocstrings==0.22.0" "mkdocstrings-python==1.3.*" "mkdocs-material"
|
|
23
|
+
- run: mkdocs gh-deploy --force
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: snk-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Project-URL: Documentation, https://github.com/unknown/snk-cli#readme
|
|
5
5
|
Project-URL: Issues, https://github.com/unknown/snk-cli/issues
|
|
6
6
|
Project-URL: Source, https://github.com/unknown/snk-cli
|
|
@@ -27,3 +27,8 @@ Requires-Dist: typer[all]~=0.9.0
|
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
|
|
29
29
|
# snk-cli
|
|
30
|
+
[](https://pypi.org/project/snk-cli)
|
|
31
|
+
[](https://pypi.org/project/snk-cli)
|
|
32
|
+
[](https://write-the.wytamma.com/)
|
|
33
|
+
|
|
34
|
+
Used internally by [snk](https://snk.wytamma.com/) to generate dynamic [snakemake](https://snakemake.github.io/) CLIs. You can use `snk-cli` to build self contained snakemake tools. See here for more details -> [https://snk.wytamma.com/workflow_packages](https://snk.wytamma.com/workflow_packages/)
|
snk_cli-0.1.1/README.md
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# snk-cli
|
|
2
|
+
[](https://pypi.org/project/snk-cli)
|
|
3
|
+
[](https://pypi.org/project/snk-cli)
|
|
4
|
+
[](https://write-the.wytamma.com/)
|
|
5
|
+
|
|
6
|
+
Used internally by [snk](https://snk.wytamma.com/) to generate dynamic [snakemake](https://snakemake.github.io/) CLIs. You can use `snk-cli` to build self contained snakemake tools. See here for more details -> [https://snk.wytamma.com/workflow_packages](https://snk.wytamma.com/workflow_packages/)
|
snk_cli-0.1.1/mkdocs.yml
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
|
|
2
|
+
site_name: snk_cli
|
|
3
|
+
# repo_url: https://github.com/wytamma/write-the
|
|
4
|
+
|
|
5
|
+
theme:
|
|
6
|
+
name: "material"
|
|
7
|
+
# homepage: https://write-the.wytamma.com
|
|
8
|
+
# logo: assets/logo.png
|
|
9
|
+
# favicon: images/favicon.png
|
|
10
|
+
palette:
|
|
11
|
+
- scheme: default
|
|
12
|
+
toggle:
|
|
13
|
+
icon: material/brightness-7
|
|
14
|
+
name: Switch to dark mode
|
|
15
|
+
- scheme: slate
|
|
16
|
+
toggle:
|
|
17
|
+
icon: material/brightness-4
|
|
18
|
+
name: Switch to light mode
|
|
19
|
+
features:
|
|
20
|
+
- toc.follow
|
|
21
|
+
- content.action.edit
|
|
22
|
+
|
|
23
|
+
extra:
|
|
24
|
+
social:
|
|
25
|
+
- icon: fontawesome/solid/robot
|
|
26
|
+
link: https://github.com/Wytamma/write-the
|
|
27
|
+
name: Generated with write-the
|
|
28
|
+
|
|
29
|
+
plugins:
|
|
30
|
+
- search
|
|
31
|
+
- mkdocstrings:
|
|
32
|
+
handlers:
|
|
33
|
+
python:
|
|
34
|
+
options:
|
|
35
|
+
docstring_style: "google"
|
|
36
|
+
|
|
37
|
+
markdown_extensions:
|
|
38
|
+
- pymdownx.highlight:
|
|
39
|
+
anchor_linenums: true
|
|
40
|
+
line_spans: __span
|
|
41
|
+
pygments_lang_class: true
|
|
42
|
+
- pymdownx.inlinehilite
|
|
43
|
+
- pymdownx.snippets
|
|
44
|
+
- pymdownx.superfences
|
|
@@ -24,10 +24,13 @@ from snk_cli.workflow import Workflow
|
|
|
24
24
|
class CLI(DynamicTyper):
|
|
25
25
|
"""
|
|
26
26
|
Constructor for the dynamic Snk CLI class.
|
|
27
|
+
|
|
27
28
|
Args:
|
|
28
29
|
workflow_dir_path (Path): Path to the workflow directory.
|
|
30
|
+
|
|
29
31
|
Side Effects:
|
|
30
32
|
Initializes the CLI class.
|
|
33
|
+
|
|
31
34
|
Examples:
|
|
32
35
|
>>> CLI(Path('/path/to/workflow'))
|
|
33
36
|
"""
|
|
@@ -58,10 +61,10 @@ class CLI(DynamicTyper):
|
|
|
58
61
|
)
|
|
59
62
|
else:
|
|
60
63
|
self.snk_config = snk_config
|
|
61
|
-
if self.
|
|
62
|
-
self.version = self.snk_config.version
|
|
63
|
-
else:
|
|
64
|
+
if self.workflow.version:
|
|
64
65
|
self.version = self.workflow.version
|
|
66
|
+
else:
|
|
67
|
+
self.version = self.snk_config.version
|
|
65
68
|
self.options = build_dynamic_cli_options(self.snakemake_config, self.snk_config)
|
|
66
69
|
self.snakefile = self._find_snakefile()
|
|
67
70
|
self.conda_prefix_dir = self.workflow.conda_prefix_dir
|
|
@@ -88,31 +91,35 @@ class CLI(DynamicTyper):
|
|
|
88
91
|
invoke_without_command=True,
|
|
89
92
|
context_settings={"help_option_names": ["-h", "--help"]},
|
|
90
93
|
)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
run_app = RunApp(
|
|
94
|
-
conda_prefix_dir=self.conda_prefix_dir,
|
|
95
|
-
snk_config=self.snk_config,
|
|
96
|
-
singularity_prefix_dir=self.singularity_prefix_dir,
|
|
97
|
-
snakefile=self.snakefile,
|
|
98
|
-
workflow=self.workflow,
|
|
99
|
-
verbose=self.verbose,
|
|
100
|
-
logo=self.logo,
|
|
101
|
-
dynamic_run_options=self.options,
|
|
102
|
-
)
|
|
94
|
+
|
|
103
95
|
# Subcommands
|
|
104
|
-
self.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
96
|
+
if "info" in self.snk_config.commands:
|
|
97
|
+
self.register_command(self.info, help="Show information about the workflow.")
|
|
98
|
+
|
|
99
|
+
if "run" in self.snk_config.commands:
|
|
100
|
+
run_app = RunApp(
|
|
101
|
+
conda_prefix_dir=self.conda_prefix_dir,
|
|
102
|
+
snk_config=self.snk_config,
|
|
103
|
+
singularity_prefix_dir=self.singularity_prefix_dir,
|
|
104
|
+
snakefile=self.snakefile,
|
|
110
105
|
workflow=self.workflow,
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
106
|
+
verbose=self.verbose,
|
|
107
|
+
logo=self.logo,
|
|
108
|
+
dynamic_run_options=self.options,
|
|
109
|
+
)
|
|
110
|
+
self.register_command(
|
|
111
|
+
run_app,
|
|
112
|
+
name="run",
|
|
113
|
+
)
|
|
114
|
+
if "config" in self.snk_config.commands:
|
|
115
|
+
self.register_command(
|
|
116
|
+
ConfigApp(
|
|
117
|
+
workflow=self.workflow,
|
|
118
|
+
options=self.options,
|
|
119
|
+
),
|
|
120
|
+
name="config",
|
|
121
|
+
)
|
|
122
|
+
if self.workflow.environments and "env" in self.snk_config.commands:
|
|
116
123
|
self.register_group(
|
|
117
124
|
EnvApp(
|
|
118
125
|
workflow=self.workflow,
|
|
@@ -123,7 +130,7 @@ class CLI(DynamicTyper):
|
|
|
123
130
|
name="env",
|
|
124
131
|
help="Access the workflow conda environments.",
|
|
125
132
|
)
|
|
126
|
-
if self.workflow.scripts:
|
|
133
|
+
if self.workflow.scripts and "script" in self.snk_config.commands:
|
|
127
134
|
self.register_group(
|
|
128
135
|
ScriptApp(
|
|
129
136
|
workflow=self.workflow,
|
|
@@ -134,7 +141,7 @@ class CLI(DynamicTyper):
|
|
|
134
141
|
name="script",
|
|
135
142
|
help="Access the workflow scripts.",
|
|
136
143
|
)
|
|
137
|
-
if self.workflow.profiles:
|
|
144
|
+
if self.workflow.profiles and "profile" in self.snk_config.commands:
|
|
138
145
|
self.register_group(
|
|
139
146
|
ProfileApp(
|
|
140
147
|
workflow=self.workflow,
|
|
@@ -185,10 +192,14 @@ class CLI(DynamicTyper):
|
|
|
185
192
|
):
|
|
186
193
|
"""
|
|
187
194
|
Create a logo for the CLI.
|
|
195
|
+
|
|
188
196
|
Args:
|
|
189
|
-
|
|
197
|
+
tagline (str, optional): The tagline to include in the logo. Defaults to "A Snakemake workflow CLI generated with snk".
|
|
198
|
+
font (str, optional): The font to use for the logo. Defaults to "small".
|
|
199
|
+
|
|
190
200
|
Returns:
|
|
191
201
|
str: The logo.
|
|
202
|
+
|
|
192
203
|
Examples:
|
|
193
204
|
>>> CLI._create_logo()
|
|
194
205
|
"""
|
|
@@ -203,8 +214,13 @@ class CLI(DynamicTyper):
|
|
|
203
214
|
def _find_snakefile(self):
|
|
204
215
|
"""
|
|
205
216
|
Search possible snakefile locations.
|
|
217
|
+
|
|
206
218
|
Returns:
|
|
207
219
|
Path: The path to the snakefile.
|
|
220
|
+
|
|
221
|
+
Raises:
|
|
222
|
+
FileNotFoundError: If the snakefile is not found.
|
|
223
|
+
|
|
208
224
|
Examples:
|
|
209
225
|
>>> CLI._find_snakefile()
|
|
210
226
|
"""
|
|
@@ -216,8 +232,10 @@ class CLI(DynamicTyper):
|
|
|
216
232
|
def info(self):
|
|
217
233
|
"""
|
|
218
234
|
Display information about current workflow install.
|
|
235
|
+
|
|
219
236
|
Returns:
|
|
220
237
|
str: A JSON string containing information about the current workflow install.
|
|
238
|
+
|
|
221
239
|
Examples:
|
|
222
240
|
>>> CLI.info()
|
|
223
241
|
"""
|
|
@@ -7,18 +7,58 @@ import yaml
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class SnkConfigError(Exception):
|
|
10
|
-
"""
|
|
10
|
+
"""
|
|
11
|
+
Base class for all SNK config exceptions.
|
|
12
|
+
"""
|
|
11
13
|
|
|
12
14
|
class InvalidSnkConfigError(SnkConfigError, ValueError):
|
|
13
|
-
"""
|
|
15
|
+
"""
|
|
16
|
+
Thrown if the given SNK config appears to have an invalid format.
|
|
17
|
+
"""
|
|
14
18
|
|
|
15
19
|
class MissingSnkConfigError(SnkConfigError, FileNotFoundError):
|
|
16
|
-
"""
|
|
20
|
+
"""
|
|
21
|
+
Thrown if the given SNK config file cannot be found.
|
|
22
|
+
"""
|
|
17
23
|
|
|
18
24
|
@dataclass
|
|
19
25
|
class SnkConfig:
|
|
20
26
|
"""
|
|
21
27
|
A dataclass for storing Snakemake workflow configuration.
|
|
28
|
+
|
|
29
|
+
Attributes:
|
|
30
|
+
art (str, optional): The art to display in the CLI. Defaults to None.
|
|
31
|
+
logo (str, optional): The logo to display in the CLI. Defaults to None.
|
|
32
|
+
tagline (str): The tagline to display in the CLI. Defaults to "A Snakemake workflow CLI generated with Snk".
|
|
33
|
+
font (str): The font size for the CLI. Defaults to "small".
|
|
34
|
+
version (Optional[str], optional): The version of the workflow. Defaults to None.
|
|
35
|
+
conda (bool): Whether to use conda for managing environments. Defaults to True.
|
|
36
|
+
resources (List[Path]): List of paths to additional resources. Defaults to an empty list.
|
|
37
|
+
symlink_resources (bool): Whether to symlink resources instead of copying them. Defaults to False.
|
|
38
|
+
skip_missing (bool): Whether to skip missing CLI options. Defaults to False.
|
|
39
|
+
additional_snakemake_args (List[str]): List of additional Snakemake command-line arguments. Defaults to an empty list.
|
|
40
|
+
commands (List[str]): List of subcommands to include in the CLI. Defaults to ["run", "script", "env", "profile", "info", "config"].
|
|
41
|
+
cli (dict): Dictionary of CLI options and their values. Defaults to an empty dictionary.
|
|
42
|
+
_snk_config_path (Path): The path to the SNK config file. Defaults to None.
|
|
43
|
+
|
|
44
|
+
Methods:
|
|
45
|
+
from_path(snk_config_path: Path) -> SnkConfig:
|
|
46
|
+
Load and validate Snk config from file.
|
|
47
|
+
|
|
48
|
+
from_workflow_dir(workflow_dir_path: Path, create_if_not_exists: bool = False) -> SnkConfig:
|
|
49
|
+
Load and validate SNK config from workflow directory.
|
|
50
|
+
|
|
51
|
+
validate_resources(resources: List[Path]) -> None:
|
|
52
|
+
Validate resources.
|
|
53
|
+
|
|
54
|
+
add_resources(resources: List[Path], workflow_dir_path: Path = None) -> None:
|
|
55
|
+
Add resources to the SNK config.
|
|
56
|
+
|
|
57
|
+
to_yaml(path: Path) -> None:
|
|
58
|
+
Write SNK config to YAML file.
|
|
59
|
+
|
|
60
|
+
save() -> None:
|
|
61
|
+
Save SNK config.
|
|
22
62
|
"""
|
|
23
63
|
|
|
24
64
|
art: str = None
|
|
@@ -28,10 +68,11 @@ class SnkConfig:
|
|
|
28
68
|
version: Optional[str] = None
|
|
29
69
|
conda: bool = True
|
|
30
70
|
resources: List[Path] = field(default_factory=list)
|
|
71
|
+
symlink_resources: bool = False
|
|
31
72
|
skip_missing: bool = False # skip any missing cli options (i.e. those not in the snk file)
|
|
32
73
|
additional_snakemake_args: List[str] = field(default_factory=list)
|
|
74
|
+
commands: List[str] = field(default_factory=lambda: ["run", "script", "env", "profile", "info", "config"])
|
|
33
75
|
cli: dict = field(default_factory=dict)
|
|
34
|
-
symlink_resources: bool = False
|
|
35
76
|
_snk_config_path: Path = None
|
|
36
77
|
|
|
37
78
|
@classmethod
|
|
@@ -3,17 +3,24 @@ from snakemake import load_configfile
|
|
|
3
3
|
|
|
4
4
|
def get_version_from_config(config_path: Path, config_dict: dict = None) -> str:
|
|
5
5
|
"""
|
|
6
|
-
Get the version from config
|
|
7
|
-
|
|
8
|
-
Path must be relative to the config file.
|
|
6
|
+
Get the version from the config file or config dictionary.
|
|
7
|
+
|
|
9
8
|
Args:
|
|
10
9
|
config_path (Path): Path to the config file.
|
|
11
|
-
config_dict (dict): Config
|
|
10
|
+
config_dict (dict, optional): Config dictionary. Defaults to None.
|
|
11
|
+
|
|
12
12
|
Returns:
|
|
13
|
-
str:
|
|
13
|
+
str: The version.
|
|
14
|
+
|
|
15
|
+
Raises:
|
|
16
|
+
FileNotFoundError: If the version file (__about__.py) is not found.
|
|
17
|
+
KeyError: If the __version__ key is not found in the version file.
|
|
18
|
+
|
|
14
19
|
Examples:
|
|
15
|
-
>>>
|
|
20
|
+
>>> get_version_from_config(Path("config.yaml"))
|
|
16
21
|
'0.1.0'
|
|
22
|
+
>>> get_version_from_config(Path("config.yaml"), {"version": "0.2.0"})
|
|
23
|
+
'0.2.0'
|
|
17
24
|
"""
|
|
18
25
|
if not config_dict:
|
|
19
26
|
config_dict = load_configfile(config_path)
|
|
@@ -10,27 +10,41 @@ import sys
|
|
|
10
10
|
class DynamicTyper:
|
|
11
11
|
app: typer.Typer
|
|
12
12
|
|
|
13
|
-
def
|
|
14
|
-
|
|
15
|
-
cls.app = typer.Typer()
|
|
13
|
+
def __init__(self):
|
|
14
|
+
self.app = typer.Typer()
|
|
16
15
|
|
|
17
16
|
def __call__(self):
|
|
18
17
|
"""
|
|
19
18
|
Invoke the CLI.
|
|
19
|
+
|
|
20
20
|
Side Effects:
|
|
21
21
|
Invokes the CLI.
|
|
22
|
+
|
|
22
23
|
Examples:
|
|
23
24
|
>>> CLI(Path('/path/to/workflow'))()
|
|
24
25
|
"""
|
|
25
|
-
self.
|
|
26
|
+
self._set_app()
|
|
27
|
+
|
|
28
|
+
def _set_app(self):
|
|
29
|
+
"""
|
|
30
|
+
Set the app attribute.
|
|
31
|
+
|
|
32
|
+
Side Effects:
|
|
33
|
+
Sets the app attribute to a Typer object.
|
|
34
|
+
"""
|
|
35
|
+
if not hasattr(self, "app"):
|
|
36
|
+
self.app = typer.Typer()
|
|
26
37
|
|
|
27
38
|
def register_default_command(self, command: Callable, **command_kwargs) -> None:
|
|
28
39
|
"""
|
|
29
40
|
Register a default command to the CLI.
|
|
41
|
+
|
|
30
42
|
Args:
|
|
31
43
|
command (Callable): The command to register.
|
|
44
|
+
|
|
32
45
|
Side Effects:
|
|
33
46
|
Registers the command to the CLI.
|
|
47
|
+
|
|
34
48
|
Examples:
|
|
35
49
|
>>> CLI.register_default_command(my_command)
|
|
36
50
|
"""
|
|
@@ -65,13 +79,19 @@ class DynamicTyper:
|
|
|
65
79
|
) -> None:
|
|
66
80
|
"""
|
|
67
81
|
Register a command to the CLI.
|
|
82
|
+
|
|
68
83
|
Args:
|
|
69
84
|
command (Callable): The command to register.
|
|
85
|
+
dynamic_options (List[Option], optional): A list of dynamic options to add to the command.
|
|
86
|
+
|
|
70
87
|
Side Effects:
|
|
71
88
|
Registers the command to the CLI.
|
|
89
|
+
|
|
72
90
|
Examples:
|
|
73
91
|
>>> CLI.register_command(my_command)
|
|
92
|
+
>>> CLI.register_command(my_command, dynamic_options=[option1, option2])
|
|
74
93
|
"""
|
|
94
|
+
self._set_app()
|
|
75
95
|
if dynamic_options is not None:
|
|
76
96
|
command = self.add_dynamic_options(command, dynamic_options)
|
|
77
97
|
if isinstance(command, DynamicTyper):
|
|
@@ -82,34 +102,45 @@ class DynamicTyper:
|
|
|
82
102
|
def register_callback(self, command: Callable, **command_kwargs) -> None:
|
|
83
103
|
"""
|
|
84
104
|
Register a callback to the CLI.
|
|
105
|
+
|
|
85
106
|
Args:
|
|
86
107
|
command (Callable): The callback to register.
|
|
108
|
+
|
|
87
109
|
Side Effects:
|
|
88
110
|
Registers the callback to the CLI.
|
|
111
|
+
|
|
89
112
|
Examples:
|
|
90
113
|
>>> CLI.register_callback(my_callback)
|
|
91
114
|
"""
|
|
115
|
+
self._set_app()
|
|
92
116
|
self.app.callback(**command_kwargs)(command)
|
|
93
117
|
|
|
94
118
|
def register_group(self, group: "DynamicTyper", **command_kwargs) -> None:
|
|
95
119
|
"""
|
|
96
|
-
Register a subcommand group
|
|
120
|
+
Register a subcommand group to the CLI.
|
|
121
|
+
|
|
97
122
|
Args:
|
|
98
123
|
group (DynamicTyper): The subcommand group to register.
|
|
124
|
+
|
|
99
125
|
Side Effects:
|
|
100
126
|
Registers the subcommand group to the CLI.
|
|
127
|
+
|
|
101
128
|
Examples:
|
|
102
|
-
>>> CLI.
|
|
129
|
+
>>> CLI.register_group(my_group)
|
|
103
130
|
"""
|
|
131
|
+
self._set_app()
|
|
104
132
|
self.app.add_typer(group.app, **command_kwargs)
|
|
105
133
|
|
|
106
134
|
def _create_cli_parameter(self, option: Option):
|
|
107
135
|
"""
|
|
108
136
|
Creates a parameter for a CLI option.
|
|
137
|
+
|
|
109
138
|
Args:
|
|
110
139
|
option (Option): An Option object containing the option's name, type, required status, default value, and help message.
|
|
140
|
+
|
|
111
141
|
Returns:
|
|
112
142
|
Parameter: A parameter object for the CLI option.
|
|
143
|
+
|
|
113
144
|
Examples:
|
|
114
145
|
>>> option = Option(name='foo', type='int', required=True, default=0, help='A number')
|
|
115
146
|
>>> create_cli_parameter(option)
|
|
@@ -131,8 +162,10 @@ class DynamicTyper:
|
|
|
131
162
|
def check_if_option_passed_via_command_line(self, option: Option):
|
|
132
163
|
"""
|
|
133
164
|
Check if an option is passed via the command line.
|
|
165
|
+
|
|
134
166
|
Args:
|
|
135
167
|
option (Option): An Option object containing the option's name, type, required status, default value, and help message.
|
|
168
|
+
|
|
136
169
|
Returns:
|
|
137
170
|
bool: Whether the option is passed via the command line.
|
|
138
171
|
"""
|
|
@@ -148,15 +181,17 @@ class DynamicTyper:
|
|
|
148
181
|
def add_dynamic_options(self, func: Callable, options: List[Option]):
|
|
149
182
|
"""
|
|
150
183
|
Function to add dynamic options to a command.
|
|
184
|
+
|
|
151
185
|
Args:
|
|
152
|
-
|
|
153
|
-
options (List[
|
|
186
|
+
func (Callable): The command to which the dynamic options should be added.
|
|
187
|
+
options (List[Option]): A list of Option objects containing the options to add.
|
|
188
|
+
|
|
154
189
|
Returns:
|
|
155
190
|
Callable: A function with the dynamic options added.
|
|
191
|
+
|
|
156
192
|
Examples:
|
|
157
|
-
>>> my_func = add_dynamic_options_to_function(my_func, [
|
|
193
|
+
>>> my_func = add_dynamic_options_to_function(my_func, [option1, option2])
|
|
158
194
|
>>> my_func
|
|
159
|
-
<function my_func at 0x7f8f9f9f9f90>
|
|
160
195
|
"""
|
|
161
196
|
func_sig = signature(func)
|
|
162
197
|
params = list(func_sig.parameters.values())
|
|
@@ -168,13 +203,16 @@ class DynamicTyper:
|
|
|
168
203
|
def func_wrapper(*args, **kwargs):
|
|
169
204
|
"""
|
|
170
205
|
Wraps a function with dynamic options.
|
|
206
|
+
|
|
171
207
|
Args:
|
|
172
|
-
|
|
173
|
-
|
|
208
|
+
*args: Variable length argument list.
|
|
209
|
+
**kwargs: Arbitrary keyword arguments.
|
|
210
|
+
|
|
174
211
|
Returns:
|
|
175
|
-
|
|
212
|
+
Callable: A wrapped function with the dynamic options added.
|
|
213
|
+
|
|
176
214
|
Notes:
|
|
177
|
-
|
|
215
|
+
This function is used in the `add_dynamic_options_to_function` function.
|
|
178
216
|
"""
|
|
179
217
|
flat_config = None
|
|
180
218
|
|
|
@@ -216,6 +254,7 @@ class DynamicTyper:
|
|
|
216
254
|
def error(self, msg, exit=True):
|
|
217
255
|
"""
|
|
218
256
|
Logs an error message (red) and exits (optional).
|
|
257
|
+
|
|
219
258
|
Args:
|
|
220
259
|
msg (str): The error message to log.
|
|
221
260
|
exit (bool): Whether to exit after logging the error message.
|
|
@@ -227,6 +266,7 @@ class DynamicTyper:
|
|
|
227
266
|
def success(self, msg):
|
|
228
267
|
"""
|
|
229
268
|
Logs a success message (green).
|
|
269
|
+
|
|
230
270
|
Args:
|
|
231
271
|
msg (str): The success message to log.
|
|
232
272
|
"""
|
|
@@ -235,14 +275,18 @@ class DynamicTyper:
|
|
|
235
275
|
def log(self, msg, color="yellow", stderr=True):
|
|
236
276
|
"""
|
|
237
277
|
Logs a message (yellow).
|
|
278
|
+
|
|
238
279
|
Args:
|
|
239
280
|
msg (str): The message to log.
|
|
281
|
+
color (str, optional): The color of the log message. Defaults to "yellow".
|
|
282
|
+
stderr (bool, optional): Whether to log the message to stderr. Defaults to True.
|
|
240
283
|
"""
|
|
241
284
|
typer.secho(msg, fg=color, err=stderr)
|
|
242
285
|
|
|
243
286
|
def echo(self, msg):
|
|
244
287
|
"""
|
|
245
288
|
Prints a message.
|
|
289
|
+
|
|
246
290
|
Args:
|
|
247
291
|
msg (str): The message to print.
|
|
248
292
|
"""
|
|
@@ -37,13 +37,16 @@ def create_option_from_annotation(
|
|
|
37
37
|
) -> Option:
|
|
38
38
|
"""
|
|
39
39
|
Create an Option object from a given annotation.
|
|
40
|
+
|
|
40
41
|
Args:
|
|
41
|
-
annotation_key: The key in the annotations.
|
|
42
|
-
annotation_values: The dictionary of annotation values.
|
|
43
|
-
default_values:
|
|
42
|
+
annotation_key (str): The key in the annotations.
|
|
43
|
+
annotation_values (dict): The dictionary of annotation values.
|
|
44
|
+
default_values (dict): Default value from config.
|
|
45
|
+
from_annotation (bool, optional): Whether the option is from an annotation. Defaults to False.
|
|
46
|
+
|
|
44
47
|
Returns:
|
|
45
|
-
An Option object.
|
|
46
|
-
"""
|
|
48
|
+
Option: An Option object.
|
|
49
|
+
"""
|
|
47
50
|
config_default = default_values.get(annotation_key, None)
|
|
48
51
|
|
|
49
52
|
default = annotation_values.get(f"{annotation_key}:default", config_default)
|
|
@@ -83,9 +86,11 @@ def build_dynamic_cli_options(
|
|
|
83
86
|
) -> List[dict]:
|
|
84
87
|
"""
|
|
85
88
|
Builds a list of options from a snakemake config and a snk config.
|
|
89
|
+
|
|
86
90
|
Args:
|
|
87
91
|
snakemake_config (dict): A snakemake config.
|
|
88
92
|
snk_config (SnkConfig): A snk config.
|
|
93
|
+
|
|
89
94
|
Returns:
|
|
90
95
|
List[dict]: A list of options.
|
|
91
96
|
"""
|