Skip to content

Debug Task Execution at Render Time

Description

The --eager flag is designed to help users debug tasks and workflows during render time, before the final CWL (or other) workflow is generated.

Normally, dewret builds a lazy task graph that is rendered into a declarative workflow (e.g., CWL, Snakemake). However, this can make debugging difficult, since no code is actually executed during rendering.

With --eager, dewret will:

  • Directly execute the task using the provided inputs
  • Print the result to the terminal
  • Bypass the lazy rendering pipeline

This allows you to: - Test tasks in isolation - Verify that input arguments are valid - Inspect real outputs before committing to workflow generation


Usage

When using eager evaluation, dewret will evaluate and execute the workflow immediately, rather than generating a declarative workflow. This is useful for debugging and inspecting runtime behavior.


Simple workflow or task

Given the following workflow:

# eager_demo.py
from dewret.tasks import (
    workflow,
    task,
)

@task()
def sum(left: int, right: int) -> int:
    print("left", left)
    print("right", right)
    return left + right

@workflow()
def black_total(
    hearts: int,
    clubs: int,
    spades: int,
    diamonds: int
) -> int:
    print("hearts", hearts)
    print("spades", spades)
    print("diamonds", diamonds)
    print("clubs", clubs)
    return sum(left=spades, right=clubs)

Run a single task via CLI:

python -m dewret --eager eager_demo.py sum "left:10" "right:11"

Output:

{'left': 10, 'right': 11}
{'left': <class 'int'>, 'right': <class 'int'>, 'return': <class 'int'>}
left 10
right 11
21

Run the full workflow via CLI:

python -m dewret --eager eager_demo.py black_total "hearts:10" "spades:11" "diamonds:12" "clubs:13"

Output:

{'hearts': 10, 'spades': 11, 'diamonds': 12, 'clubs': 13}
{'hearts': <class 'int'>, 'clubs': <class 'int'>, 'spades': <class 'int'>, 'diamonds': <class 'int'>, 'return': <class 'int'>}
hearts 10
spades 11
diamonds 12
clubs 13

{'left': 11, 'right': 13}
{'left': <class 'int'>, 'right': <class 'int'>, 'return': <class 'int'>}
left 11
right 13
24

Debugging workflows with custom objects

For more complex cases using factories or dataclasses, use eager evaluation in code like this:

# this block is formatted to comply with doctests
>>> from attrs import define
>>> from dewret.core import set_configuration
>>> from dewret.tasks import workflow, factory, task

>>> @define
... class PackResult:
...     hearts: int
...     clubs: int
...     spades: int
...     diamonds: int

>>> Pack = factory(PackResult)

>>> @task()
... def sum(left: int, right: int) -> int:
...     print("left", left)
...     print("right", right)
...     return left + right

>>> @workflow()
... def black_total(pack: PackResult) -> int:
...     print("pack", type(pack))
...     print("hearts", pack.hearts)
...     print("spades", pack.spades)
...     print("diamonds", pack.diamonds)
...     print("clubs", pack.clubs)
...     return sum(left=pack.spades, right=pack.clubs)

>>> with set_configuration(eager=True):
...     pack = Pack(hearts=13, spades=13, diamonds=13, clubs=13)
...     output = black_total(pack=pack)
...     print("output", output)
pack <class '__main__.PackResult'>
hearts 13
spades 13
diamonds 13
clubs 13
left 13
right 13
output 26

Debugging with eager on VS code

100%