SSE 流式响应 = 一个"异步迭代器" 每次 yield 一个事件,直到流结束。 就像: 普通迭代器: for item in [1, 2, 3] → 立即可用 异步迭代器: async for item in stream → 可能要等网络
()
| 180 | # ============================================================ |
| 181 | |
| 182 | def lesson_3_async_iterator(): |
| 183 | """ |
| 184 | SSE 流式响应 = 一个"异步迭代器" |
| 185 | 每次 yield 一个事件,直到流结束。 |
| 186 | |
| 187 | 就像: |
| 188 | 普通迭代器: for item in [1, 2, 3] → 立即可用 |
| 189 | 异步迭代器: async for item in stream → 可能要等网络 |
| 190 | """ |
| 191 | print("\n" + "=" * 60) |
| 192 | print("第三课: 异步迭代器(SSE 流的基础)") |
| 193 | print("=" * 60) |
| 194 | |
| 195 | # 用 async generator 模拟 SSE 流 |
| 196 | async def fake_sse_stream() -> AsyncIterator[dict]: |
| 197 | """模拟 Anthropic API 的 SSE 流""" |
| 198 | events = [ |
| 199 | {"type": "message_start", "message": {"id": "msg_123"}}, |
| 200 | {"type": "content_block_start", "index": 0}, |
| 201 | {"type": "content_block_delta", "delta": {"text": "Hello"}}, |
| 202 | {"type": "content_block_delta", "delta": {"text": " World"}}, |
| 203 | {"type": "content_block_delta", "delta": {"text": "!"}}, |
| 204 | {"type": "content_block_stop", "index": 0}, |
| 205 | {"type": "message_stop"}, |
| 206 | ] |
| 207 | for event in events: |
| 208 | await asyncio.sleep(0.1) # 模拟网络延迟 |
| 209 | yield event # 像 return,但不终止函数 |
| 210 | |
| 211 | async def consume_stream(): |
| 212 | """消费 SSE 流,逐字拼接文本""" |
| 213 | full_text = "" |
| 214 | async for event in fake_sse_stream(): |
| 215 | event_type = event["type"] |
| 216 | if event_type == "content_block_delta": |
| 217 | chunk = event["delta"]["text"] |
| 218 | full_text += chunk |
| 219 | print(f" 收到: '{chunk}' (累计: '{full_text}')") |
| 220 | else: |
| 221 | print(f" 事件: {event_type}") |
| 222 | return full_text |
| 223 | |
| 224 | print("\n 模拟 SSE 流消费:") |
| 225 | result = asyncio.run(consume_stream()) |
| 226 | print(f"\n 最终文本: '{result}'") |
| 227 | |
| 228 | print(""" |
| 229 | 关键语法: |
| 230 | async def stream() -> AsyncIterator: |
| 231 | yield item # async generator |
| 232 | |
| 233 | async for item in stream(): |
| 234 | process(item) # async for 循环 |
| 235 | |
| 236 | 这就是 Claude Code 的 MessageStream.next_event() 的 Python 版。 |
| 237 | """) |
| 238 | |
| 239 |
no test coverage detected