Task Dependencies

In many workflows, tasks depend on the results of other tasks. Pravaha allows you to define task dependencies using the depends_on attribute.

Defining dependencies ensures that tasks are executed in the correct order and prevents failures caused by missing prerequisites.

Defining Dependencies

Pravaha supports two types of dependencies:

  1. OR-based dependencies

  2. AND-based dependencies

OR-based Dependencies

An OR-based dependency means that a task will execute if at least one of its dependent tasks completes successfully.

Example

from pravaha.core.task import Task
from pravaha.core.executor import TaskExecutor
from pravaha.dependency.dependency import Dependency

# Dependency(type="OR | AND", dependencies=list[str])
@Task("a", depends_on=Dependency("OR", dependencies=["b", "c"]))
def a():
    print("a")

@Task("b")
def b():
    pass

@Task("c")
def c():
    pass

TaskExecutor.execute()

AND-based Dependencies

An AND-based dependency means that a task will execute only if all of its dependent tasks complete successfully.

AND-based dependencies can be defined in two ways.

### 1. Implicit AND dependency using a list

By default, passing a list to depends_on is treated as an AND dependency.

from pravaha.core.task import Task
from pravaha.core.executor import TaskExecutor

@Task(name="task1", depends_on=["task2"])
def task1():
    print("Task1 executed")

@Task(name="task2")
def task2():
    print("Task2 executed")

if __name__ == "__main__":
    TaskExecutor.execute()

Expected Output

Task2 executed
Task1 executed

### 2. Explicit AND dependency using Dependency

You can also explicitly define an AND-based dependency using the Dependency object.

from pravaha.core.task import Task
from pravaha.core.executor import TaskExecutor
from pravaha.dependency.dependency import Dependency

# Dependency(type="OR | AND", dependencies=list[str])
@Task("a", depends_on=Dependency("AND", dependencies=["b", "c"]))
def a():
    print("a")

@Task("b")
def b():
    pass

@Task("c")
def c():
    pass

TaskExecutor.execute()

Notes

  • Task registration order does not matter when dependencies are defined.

  • The executor automatically determines the correct execution order based on the dependency graph.

  • Circular dependencies are not allowed. Ensure that your workflow graph is acyclic (DAG).