01Real-world example

Edges run nodes in order. Each step adds its result to the state, and nothing is lost on the way.


total=False lets the state start with only test_name; the other keys are filled in on the way.stream(..., stream_mode="updates") yields one dict per step: {node_name: what_it_changed}.cd chapter_18_LangGraph/src/chapters
python 002_Linear_Pipeline.py
setup changed -> {'browser': 'chromium'}
execute changed -> {'status': 'passed'}
teardown changed -> {'cleaned_up': True}
Work in chapter_18_LangGraph/src/chapters. Change one thing, run it, and compare with the expected result.
Add a report node between execute and teardown that returns {"report": "1 passed"}.
Loop over app.stream(..., stream_mode="values") and print each item.
{'test_name': 'login_works'}.Make execute return {"status": "failed"}. Does teardown still run?
The exact file from the course repo, plus the output it printed when this page was written.
"""002 - Three nodes in a row, like a test's setup -> execute -> teardown.
Each node returns a *partial* update. Keys it does not return are left alone.
stream_mode="updates" shows you exactly what each node changed, step by step.
"""
from typing import TypedDict
from langgraph.graph import END, START, StateGraph
class State(TypedDict, total=False):
test_name: str
browser: str
status: str
cleaned_up: bool
def setup(state: State) -> dict:
return {"browser": "chromium"}
def execute(state: State) -> dict:
return {"status": "passed"}
def teardown(state: State) -> dict:
return {"cleaned_up": True}
builder = StateGraph(State)
builder.add_node("setup", setup)
builder.add_node("execute", execute)
builder.add_node("teardown", teardown)
builder.add_edge(START, "setup")
builder.add_edge("setup", "execute")
builder.add_edge("execute", "teardown")
builder.add_edge("teardown", END)
app = builder.compile()
if __name__ == "__main__":
for step in app.stream({"test_name": "login_works"}, stream_mode="updates"):
for node, update in step.items():
print(f"{node:<9} changed -> {update}")
print("\nFinal state:", app.invoke({"test_name": "login_works"}))
setup changed -> {'browser': 'chromium'}
execute changed -> {'status': 'passed'}
teardown changed -> {'cleaned_up': True}