1313 AssistantMessage ,
1414 ClaudeCodeOptions ,
1515 ClaudeSDKClient ,
16+ CLIConnectionError ,
1617 ResultMessage ,
1718 TextBlock ,
1819)
@@ -27,18 +28,13 @@ async def example_basic_streaming():
2728 await client .send_message ("What is 2+2?" )
2829
2930 # Receive complete response using the helper method
30- messages , result = await client .receive_response ()
31-
32- # Extract text from assistant's response
33- for msg in messages :
31+ async for msg in client .receive_response ():
3432 if isinstance (msg , AssistantMessage ):
3533 for block in msg .content :
3634 if isinstance (block , TextBlock ):
3735 print (f"Claude: { block .text } " )
38-
39- # Print cost if available
40- if result and result .total_cost_usd :
41- print (f"Cost: ${ result .total_cost_usd :.4f} " )
36+ elif isinstance (msg , ResultMessage ) and msg .total_cost_usd :
37+ print (f"Cost: ${ msg .total_cost_usd :.4f} " )
4238
4339 print ("Session ended\n " )
4440
@@ -52,32 +48,22 @@ async def example_multi_turn_conversation():
5248 print ("User: What's the capital of France?" )
5349 await client .send_message ("What's the capital of France?" )
5450
55- messages , _ = await client .receive_response ()
56-
5751 # Extract and print response
58- for msg in messages :
59- if isinstance (msg , AssistantMessage ):
60- for block in msg . content :
61- if isinstance (block , TextBlock ):
62- print (f"Claude: { block .text } " )
52+ async for msg in client . receive_response () :
53+ content_blocks = getattr (msg , 'content' , [])
54+ for block in content_blocks :
55+ if isinstance (block , TextBlock ):
56+ print (f"{ block .text } " )
6357
6458 # Second turn - follow-up
6559 print ("\n User: What's the population of that city?" )
6660 await client .send_message ("What's the population of that city?" )
6761
68- messages , _ = await client .receive_response ()
69-
70- for msg in messages :
71- if isinstance (msg , AssistantMessage ):
72- for block in msg .content :
73- if isinstance (block , TextBlock ):
74- print (f"Claude: { block .text } " )
75-
76- for msg in messages :
77- if isinstance (msg , AssistantMessage ):
78- for block in msg .content :
79- if isinstance (block , TextBlock ):
80- print (f"Claude: { block .text } " )
62+ async for msg in client .receive_response ():
63+ content_blocks = getattr (msg , 'content' , [])
64+ for block in content_blocks :
65+ if isinstance (block , TextBlock ):
66+ print (f"{ block .text } " )
8167
8268 print ("\n Conversation ended\n " )
8369
@@ -102,7 +88,7 @@ async def receive_messages():
10288 questions = [
10389 "What is 2 + 2?" ,
10490 "What is the square root of 144?" ,
105- "What is 15 % of 80?" ,
91+ "What is 10 % of 80?" ,
10692 ]
10793
10894 for question in questions :
@@ -168,9 +154,7 @@ async def consume_messages():
168154 await client .send_message ("Never mind, just tell me a quick joke" )
169155
170156 # Get the joke
171- messages , result = await client .receive_response ()
172-
173- for msg in messages :
157+ async for msg in client .receive_response ():
174158 if isinstance (msg , AssistantMessage ):
175159 for block in msg .content :
176160 if isinstance (block , TextBlock ):
@@ -233,10 +217,8 @@ async def example_with_options():
233217 "Create a simple hello.txt file with a greeting message"
234218 )
235219
236- messages , result = await client .receive_response ()
237-
238220 tool_uses = []
239- for msg in messages :
221+ async for msg in client . receive_response () :
240222 if isinstance (msg , AssistantMessage ):
241223 for block in msg .content :
242224 if isinstance (block , TextBlock ):
@@ -257,48 +239,34 @@ async def example_error_handling():
257239 client = ClaudeSDKClient ()
258240
259241 try :
260- # Connect with custom stream
261- async def message_stream ():
262- yield {
263- "type" : "user" ,
264- "message" : {"role" : "user" , "content" : "Hello" },
265- "parent_tool_use_id" : None ,
266- "session_id" : "error-demo" ,
267- }
268-
269- await client .connect (message_stream ())
242+ await client .connect ()
270243
271- # Create a background task to consume messages (required for interrupt to work)
272- consume_task = None
244+ # Send a message that will take time to process
245+ await client . send_message ( "Run a bash sleep command for 60 seconds" )
273246
274- async def consume_messages ():
275- """Background message consumer."""
276- async for msg in client .receive_messages ():
277- if isinstance (msg , AssistantMessage ):
278- print ("Received response from Claude" )
279-
280- # Receive messages with timeout
247+ # Try to receive response with a short timeout
281248 try :
282- # Start consuming messages in background
283- consume_task = asyncio .create_task (consume_messages ())
284-
285- # Wait for response with timeout
286- await asyncio .wait_for (consume_task , timeout = 30.0 )
249+ messages = []
250+ async with asyncio .timeout (10.0 ):
251+ async for msg in client .receive_response ():
252+ messages .append (msg )
253+ if isinstance (msg , AssistantMessage ):
254+ for block in msg .content :
255+ if isinstance (block , TextBlock ):
256+ print (f"Claude: { block .text [:50 ]} ..." )
257+ elif isinstance (msg , ResultMessage ):
258+ print ("Received complete response" )
259+ break
287260
288261 except asyncio .TimeoutError :
289- print ("Response timeout - sending interrupt" )
290- # Note: interrupt requires active message consumption
291- # Since we're already consuming in the background task, interrupt will work
292- await client .interrupt ()
262+ print ("\n Response timeout after 10 seconds - demonstrating graceful handling" )
263+ print (f"Received { len (messages )} messages before timeout" )
293264
294- # Cancel the consume task
295- if consume_task :
296- consume_task .cancel ()
297- with contextlib .suppress (asyncio .CancelledError ):
298- await consume_task
265+ except CLIConnectionError as e :
266+ print (f"Connection error: { e } " )
299267
300268 except Exception as e :
301- print (f"Error : { e } " )
269+ print (f"Unexpected error : { e } " )
302270
303271 finally :
304272 # Always disconnect
0 commit comments