Conversation
OpenAI-compatible run_chat_completion / run_response wrappers can now receive the incoming request headers by declaring an optional 'headers' parameter. The OpenAI router forwards headers to the wrapper only when the method declares the parameter (or **kwargs), so existing wrappers are unaffected. Removes the need for custom middleware + a ContextVar to bridge request headers to a wrapper for use cases like per-request identity/token forwarding. Assisted-by: Claude:claude-opus-4-8
Adds tests for the behaviour introduced in the previous commit. Two wrapper fixtures under tests/test_files/files/ deploy through the normal path: one declares `headers` and echoes the Authorization header back, the other keeps the existing (model, messages, body) signature and must be called unchanged. The end-to-end checks are skipped when the installed fastapi-openai-compat predates header forwarding, since the wrapper cannot receive headers the router never passes on. They activate on their own once a version that forwards them is installed. `_method_accepts_kwarg` and `_build_call_kwargs` get unit tests, covering explicit parameters, **kwargs, wrappers that do not opt in, callables without an introspectable signature, and headers=None from non-HTTP entry points. Also wraps the `_build_call_kwargs` signature to stay inside the 120-column limit, and documents the opt-in on run_response and on both async variants, which the previous commit only did for run_chat_completion. Assisted-by: Claude:claude-opus-5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Expose request headers to pipeline wrapper run methods (opt-in)
Closes #251.
run_chat_completion/run_response, and their async variants, can now receivethe incoming request headers by declaring an optional
headersparameter. TheOpenAI router forwards them only when the method declares the parameter, or
**kwargs, so existing wrappers are unaffected.This removes the need for custom middleware plus a
ContextVarto get a headersuch as
Authorizationinto a wrapper, which is the usual approach today forper-request identity or token forwarding.
Requires a fastapi-openai-compat release
Header forwarding has to happen in
fastapi-openai-compatfirst, since that iswhat invokes the
run_completioncallback: fastapi-openai-compat/pull/6. Until a versioncontaining it is installed, this change is inert. I have deliberately left the
fastapi-openai-compat>=1.2.0floor alone here, so the pin can be bumped onceyou have released the other side.
Question for maintainers
If a wrapper declares
headerswithout a default, and the installed compatversion does not forward headers, the call fails with
TypeError: run_chat_completion() missing 1 required positional argument: 'headers',surfacing as a 500. Two ways to handle it, and I do not want to pick for you:
headers: dict[str, str] | None = None. Keeps the failure visible when theplumbing is wrong.
{}. When a wrapper opts in but no headers are available, hand it anempty dict. The contract becomes "declare it and you always get a dict", at
the cost of hiding a misconfiguration.
Happy to implement either.
Tests
tests/test_it_openai_headers.pydeploys two wrapper fixtures through the normalpath: one declaring
headersthat echoesAuthorizationback, and one keepingthe existing signature that must be called unchanged. The end-to-end checks skip
themselves when the installed compat predates forwarding, and activate
automatically once it ships.
_method_accepts_kwargand_build_call_kwargshaveunit tests covering explicit parameters,
**kwargs, wrappers that do not opt in,unintrospectable callables, and
headers=Nonefrom non-HTTP entry points.