99
1010Note on serialization
1111---------------------
12- The Durable Task SDK serializes dataclass and namedtuple inputs to JSON.
13- When deserialized on the receiving side, top-level objects become
14- ``SimpleNamespace`` instances while nested objects become plain ``dict``s.
15- Activities that receive complex inputs should therefore use dict-style
16- access (``item["quantity"]``) for nested data.
12+ The Durable Task SDK serializes dataclass inputs to JSON. Annotating an
13+ orchestrator's or activity's input parameter with its dataclass type lets the
14+ SDK reconstruct that type on the receiving side (including nested dataclass
15+ fields), so the functions below use attribute access (``order.items``,
16+ ``item.quantity``). Without a type annotation, payloads arrive as plain
17+ ``dict`` / ``list`` values and would need dict-style access instead.
1718"""
1819
1920from dataclasses import dataclass
2526# ---------------------------------------------------------------------------
2627# Data models
2728# ---------------------------------------------------------------------------
28- # These dataclasses document the expected shape of the data. At runtime,
29- # they are serialized to JSON and arrive in activities as SimpleNamespace
30- # (top-level) or dict ( nested) objects .
29+ # These dataclasses describe the shape of the data. Because the orchestrators
30+ # and activities annotate their inputs with these types, the SDK reconstructs
31+ # them (including the nested ``OrderItem`` list) on the receiving side .
3132
3233
3334@dataclass
3435class OrderItem :
35- """A single item in an order (arrives as a ``dict`` inside activities) ."""
36+ """A single item in an order."""
3637 name : str
3738 quantity : int
3839 unit_price : float
3940
4041
4142@dataclass
4243class Order :
43- """An order containing one or more items (arrives as ``SimpleNamespace``) ."""
44+ """An order containing one or more items."""
4445 customer : str
4546 items : list [OrderItem ]
4647
@@ -50,25 +51,25 @@ class Order:
5051# ---------------------------------------------------------------------------
5152
5253
53- def validate_order (ctx : task .ActivityContext , order ) -> None :
54+ def validate_order (ctx : task .ActivityContext , order : Order ) -> None :
5455 """Validate that the order has items and all quantities/prices are valid.
5556
5657 Raises ``ValueError`` on invalid input.
5758 """
5859 if not order .items :
5960 raise ValueError ("Order must contain at least one item" )
6061 for item in order .items :
61- if item [ " quantity" ] <= 0 :
62+ if item . quantity <= 0 :
6263 raise ValueError (
63- f"Invalid quantity for '{ item [ ' name' ] } ': { item [ ' quantity' ] } " )
64- if item [ " unit_price" ] < 0 :
64+ f"Invalid quantity for '{ item . name } ': { item . quantity } " )
65+ if item . unit_price < 0 :
6566 raise ValueError (
66- f"Invalid price for '{ item [ ' name' ] } ': { item [ ' unit_price' ] } " )
67+ f"Invalid price for '{ item . name } ': { item . unit_price } " )
6768
6869
69- def calculate_total (ctx : task .ActivityContext , items : list ) -> float :
70- """Return the total cost for a list of item dicts ."""
71- return sum (item [ " quantity" ] * item [ " unit_price" ] for item in items )
70+ def calculate_total (ctx : task .ActivityContext , items : list [ OrderItem ] ) -> float :
71+ """Return the total cost for a list of order items ."""
72+ return sum (item . quantity * item . unit_price for item in items )
7273
7374
7475def process_payment (ctx : task .ActivityContext , amount : float ) -> str :
@@ -95,7 +96,7 @@ def ship_item(ctx: task.ActivityContext, item_name: str) -> str:
9596# ---------------------------------------------------------------------------
9697
9798
98- def process_order (ctx : task .OrchestrationContext , order ):
99+ def process_order (ctx : task .OrchestrationContext , order : Order ):
99100 """Process a complete order: validate, pay, ship items in parallel, confirm.
100101
101102 Demonstrates:
@@ -115,7 +116,7 @@ def process_order(ctx: task.OrchestrationContext, order):
115116
116117 # 4. Ship all items in parallel (fan-out / fan-in)
117118 ship_tasks : list [task .Task [str ]] = [
118- ctx .call_activity (ship_item , input = item [ " name" ] )
119+ ctx .call_activity (ship_item , input = item . name )
119120 for item in order .items
120121 ]
121122 tracking_ids : list [str ] = yield task .when_all (ship_tasks )
@@ -135,7 +136,7 @@ def process_order(ctx: task.OrchestrationContext, order):
135136 }
136137
137138
138- def order_with_approval (ctx : task .OrchestrationContext , order ):
139+ def order_with_approval (ctx : task .OrchestrationContext , order : Order ):
139140 """Order workflow that requires manager approval for high-value orders.
140141
141142 Demonstrates:
0 commit comments