Search code examples
pythonsnakemake

How to access variables defined in the snakefile in a snakemake wrapper?


I would like to write a snakemake wrapper able to adapt its behaviour based on the value of variables defined in the main snakefile.

This doesn't seem to simply work, I get a NameError when I try to use such a variable in the wrapper.

In particular, I wanted to have the wrapper add module load ... and module unload ... commands around shell commands when run on a cluster that uses such a mechanism to put some programs in the PATH, based on information defined in the configuration file:

In the main snakefile:

load_modules = False
# By default, cluster nodes are expected
# to have names starting with "tars"
cluster_prefix = config.get("cluster_prefix", "tars")
if cluster_prefix:
    from socket import gethostname
    if gethostname().startswith(cluster_prefix):
        load_modules = True

# ...

rule ...:
    # ...
    wrapper:
        "file://path/to/the/wrapper/folder"

Then, in the corresponding wrapper.py file:

if load_modules:
    # ...

This results in:

NameError: name 'load_modules' is not defined

Is it possible to make the wrapper aware of some variables without going through extra params sections in the rules?


Solution

  • One possibility that does not require to add things to the params section of rules is to store variables in config, which is accessible in snakemake wrappers as snakemake.config.

    For instance, in the snakefile:

    # By default, cluster nodes are expected
    # to have names starting with "tars"
    cluster_prefix = config.get("cluster_prefix", "tars")
    if cluster_prefix:
        from socket import gethostname
        if gethostname().startswith(cluster_prefix):
            config["load_modules"] = True
    
    # ...
    
    rule ...:
        # ...
        wrapper:
            "file://path/to/the/wrapper/folder"
    

    And in the wrapper.py:

    load_modules = snakemake.config.get("load_modules", False)
    if load_modules:
        # ...