Skip to content

Commit

Permalink
feat: Updated workflows documentation for issue #47
Browse files Browse the repository at this point in the history
  • Loading branch information
KamenDimitrov97 committed Aug 5, 2024
1 parent 39695cb commit a4fc3ad
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 9 deletions.
75 changes: 69 additions & 6 deletions docs/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,26 @@ Notice that the `increment` tasks appears twice in the CWL workflow definition,
This duplication can be avoided by explicitly indicating that the parameters are the same, with the `param` function.

```python
>>> @task()
... def increment(num: int) -> int:
... """Increment an integer."""
... return num + 1
>>>
>>> @task()
... def double(num: int) -> int:
... """Double an integer."""
... return 2 * num
>>>
>>> @task()
... def mod10(num: int) -> int:
... """Take num mod 10."""
... return num % 10
>>>
>>> @task()
... def sum(left: int, right: int) -> int:
... """Add two integers."""
... return left + right
>>>
>>> num = param("num", default=3)
>>> result = sum(
... left=double(num=increment(num=num)),
Expand Down Expand Up @@ -249,6 +269,12 @@ As code:

```python
>>> from dewret.tasks import nested_task
>>> INPUT_NUM = 3
>>> @task()
... def rotate(num: int) -> int:
... """Rotate an integer."""
... return (num + INPUT_NUM) % INPUT_NUM
>>>
>>> @nested_task()
... def double_rotate(num: int) -> int:
... """Rotate an integer twice."""
Expand Down Expand Up @@ -531,8 +557,27 @@ A special form of nested task is available to help divide up
more complex workflows: the *subworkflow*. By wrapping logic in subflows,
dewret will produce multiple output workflows that reference each other.

```
```python
>>> from dewret.tasks import subworkflow
>>> from attrs import define
>>> from numpy import random
>>> @define
... class PackResult:
... hearts: int
... clubs: int
... spades: int
... diamonds: int
>>>
>>> @task()
... def shuffle(max_cards_per_suit: int) -> PackResult:
... """Fill a random pile from a card deck, suit by suit."""
... return PackResult(
... hearts=random.randint(max_cards_per_suit),
... clubs=random.randint(max_cards_per_suit),
... spades=random.randint(max_cards_per_suit),
... diamonds=random.randint(max_cards_per_suit)
... )
>>>
>>> my_param = param("num", typ=int)
>>> @subworkflow()
... def red_total():
Expand All @@ -546,6 +591,10 @@ dewret will produce multiple output workflows that reference each other.
... left=shuffle(max_cards_per_suit=13).spades,
... right=shuffle(max_cards_per_suit=13).clubs
... )
>>> @task()
... def sum(left: int, right: int) -> int:
... return left + right
>>>
>>> total = sum(left=red_total(), right=black_total())
>>> workflow = construct(total, simplify_ids=True)
>>> cwl, subworkflows = render(workflow)
Expand Down Expand Up @@ -585,7 +634,7 @@ As we have used subworkflow to wrap the colour totals, the outer workflow
contains references to them only. The subworkflows are now returned by `render`
as a second term.

```
```python
>>> yaml.dump(subworkflows["red_total-1"], sys.stdout, indent=2)
class: Workflow
cwlVersion: 1.2
Expand Down Expand Up @@ -662,11 +711,18 @@ the chosen renderer has the capability.

Below is the default output, treating `Pack` as a task.

```
```python
>>> from dewret.tasks import subworkflow, factory
>>> @define
... class PackResult:
... hearts: int
... clubs: int
... spades: int
... diamonds: int
>>>
>>> my_param = param("num", typ=int)
>>> Pack = factory(PackResult)
>>> @nested_task()
>>> @subworkflow()
... def black_total(pack: PackResult):
... return sum(
... left=pack.spades,
Expand Down Expand Up @@ -740,11 +796,18 @@ steps:
The CWL renderer is also able to treat `pack` as a parameter, if complex
types are allowed.

```
```python
>>> from dewret.tasks import subworkflow, factory
>>> @define
... class PackResult:
... hearts: int
... clubs: int
... spades: int
... diamonds: int
>>>
>>> my_param = param("num", typ=int)
>>> Pack = factory(PackResult)
>>> @nested_task()
>>> @subworkflow()
... def black_total(pack: PackResult):
... return sum(
... left=pack.spades,
Expand Down
17 changes: 14 additions & 3 deletions example/workflow_complex.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,26 @@
```
"""

from dewret.tasks import nested_task
from dewret.tasks import subworkflow
from workflow_tasks import sum, double, increase

STARTING_NUMBER: int = 23


@nested_task()
@subworkflow()
def nested_workflow() -> int | float:
"""Creates a graph of task calls."""
"""Creates a complex workflow with a nested task.
Workflow Steps:
1. **Increase**: The starting number (`STARTING_NUMBER`) is incremented by 1 using the `increase` task.
2. **Double**: The result from the first step is then doubled using the `double` task.
3. **Increase Again**: Separately, the number 17 is incremented twice using the `increase` task.
4. **Sum**: Finally, the results of the two branches (left and right) are summed together using the `sum` task.
Returns:
- `int | float`: The result of summing the doubled and increased values, which may be an integer or a float depending on the operations.
"""
left = double(num=increase(num=STARTING_NUMBER))
right = increase(num=increase(num=17))
return sum(left=left, right=right)

0 comments on commit a4fc3ad

Please sign in to comment.