@@ -15,24 +15,28 @@ You can subscribe to events by creating an event handler class and overloading t
1515
1616``` python
1717from typing_extensions import override
18- from openai import AssistantEventHandler
18+ from openai import AssistantEventHandler, OpenAI
19+ from openai.types.beta.threads import Text, TextDelta
20+ from openai.types.beta.threads.runs import ToolCall, ToolCallDelta
21+
22+ client = openai.OpenAI()
1923
2024# First, we create a EventHandler class to define
2125# how we want to handle the events in the response stream.
2226
2327class EventHandler (AssistantEventHandler ):
2428 @override
25- def on_text_created (self , text ) -> None :
29+ def on_text_created (self , text : Text ) -> None :
2630 print (f " \n assistant > " , end = " " , flush = True )
2731
2832 @override
29- def on_text_delta (self , delta , snapshot ):
33+ def on_text_delta (self , delta : TextDelta , snapshot : Text ):
3034 print (delta.value, end = " " , flush = True )
3135
32- def on_tool_call_created (self , tool_call ):
36+ def on_tool_call_created (self , tool_call : ToolCall ):
3337 print (f " \n assistant > { tool_call.type} \n " , flush = True )
3438
35- def on_tool_call_delta (self , delta , snapshot ):
39+ def on_tool_call_delta (self , delta : ToolCallDelta , snapshot : ToolCall ):
3640 if delta.type == ' code_interpreter' :
3741 if delta.code_interpreter.input:
3842 print (delta.code_interpreter.input, end = " " , flush = True )
@@ -47,14 +51,64 @@ class EventHandler(AssistantEventHandler):
4751# and stream the response.
4852
4953with client.beta.threads.runs.create_and_stream(
50- thread_id = thread.id,
51- assistant_id = assistant.id,
52- instructions = " Please address the user as Jane Doe. The user has a premium account." ,
54+ thread_id = " thread_id" ,
55+ assistant_id = " assistant_id" ,
5356 event_handler = EventHandler(),
5457) as stream:
5558 stream.until_done()
5659```
5760
61+ #### An example of iterating over events
62+
63+ You can also iterate over all the streamed events.
64+
65+ ``` python
66+ with client.beta.threads.runs.create_and_stream(
67+ thread_id = thread.id,
68+ assistant_id = assistant.id
69+ ) as stream:
70+ for event in stream:
71+ # Print the text from text delta events
72+ if event.type == " thread.message.delta" and event.data.delta.content:
73+ print (event.data.delta.content[0 ].text)
74+ ```
75+
76+ #### An example of iterating over text
77+
78+ You can also iterate over just the text deltas received
79+
80+ ``` python
81+ with client.beta.threads.runs.create_and_stream(
82+ thread_id = thread.id,
83+ assistant_id = assistant.id
84+ ) as stream:
85+ for text in stream.text_deltas:
86+ print (text)
87+ ```
88+
89+ ### Creating Streams
90+
91+ There are three helper methods for creating streams:
92+
93+ ``` python
94+ client.beta.threads.runs.create_and_stream()
95+ ```
96+
97+ This method can be used to start and stream the response to an existing run with an associated thread
98+ that is already populated with messages.
99+
100+ ``` python
101+ client.beta.threads.create_and_run_stream()
102+ ```
103+
104+ This method can be used to add a message to a thread, start a run and then stream the response.
105+
106+ ``` python
107+ client.beta.threads.runs.submit_tool_outputs_stream()
108+ ```
109+
110+ This method can be used to submit a tool output to a run waiting on the output and start a stream.
111+
58112### Assistant Events
59113
60114The assistant API provides events you can subscribe to for the following events.
@@ -139,22 +193,22 @@ This event is triggered if an exception occurs during streaming.
139193The assistant streaming object also provides a few methods for convenience:
140194
141195``` python
142- def current_event ()
143- def current_run ()
144- def current_message_snapshot ()
145- def current_run_step_snapshot ()
196+ def current_event () -> AssistantStreamEvent | None
197+ def current_run() -> Run | None
198+ def current_message_snapshot() -> Message | None
199+ def current_run_step_snapshot() -> RunStep | None
146200```
147201
148202These methods are provided to allow you to access additional context from within event handlers. In many cases
149203the handlers should include all the information you need for processing, but if additional context is required it
150204can be accessed.
151205
152- Note: There is not always a relevant context in certain situations (these will be undefined in those cases).
206+ Note: There is not always a relevant context in certain situations (these will be ` None ` in those cases).
153207
154208```python
155- def get_final_run (self )
156- def get_final_run_steps (self )
157- def get_final_messages (self )
209+ def get_final_run(self ) -> Run
210+ def get_final_run_steps(self ) -> List[RunStep]
211+ def get_final_messages(self ) -> List[Message]
158212```
159213
160214These methods are provided for convenience to collect information at the end of a stream. Calling these events
0 commit comments