claude-code-sdk-python/examples/streaming_mode_trio.py
Dickson Tsai 5f8351fce9
Some checks are pending
Lint / lint (push) Waiting to run
Test / test (3.10) (push) Waiting to run
Test / test (3.11) (push) Waiting to run
Test / test (3.12) (push) Waiting to run
Test / test (3.13) (push) Waiting to run
Make streaming implementation trio-compatible (#84)
## Summary
- Replace asyncio.create_task() with anyio task group for trio
compatibility
- Update client.py docstring example to use anyio.sleep
- Add trio example demonstrating multi-turn conversation

## Details
The SDK already uses anyio for most async operations, but one line was
using asyncio.create_task() which broke trio compatibility. This PR
fixes that by using anyio's task group API with proper lifecycle
management.

### Changes:
1. **subprocess_cli.py**: Replace asyncio.create_task() with anyio task
group, ensuring proper cleanup on disconnect
2. **client.py**: Update docstring example to use anyio.sleep instead of
asyncio.sleep
3. **streaming_mode_trio.py**: Add new example showing how to use the
SDK with trio

## Test plan
- [x] All existing tests pass
- [x] Manually tested with trio runtime (created test script that
successfully runs multi-turn conversation)
- [x] Linting and type checking pass

🤖 Generated with [Claude Code](https://claude.ai/code)
2025-07-22 23:31:42 -07:00

80 lines
2.3 KiB
Python

#!/usr/bin/env python3
"""
Example of multi-turn conversation using trio with the Claude SDK.
This demonstrates how to use the ClaudeSDKClient with trio for interactive,
stateful conversations where you can send follow-up messages based on
Claude's responses.
"""
import trio
from claude_code_sdk import (
AssistantMessage,
ClaudeCodeOptions,
ClaudeSDKClient,
ResultMessage,
SystemMessage,
TextBlock,
UserMessage,
)
def display_message(msg):
"""Standardized message display function.
- UserMessage: "User: <content>"
- AssistantMessage: "Claude: <content>"
- SystemMessage: ignored
- ResultMessage: "Result ended" + cost if available
"""
if isinstance(msg, UserMessage):
for block in msg.content:
if isinstance(block, TextBlock):
print(f"User: {block.text}")
elif isinstance(msg, AssistantMessage):
for block in msg.content:
if isinstance(block, TextBlock):
print(f"Claude: {block.text}")
elif isinstance(msg, SystemMessage):
# Ignore system messages
pass
elif isinstance(msg, ResultMessage):
print("Result ended")
async def multi_turn_conversation():
"""Example of a multi-turn conversation using trio."""
async with ClaudeSDKClient(
options=ClaudeCodeOptions(model="claude-3-5-sonnet-20241022")
) as client:
print("=== Multi-turn Conversation with Trio ===\n")
# First turn: Simple math question
print("User: What's 15 + 27?")
await client.query("What's 15 + 27?")
async for message in client.receive_response():
display_message(message)
print()
# Second turn: Follow-up calculation
print("User: Now multiply that result by 2")
await client.query("Now multiply that result by 2")
async for message in client.receive_response():
display_message(message)
print()
# Third turn: One more operation
print("User: Divide that by 7 and round to 2 decimal places")
await client.query("Divide that by 7 and round to 2 decimal places")
async for message in client.receive_response():
display_message(message)
print("\nConversation complete!")
if __name__ == "__main__":
trio.run(multi_turn_conversation)