This repository provides formatting for Snakemake files. It follows the
design and specifications of Black.
[!WARNING]
snakefmt modifies files in-place by default, thus we strongly
recommend ensuring your files are under version control before doing any formatting.
You can also pipe the file in from stdin, which will print it to the screen, or use the
--diff or --check options. See Usage for more details.
[!IMPORTANT]
Recent Changes:
Rule and module directives are now sorted by default:snakefmt will automatically sort the order of directives inside rules (e.g. input, output, shell) and modules into a consistent order. You can opt out of this by using the --no-sort CLI flag.
Black upgraded to v26: The underlying black formatter has been upgraded to v26. You will see changes in how implicitly concatenated strings are wrapped (they are now collapsed onto a single line if they fit within the line limit) and other minor adjustments compared to previous versions.
Example of expected differences:
# Before (Snakefmt older versions)
rule example:
shell:
"for i in $(seq 1 5);"
"do echo $i;"
"done"
output:
"b.txt",
input:
"a.txt",
# After (Directives sorted, strings collapsed by Black 26)
rule example:
input:
"a.txt",
output:
"b.txt",
shell:
"for i in $(seq 1 5);" "do echo $i;" "done"
# install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
git clone https://github.com/snakemake/snakefmt && cd snakefmt
# install snakefmt in a new environment
make install
# you can now run snakefmt with
uv run snakefmt --help
Example File
Input
from snakemake.utils import min_version
min_version("5.14.0")
configfile: "config.yaml" # snakemake keywords are treated like classes i.e. 2 newlines
SAMPLES = ['s1', 's2'] # strings are normalised
CONDITIONS = ["a", "b", "longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong"] # long lines are wrapped
include: "rules/foo.smk" # 2 newlines
rule all:
input: "data/results.txt" # newlines after keywords enforced and trailing comma
rule gets_separated_by_two_newlines:
input:
files = expand("long/string/to/data/files/gets_broken_by_black/{sample}.{condition}",sample=SAMPLES, condition=CONDITIONS)
if True:
rule can_be_inside_python_code:
input: "parameters", "get_indented"
threads: 4 # Numeric params stay unindented
params: key_val = "PEP8_formatted"
run:
print("weirdly_spaced_string_gets_respaced")
Output
from snakemake.utils import min_version
min_version("5.14.0")
configfile: "config.yaml" # snakemake keywords are treated like classes i.e. 2 newlines
SAMPLES = ["s1", "s2"] # strings are normalised
CONDITIONS = [
"a",
"b",
"longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglong",
] # long lines are wrapped
include: "rules/foo.smk" # 2 newlines
rule all:
input:
"data/results.txt", # newlines after keywords enforced and trailing comma
rule gets_separated_by_two_newlines:
input:
files=expand(
"long/string/to/data/files/gets_broken_by_black/{sample}.{condition}",
sample=SAMPLES,
condition=CONDITIONS,
),
if True:
rule can_be_inside_python_code:
input:
"parameters",
"get_indented",
threads: 4 # Numeric params stay unindented
params:
key_val="PEP8_formatted",
run:
print("weirdly_spaced_string_gets_respaced")
Usage
Basic Usage
Format a single Snakefile.
snakefmt Snakefile
Format all Snakefiles within a directory.
snakefmt workflows/
Format a file but write the output to stdout.
snakefmt - < Snakefile
Full Usage
$ snakefmt --help
Usage: snakefmt [OPTIONS] [SRC]...
The uncompromising Snakemake code formatter.
SRC specifies directories and files to format. Directories will be searched
for file names that conform to the include/exclude patterns provided.
Files are modified in-place by default; use diff, check, or `snakefmt - <
Snakefile` to avoid this.
Options:
-l, --line-length INT Lines longer than INT will be wrapped. [default:
88]
-s, --sort / -S, --no-sort Sort directives in rules and modules. [default:
sort]
--check Don't write the files back, just return the
status. Return code 0 means nothing would
change. Return code 1 means some files would be
reformatted. Return code 123 means there was an
error.
-d, --diff Don't write the files back, just output a diff
for each file to stdout.
--compact-diff Same as --diff but only shows lines that would
change plus a few lines of context.
--include PATTERN A regular expression that matches files and
directories that should be included on recursive
searches. An empty value means all files are
included regardless of the name. Use forward
slashes for directories on all platforms
(Windows, too). Exclusions are calculated
first, inclusions later. [default:
(\.smk$|^Snakefile)]
--exclude PATTERN A regular expression that matches files and
directories that should be excluded on recursive
searches. An empty value means no paths are
excluded. Use forward slashes for directories on
all platforms (Windows, too). Exclusions are
calculated first, inclusions later. [default: (
\.snakemake/|\.eggs/|\.git/|\.hg/|\.mypy_cache/|
\.nox/|\.tox/|\.venv/|\.svn/|_build/|buck-
out/|/build/|/dist/|\.template/)]
-c, --config PATH Read configuration from PATH. By default, will
try to read from `./pyproject.toml`
-h, --help Show this message and exit.
-V, --version Show the version and exit.
-v, --verbose Turns on debug-level logger.
Directive Sorting
By default, snakefmt sorts rule and module directives (like input, output, shell, etc.) into a consistent order. This makes rules easier to read and allows for quicker cross-referencing between inputs, outputs, and the resources used by the execution command.
Directives are grouped by their functional role in the following order:
This ordering ensures that the directives most frequently used in execution blocks (like threads, resources, and params) are placed immediately above the action directive.
You can disable this feature using the --no-sort flag.
Format Directives
snakefmt supports comment directives to control formatting behaviour for specific regions of code.
Directives should appear as standalone comment lines, an inline occurrence (e.g. input: # fmt: off) is treated as a plain comment and has no effect.
All directives are scope-local: only the region they select is affected, while code before and after follows normal snakefmt formatting and spacing rules (equivalent to replacing the directive with a plain comment line).
# fmt: off / # fmt: on
Disables all formatting for the region between the two directives.
Both directives must appear at the same indentation level; a # fmt: on at a deeper indent than the matching # fmt: off has no effect.
rule a:
input:
"a.txt",
# fmt: off
rule b:
input: "b.txt"
output:
"c.txt"
# fmt: on
rule c:
input:
"d.txt",
Note: inside run: blocks and other Python contexts, # fmt: off / # fmt: on is passed through to Black, which handles it natively.
# fmt: off[sort]
Disables directive sorting for the enclosed region while still applying all other formatting.
Directives between # fmt: off[sort] and # fmt: on[sort] are kept in their original order.
A plain # fmt: on also closes a # fmt: off[sort] region.
Disables formatting for the single next Snakemake keyword block (e.g. rule, checkpoint, use rule).
Only that block is left unformatted; all subsequent blocks are formatted normally.
# fmt: skip preserves a single line exactly as written, without any formatting (see Black’s documentation for details).
Note:# fmt: skip is not yet supported within Snakemake rule blocks.
It currently applies only to plain Python lines outside of rules, checkpoints, and similar Snakemake constructs.
Configuration
snakefmt is able to read project-specific default values for its command line options
from a pyproject.toml file. In addition, it will also load any black
configurations you have in the same file.
By default, snakefmt will search in the parent directories of the formatted file(s)
for a file called pyproject.toml and use any configuration there.
If your configuration file is located somewhere else or called something different,
specify it using --config.
Any options you pass on the command line will take precedence over default values in the
configuration file.
Snakefmt
This repository provides formatting for Snakemake files. It follows the design and specifications of Black.
Table of Contents
Install
PyPi
Conda
Containers
As
snakefmthas a Conda recipe, there is a matching image built for each version by Biocontainers.In the following examples, all tags (
<tag>) can be found here.Docker
Singularity
Local
These instructions include installing
uv.Example File
Input
Output
Usage
Basic Usage
Format a single Snakefile.
Format all Snakefiles within a directory.
Format a file but write the output to stdout.
Full Usage
Directive Sorting
By default,
snakefmtsorts rule and module directives (likeinput,output,shell, etc.) into a consistent order. This makes rules easier to read and allows for quicker cross-referencing between inputs, outputs, and the resources used by the execution command.Directives are grouped by their functional role in the following order:
name,default_targetinput,output,log,benchmarkwildcard_constraints,pathvarspriority,retries,group,localrule,cache,handovershadow,conda,container,singularity,containerized,envmodulesthreads,resources,paramsmessageshell,run,script,notebook,wrapper,cwl,template_engineThis ordering ensures that the directives most frequently used in execution blocks (like
threads,resources, andparams) are placed immediately above the action directive.You can disable this feature using the
--no-sortflag.Format Directives
snakefmtsupports comment directives to control formatting behaviour for specific regions of code. Directives should appear as standalone comment lines, an inline occurrence (e.g.input: # fmt: off) is treated as a plain comment and has no effect. All directives are scope-local: only the region they select is affected, while code before and after follows normalsnakefmtformatting and spacing rules (equivalent to replacing the directive with a plain comment line).# fmt: off/# fmt: onDisables all formatting for the region between the two directives. Both directives must appear at the same indentation level; a
# fmt: onat a deeper indent than the matching# fmt: offhas no effect.# fmt: off[sort]Disables directive sorting for the enclosed region while still applying all other formatting. Directives between
# fmt: off[sort]and# fmt: on[sort]are kept in their original order. A plain# fmt: onalso closes a# fmt: off[sort]region.# fmt: off[next]Disables formatting for the single next Snakemake keyword block (e.g.
rule,checkpoint,use rule). Only that block is left unformatted; all subsequent blocks are formatted normally.# fmt: skip# fmt: skippreserves a single line exactly as written, without any formatting (see Black’s documentation for details).Configuration
snakefmtis able to read project-specific default values for its command line options from apyproject.tomlfile. In addition, it will also load anyblackconfigurations you have in the same file.By default,
snakefmtwill search in the parent directories of the formatted file(s) for a file calledpyproject.tomland use any configuration there. If your configuration file is located somewhere else or called something different, specify it using--config.Any options you pass on the command line will take precedence over default values in the configuration file.
Example
pyproject.toml