portkey-python-sdk icon indicating copy to clipboard operation
portkey-python-sdk copied to clipboard

fix: properly handle extra_body parameter to match OpenAI SDK behavior

Open roh26it opened this issue 4 days ago • 0 comments

Problem

When users pass extra_body={'a': 'b'} to API methods like client.chat.completions.create(), the contents should be merged at the top level of the request body. Instead, the SDK was nesting it under an extra_body key.

Expected request body:

{"model": "...", "messages": [...], "a": "b"}

Actual (buggy) request body:

{"model": "...", "messages": [...], "extra_body": {"a": "b"}}

This breaks compatibility with OpenAI SDK conventions and causes issues when users try to pass provider-specific parameters like Anthropic's thinking parameter.

Root Cause

The SDK was passing kwargs directly to the OpenAI SDK's extra_body parameter:

# Before (buggy)
extra_body=kwargs  # kwargs = {'extra_body': {'a': 'b'}} → nested incorrectly

Solution

Added extract_extra_params() helper in utils.py that:

  1. Extracts extra_body from kwargs
  2. Merges its contents with remaining kwargs
  3. Returns properly structured params for the OpenAI SDK
# After (fixed)
extra_params = extract_extra_params(kwargs)
**extra_params  # extra_body={'a': 'b'} → 'a' at top level

Files Changed

  • utils.py - Added extract_extra_params() helper function
  • 11 API files updated to use the helper:
    • chat_complete.py
    • complete.py
    • embeddings.py
    • moderations.py
    • models.py
    • audio.py
    • images.py
    • batches.py
    • fine_tuning.py
    • uploads.py
    • evals.py

Testing

from portkey_ai.api_resources.utils import extract_extra_params

# Test: extra_body contents should be at top level
kwargs = {'extra_body': {'thinking': {'type': 'enabled'}}, 'custom_field': 'value'}
result = extract_extra_params(kwargs)
assert result['extra_body'] == {'thinking': {'type': 'enabled'}, 'custom_field': 'value'}
# ✓ Both extra_body contents AND custom kwargs merged at top level

Note

5 files still have the old pattern and may need fixing in a follow-up PR:

  • assistants.py
  • threads.py
  • main_files.py
  • vector_stores.py
  • beta_chat.py

roh26it avatar Nov 28 '25 19:11 roh26it