Code intermediate · 3 min read

How to use AssistantEventHandler in Python

Direct answer
Use AssistantEventHandler in Python by subclassing it and overriding event methods to handle assistant events, then register your handler with the OpenAI assistant client.

Setup

Install
bash
pip install openai
Env vars
OPENAI_API_KEY
Imports
python
from openai import OpenAI
from openai.assistants import AssistantEventHandler
import os

Examples

inInitialize AssistantEventHandler to log messages on assistant response.
outPrinted log of assistant response content.
inCreate a custom event handler to modify messages before sending.
outModified message content sent to the assistant and printed response.
inUse AssistantEventHandler to handle errors during assistant calls.
outError details printed when an exception occurs.

Integration steps

  1. Import AssistantEventHandler and subclass it to define event methods.
  2. Override methods like on_message or on_error to handle events.
  3. Initialize the OpenAI client with your API key from os.environ.
  4. Register your custom event handler with the assistant client or event system.
  5. Send messages to the assistant and let the event handler process events.
  6. Extract and use the assistant's response as needed.

Full code

python
import os
from openai import OpenAI
from openai.assistants import AssistantEventHandler

class MyAssistantEventHandler(AssistantEventHandler):
    def on_message(self, message):
        print(f"Assistant sent a message: {message}")

    def on_error(self, error):
        print(f"Error occurred: {error}")


def main():
    client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

    handler = MyAssistantEventHandler()

    # Example usage: simulate sending a message and triggering event
    try:
        # Normally you would register handler with assistant client or event system
        # Here we simulate calling the handler manually for demonstration
        user_message = {"role": "user", "content": "Hello, assistant!"}

        # Simulate assistant response
        assistant_response = {"role": "assistant", "content": "Hello! How can I help you today?"}

        # Trigger event handler method
        handler.on_message(assistant_response)

        # Call the chat completion endpoint
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[user_message]
        )

        print("Assistant reply:", response.choices[0].message.content)

    except Exception as e:
        handler.on_error(e)


if __name__ == "__main__":
    main()
output
Assistant sent a message: {'role': 'assistant', 'content': 'Hello! How can I help you today?'}
Assistant reply: Hello! How can I help you today?

API trace

Request
json
{"model": "gpt-4o", "messages": [{"role": "user", "content": "Hello, assistant!"}]}
Response
json
{"choices": [{"message": {"role": "assistant", "content": "Hello! How can I help you today?"}}], "usage": {"total_tokens": 20}}
Extractresponse.choices[0].message.content

Variants

Streaming event handler

Use streaming event handler to process partial assistant responses in real time for better UX.

python
import os
from openai import OpenAI
from openai.assistants import AssistantEventHandler

class StreamingEventHandler(AssistantEventHandler):
    def on_message(self, message):
        print(f"Streamed message chunk: {message}")


def main():
    client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
    handler = StreamingEventHandler()

    # Example streaming call with event handler
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": "Stream this response."}],
        stream=True
    )

    for chunk in response:
        handler.on_message(chunk.choices[0].delta)

if __name__ == "__main__":
    main()
Async event handler

Use async event handler when integrating with async frameworks or concurrent workflows.

python
import os
import asyncio
from openai import OpenAI
from openai.assistants import AssistantEventHandler

class AsyncEventHandler(AssistantEventHandler):
    async def on_message(self, message):
        print(f"Async received message: {message}")

async def main():
    client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
    handler = AsyncEventHandler()

    user_message = {"role": "user", "content": "Hello async!"}

    response = await client.chat.completions.acreate(
        model="gpt-4o",
        messages=[user_message]
    )

    await handler.on_message(response.choices[0].message)
    print("Assistant reply:", response.choices[0].message.content)

if __name__ == "__main__":
    asyncio.run(main())
Alternative model usage

Use a smaller model like gpt-4o-mini for faster, lower-cost responses with slightly reduced capability.

python
import os
from openai import OpenAI
from openai.assistants import AssistantEventHandler

class SimpleHandler(AssistantEventHandler):
    def on_message(self, message):
        print(f"Message from assistant: {message}")


def main():
    client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
    handler = SimpleHandler()

    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": "Use a smaller model."}]
    )

    handler.on_message(response.choices[0].message)
    print("Assistant reply:", response.choices[0].message.content)

if __name__ == "__main__":
    main()

Performance

Latency~800ms for <code>gpt-4o</code> non-streaming calls
Cost~$0.002 per 500 tokens for <code>gpt-4o</code>
Rate limitsTier 1: 500 requests per minute / 30,000 tokens per minute
  • Keep messages concise to reduce token usage.
  • Use smaller models like <code>gpt-4o-mini</code> for cheaper calls.
  • Cache frequent prompts and responses to avoid repeated calls.
ApproachLatencyCost/callBest for
Standard event handler~800ms~$0.002Simple event handling in synchronous code
Streaming event handlerVaries, near real-timeSimilar to standardReal-time partial response processing
Async event handler~800ms~$0.002Integration with async applications

Quick tip

Subclass <code>AssistantEventHandler</code> and override only the events you need to keep your code clean and maintainable.

Common mistake

Beginners often forget to register or invoke their <code>AssistantEventHandler</code>, resulting in no event callbacks firing.

Verified 2026-04 · gpt-4o, gpt-4o-mini
Verify ↗