litellm/tests/unit/llms/openai/realtime
devin-ai-integration[bot] fa2c8984ba
test: move the unit half of 126 mixed legacy files into tests/unit (#45090)
* test: move the unit half of 126 mixed legacy files into tests/unit

* test: restore litellm globals that moved tests set

* test: finalize migration test cleanup

* test: restore original bodies of moved legacy tests

The move into tests/unit had rewritten 612 test bodies, and some of the rewrites dropped assertions. Each moved test now carries its original body from the legacy file, with only the imports, helpers, fake provider credentials and monkeypatched env it needs to run under tests/unit

test_timeout_streaming goes back to tests/local_testing because it needs the fake OpenAI endpoint server. The image payload fixture moves with its only user, and two tests that leaked global state (a registered model cost entry and queued logging tasks) are now isolated

* test: drop module imports shadowed by restored local imports

* test: assert on LiteLLM output in no-assertion moved tests and isolate leaks

Twenty no-assertion candidates get one assertion on the value LiteLLM returns, with the original lines unchanged. Four tests go back to their legacy files because they only check types or imports, write into the working directory, or cannot assert without a body change

Two moved tests leaked globals into later tests in the same worker, so monkeypatch fixtures now restore the retry-after header parser and the end user cost tracking flags

* test: drain queued logging tasks before the Phoenix span test

The moved Phoenix test counted spans from logging tasks that earlier tests had queued, so the drain fixture moves to tests/unit/conftest.py and both it and the Datadog batch test use it. test_factory_function goes back to its legacy file because its returned wrapper calls the real Assistants API and cannot be asserted on without a body change

---------

Co-authored-by: yuneng <yuneng@berri.ai>
2026-10-07 14:07:43 -07:00
..
__init__.py test: move tests/test_litellm/llms into tests/unit/llms (#43191) 2026-09-25 12:43:23 -07:00
README.md test: move tests/test_litellm/llms into tests/unit/llms (#43191) 2026-09-25 12:43:23 -07:00
test_openai_realtime_handler.py test: move the unit half of 126 mixed legacy files into tests/unit (#45090) 2026-10-07 14:07:43 -07:00
test_transcription_sessions.py refactor(llms): expose public names for private provider helpers (#45037) 2026-10-07 08:49:25 -07:00

OpenAI Realtime Handler Tests

Important Context: additional_headers vs extra_headers

Background

There was confusion about the correct parameter name for passing headers to websockets.connect(). This README documents the resolution for future maintainers.

Timeline of Changes

  1. Dec 5, 2025 - Changed extra_headers → additional_headers (commit 8db7f1b8e4)
  2. Dec 18, 2025 - Changed extra_headers → additional_headers again (PR #17950, commit 9f88d61d10)
  3. Jan 15, 2026 - Upgraded websockets from 13.1.0 → 15.0.1 (commit a3cf178e24, Issue #19089)

The Issue & Resolution

The websockets library changed its API between versions:

  • websockets < 14.0: Used extra_headers parameter ✅
  • websockets >= 14.0: Uses additional_headers parameter ✅

LiteLLM uses websockets 15.0.1 (per uv.lock), which requires additional_headers.

Verification

You can verify the correct parameter name:

uv run python -c "import websockets; import inspect; print(inspect.signature(websockets.connect))"

This shows: additional_headers: 'HeadersLike | None' = None for websockets 15.0.1.

Current Implementation (Correct)

# ✅ Correct for websockets 15.0.1+
await websockets.connect(url, additional_headers={
    "Authorization": f"Bearer {api_key}",
    "OpenAI-Beta": "realtime=v1"
})

Impact

This is NOT just a test fix - this was a critical bug that affected all realtime APIs:

  • OpenAI realtime
  • Azure realtime
  • xAI realtime
  • Any pass-through realtime connections

Using extra_headers with websockets 15.0.1 resulted in:

TypeError: connect() got an unexpected keyword argument 'extra_headers'

For Future Maintainers

If you see test failures related to header parameters:

  1. Check installed websockets version:

    uv run python -c "import websockets; print(websockets.__version__)"
    
  2. Check uv.lock for the pinned version

  3. Verify the correct parameter:

    • websockets >= 14.0: use additional_headers
    • websockets < 14.0: use extra_headers
  4. Ensure consistency across all files:

    • litellm/llms/openai/realtime/handler.py
    • litellm/llms/azure/realtime/handler.py
    • litellm/llms/custom_httpx/llm_http_handler.py
    • litellm/realtime_api/main.py
    • litellm/proxy/pass_through_endpoints/pass_through_endpoints.py

Current Status (Feb 2026):

  • ✅ websockets version: 15.0.1
  • ✅ Correct parameter: additional_headers
  • ✅ All handlers updated and working