Order Processing with Typed State Keys¶
Tip
What you’ll learn How to work with state keys and state transforms.
Source: 21_statekey.py
from adk_fluent import StateKey
# Define typed state keys for an order processing system
order_count = StateKey("order_count", scope="session", type=int, default=0)
cart_items = StateKey("cart_items", scope="temp", type=list, default=[])
customer_tier = StateKey("customer_tier", scope="user", type=str, default="standard")
store_version = StateKey("store_version", scope="app", type=str, default="v2.1")
# StateKey auto-builds the full key with scope prefix:
# session scope: no prefix (default ADK behavior)
# temp/user/app: prefixed as "temp:key", "user:key", "app:key"
# Usage in callbacks/tools:
# current = order_count.get(ctx) # Returns int, typed
# order_count.increment(ctx) # Convenience for numerics
# cart_items.append(ctx, {"sku": "LAPTOP-001", "qty": 1})
# Native ADK uses raw string keys and untyped state access:
# ctx.state["order_count"] = ctx.state.get("order_count", 0) + 1
# ctx.state["temp:cart_items"] = []
#
# Problems: typos are silent, no type hints, scope prefixes are manual,
# and there's no way to set defaults or validate types.
Equivalence¶
# Key construction with correct scope prefixes
assert order_count.key == "order_count" # session scope = no prefix
assert cart_items.key == "temp:cart_items"
assert customer_tier.key == "user:customer_tier"
assert store_version.key == "app:store_version"
# Properties
assert order_count.name == "order_count"
assert order_count.scope == "session"
# Get/set with mock state
class MockCtx:
def __init__(self):
self.state = {}
ctx = MockCtx()
assert order_count.get(ctx) == 0 # Returns default when unset
order_count.set(ctx, 5)
assert order_count.get(ctx) == 5
# Increment: track how many orders processed
order_count.increment(ctx)
assert order_count.get(ctx) == 6
# Append: build up a shopping cart
cart_items.append(ctx, {"sku": "LAPTOP-001", "qty": 1})
cart_items.append(ctx, {"sku": "MOUSE-042", "qty": 2})
assert cart_items.get(ctx) == [{"sku": "LAPTOP-001", "qty": 1}, {"sku": "MOUSE-042", "qty": 2}]
# Invalid scope raises ValueError
import pytest
with pytest.raises(ValueError, match="Invalid scope"):
StateKey("bad", scope="nonexistent")