-
Notifications
You must be signed in to change notification settings - Fork 167
Fix: Add with_raw_response support to OpenAI & Anthropic wrapper #2134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| elif hasattr(outputs, "parse") and callable(outputs.parse): | ||
| # Some versions use .parse() method | ||
| try: | ||
| outputs = outputs.parse() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit unclear, what versions use .parse()? Older OpenAI SDK versions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added better comments but comes from here: github.com/openai/openai-python/blob/main/src/openai/_response.py#L285
|
|
||
| # Wrap with_raw_response.create for chat completions | ||
| if hasattr(client.chat.completions, "with_raw_response"): | ||
| client.chat.completions.with_raw_response.create = _get_wrapper( # type: ignore[method-assign] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to wrap .parse here too? And what about the responses API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so, will remove now!
| # See: anthropics/anthropic-sdk-python _legacy_response.py#L102 | ||
| if hasattr(outputs, "parse") and callable(outputs.parse): | ||
| try: | ||
| outputs = outputs.parse() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I thought of here - I think most often when people use .with_raw_response it's because they want to defer this later for some reason
Won't this consume the body?
Add
with_raw_responsesupport to OpenAI and Anthropic wrappersProblem
When using the
with_raw_responseAPI to access HTTP headers in OpenAI and Anthropic clients, the LangSmith wrappers were logging the raw response wrapper objects instead of the parsed response data. This prevented users from accessing HTTP headers (like rate limits, request IDs) while maintaining proper observability.Example of the issue:
Root Cause
The wrappers only wrapped the standard
.create()methods, not the.with_raw_response.create()methods. Whenwith_raw_responseis used, the SDKs return a wrapper object (APIResponsefor OpenAI,LegacyAPIResponsefor Anthropic) that needs to be parsed to extract the actual response data.Solution
Added parsing logic to detect and unwrap response wrapper objects:
APIResponse.parse()to extract theChatCompletion/CompletionLegacyAPIResponse.parse()to extract theMessageWrapped
with_raw_response.createmethods:client.chat.completions.with_raw_response.create(OpenAI)client.completions.with_raw_response.create(OpenAI)client.messages.with_raw_response.create(Anthropic)Updated docstrings with
with_raw_responseexamplesChanges
OpenAI Wrapper (
langsmith/wrappers/_openai.py)Wrapped methods:
client.chat.completions.with_raw_response.createclient.completions.with_raw_response.createAnthropic Wrapper (
langsmith/wrappers/_anthropic.py)Wrapped methods:
client.messages.with_raw_response.createTesting
New Integration Tests
tests/integration_tests/wrappers/test_with_raw_response.py- OpenAI teststests/integration_tests/wrappers/test_anthropic_with_raw_response.py- Anthropic testsBoth test suites verify:
raw_response.headersraw_response.parse()Test Results
Usage Example
OpenAI
Anthropic
Design Decisions
Minimalism: Only wrapped the primary
.create()methods withwith_raw_response. Did not wrap:.parse()methods (Structured Outputs - different feature)This keeps the changes focused on the reported issue without over-engineering.
References
APIResponse.parse(): https://github.com/openai/openai-python/blob/main/src/openai/_response.py#L285-L331LegacyAPIResponse.parse(): https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_legacy_response.py#L102-L176with_raw_responsedocs: https://github.com/openai/openai-python#accessing-raw-response-data-eg-headerswith_raw_responsedocs: https://github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headersBreaking Changes
None. This is a backward-compatible enhancement that adds support for a previously unsupported API pattern.
Checklist
make format,make lint,make tests)