Skip to main content

Lightweight contract helpers for Snakemake modules

Project description

snakemake-contracts

A small helper library for Snakemake workflows that use provides / requires-style contracts between modules.

Motivation

A lot of hidden complexities can stem from splitting a snakemake-based project into multiple independent submodules: how do you handle changing independent submodule outputs ?

This package exists for workflows that are split into many Snakemake submodules and need a disciplined way to connect them.

In practice, the goal is not just to reuse code. It is to make module boundaries explicit and stable:

  • each module should declare what it consumes and what it exposes;
  • each module should keep its own outputs defined in one place;
  • the root workflow should not become the only place that knows where every generated file lives.

That matters once a workflow grows beyond a single Snakefile. At that point the top-level repo tends to accumulate accidental knowledge about other modules: hard-coded file paths, config overrides for foreign outputs, and ad hoc assumptions about directory layouts. Those shortcuts make the graph harder to reason about and much easier to break when a module changes shape.

The contract model used here is intentionally close to the requires / provides style found in systems like nREPL middleware chains: producers declare the interface they offer, consumers ask for a named capability, and the resolver stays small and mechanical. The point is to treat the dependency boundary as a contract, not as an implicit convention spread across the whole repository.

Using provides.yaml as the source of truth also has a practical benefit: the module itself remains the authoritative owner of its exported outputs. The repo root can still orchestrate modules, but it does not need to mirror every output name or path in a central registry. That reduces duplication and keeps the dependency metadata next to the module that owns it.

Scope

  • resolve declared outputs by logical key
  • locate module output directories
  • validate provides.yaml files
  • optionally compare declared contracts against a repo layout

Library Usage

The core API lives in snakemake_contracts.contracts and expects a repo layout like:

repo/
  modules/
    my_module/
      Snakefile
      provides.yaml
      out/

Typical usage:

from snakemake_contracts.contracts import load_provides, provides, validate_repo

mapping = load_provides("my_module", repo_root="/path/to/repo")
report = provides("my_module", "report", repo_root="/path/to/repo")
problems = validate_repo("/path/to/repo")

provides.yaml is the source of truth for logical output names, and provides() resolves them relative to the module's out/ directory.

Wrapper Layer

The repository now also includes a separate wrapper/ package, snakemake_contracts_wrapper, for Snakemake-facing command construction. That layer is intentionally thin: it reads the named input, output, and params objects already present in a rule and turns them into ordinary script arguments.

The script itself still stays unaware of Snakemake. It only sees CLI flags. The wrapper only removes the repetitive --flag {input.foo} wiring in the Snakefile.

When .cache is configured, the Snakemake wrapper can synthesize a default log path under .cache/logs/, but it only passes that path as --log when scripts_accept_log_arg: true is also set in the workflow config. This opt-in is required because cache usage alone does not prove that every wrapped script supports a --log CLI argument.

Current Surface

  • load_provides(module, repo_root=None)
  • provides(module, key, repo_root=None)
  • out_dir(module, repo_root=None)
  • list_modules(repo_root=None)
  • mangle(name)
  • validate_repo(repo_root=None)

Wrapper surface:

  • build_argv(command, input=None, output=None, params=None, exclude_input=("script",))
  • render_shell(command, input=None, output=None, params=None, exclude_input=("script",))

Tests

  • tests/test_contracts.py exercises the library directly against a temporary repo layout.
  • tests/test_wrapper.py covers the wrapper command helpers.

Status

This is a small utility package, not a general Snakemake extension. It is meant to support workflows that already use provides.yaml-style contracts and want a single place to validate and resolve them.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

snakemake_contracts-0.4.0.tar.gz (7.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

snakemake_contracts-0.4.0-py3-none-any.whl (5.2 kB view details)

Uploaded Python 3

File details

Details for the file snakemake_contracts-0.4.0.tar.gz.

File metadata

  • Download URL: snakemake_contracts-0.4.0.tar.gz
  • Upload date:
  • Size: 7.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for snakemake_contracts-0.4.0.tar.gz
Algorithm Hash digest
SHA256 f9f79889df25da448967b6b05aa6242b516cdea952f2239608d1ada0413a4083
MD5 235da55b02a5fc9633e4fdd7f6db6297
BLAKE2b-256 5df818c30481d3ccd7dfe5666f230dacd4d5d2e6cfc42149fe2d58f1674b5511

See more details on using hashes here.

File details

Details for the file snakemake_contracts-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for snakemake_contracts-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ee053c31907811348a753264a863a4c5be844be1dc97685b847b864db9f4c216
MD5 b3f8ace05b2d3f596a4d73ed0b37cb01
BLAKE2b-256 be19c05accee6d7be07c2c9f2ba94e6a2c5ebedc422b906b1024d597d02c9894

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page