What You’ll Master Here
A dependency is an edge. Everything in this chapter is a different notation for drawing the same edges — pick the notation that makes the shape obvious to a reviewer.
Two things share this chapter, and they are the two halves of authoring a real DAG: how you write a task, and how you wire tasks into a shape. Most pipelines are not a straight line — they fan out, fan in, and cross — and the shapes you can express determine the pipelines you can build.
Start with the shapes. Pick one below and read the graph, then read every syntax that produces it. The Cross shape is worth lingering on, because it is the one that cannot be written the obvious way.
extract >> [clean, validate] >> load
# one line, four tasks, two levels of parallelismA dependency is an edge. Everything in this chapter is a different notation for drawing the same edges — pick the notation that makes the shape obvious to a reviewer.
Dependency wiring is where a DAG stops being three tasks in a row and starts being a pipeline. It is also where a quiet class of bug lives: a mis-written fan-out gives you fewer edges than you intended, the DAG still parses, the Graph view still looks plausible, and tasks run in an order you did not design.
- >>
- The shift operator, read as “must finish before”. a >> b means b waits for a.
- Fan out
- One task followed by several that can run in parallel.
- Fan in
- Several tasks joining into one that waits for all of them.
- chain()
- A helper that wires a sequence of tasks and lists in order. Pairs equal-length lists element-wise.
- cross_downstream()
- A helper connecting every task in one list to every task in another — the full cross that lists alone cannot express.
Assuming [a, b] >> [c, d] connects everything to everything. It does not build the four edges you pictured. Use cross_downstream() when you genuinely need every upstream connected to every downstream — otherwise you get a graph with missing edges and tasks that start earlier than intended.
Draw the shape before writing the code. Almost every wiring bug is a shape that was never drawn.
Prefer the notation that makes the shape visible: lists for hand-written graphs, chain() for generated ones.
Check the Graph view after any wiring change. It is the fastest confirmation that the edges are what you meant.
Every notation here produces identical graphs. The only question is which one makes your intent obvious six months later.
Learn the five shapes and the notations that build them. Everything else in DAG authoring is filling them in.
