@@ -35,7 +35,11 @@ def __init__(self, http_client: AsyncClient, api_key: str, base_url: str) -> Non
3535 """Initialize the client."""
3636 self ._http_client = http_client
3737 self ._url = f"{ base_url .rstrip ('/' )} /responses"
38- self ._headers = {
38+ self ._json_headers = {
39+ "authorization" : f"Bearer { api_key } " ,
40+ "accept" : "application/json" ,
41+ }
42+ self ._stream_headers = {
3943 "authorization" : f"Bearer { api_key } " ,
4044 "accept" : "text/event-stream" ,
4145 }
@@ -48,7 +52,7 @@ async def create_response(self, **params: Any) -> dict[str, Any]:
4852 response = await self ._http_client .post (
4953 self ._url ,
5054 json = body ,
51- headers = self ._headers ,
55+ headers = self ._json_headers ,
5256 )
5357 response .raise_for_status ()
5458 except HTTPStatusError as err :
@@ -69,7 +73,7 @@ async def stream_response(self, **params: Any) -> AsyncGenerator[dict[str, Any]]
6973 "POST" ,
7074 self ._url ,
7175 json = body ,
72- headers = self ._headers ,
76+ headers = self ._stream_headers ,
7377 ) as response :
7478 response .raise_for_status ()
7579 async for event in _iter_sse_events (response .aiter_lines ()):
@@ -104,26 +108,49 @@ def _strip_none_values(value: Any) -> Any:
104108async def _iter_sse_events (lines : AsyncIterable [str ]) -> AsyncGenerator [dict [str , Any ]]:
105109 """Yield JSON server-sent events from an Open Responses stream."""
106110 event_type : str | None = None
111+ data_lines : list [str ] = []
112+ done = False
113+
114+ async def flush_event () -> dict [str , Any ] | None :
115+ nonlocal done , event_type , data_lines
116+
117+ if not data_lines :
118+ event_type = None
119+ return None
120+
121+ data = "\n " .join (data_lines )
122+ event_type_for_payload = event_type
123+ event_type = None
124+ data_lines = []
125+
126+ if data == "[DONE]" :
127+ done = True
128+ return None
129+
130+ event = json .loads (data )
131+ if event_type_for_payload and "type" not in event :
132+ event ["type" ] = event_type_for_payload
133+ return event
107134
108135 async for line in lines :
136+ if done :
137+ return
109138 if not line :
110- event_type = None
139+ if event := await flush_event ():
140+ yield event
141+ if done :
142+ return
111143 continue
112144 if line .startswith ("event:" ):
113145 event_type = line .split (":" , 1 )[1 ].strip ()
114146 continue
115147 if not line .startswith ("data:" ):
116148 continue
117149
118- data = line .split (":" , 1 )[1 ].strip ()
119- if data == "[DONE]" :
120- return
150+ data_lines .append (line .split (":" , 1 )[1 ].strip ())
121151
122- event = json .loads (data )
123- if event_type and "type" not in event :
124- event ["type" ] = event_type
152+ if event := await flush_event ():
125153 yield event
126- event_type = None
127154
128155
129156def _raise_client_error (err : HTTPStatusError ) -> None :
0 commit comments