[azure-ai-projects] ResponsesInstrumentor breaks openai with_raw_response streaming (AsyncStreamWrapper wraps an unparsed LegacyAPIResponse)
I maintainer di solito rispondono entro 1 giorno
@M-Hietala ci sta già lavorando.
Dal 20/8/2026.
Valutazione
Questa issue non è ancora stata valutata.
Descrizione
Describe the bug
With the Responses instrumentor active, client.responses.with_raw_response.create(..., stream=True) no longer returns a raw response. It returns AsyncStreamWrapper, which:
- does not expose
.parse()or.headers, both part of thewith_raw_responsecontract; and - cannot be iterated, because its
stream_async_iteris the still-unparsedLegacyAPIResponse, which has no__anext__.
So any caller that uses with_raw_response together with streaming breaks as soon as tracing is enabled, with:
AttributeError: 'LegacyAPIResponse' object has no attribute '__anext__'
with_raw_response is the only way to read response headers (e.g. x-ms-served-model) while streaming, so this affects callers that need per-response header data.
Root cause
The instrumentor patches openai.resources.responses.AsyncResponses.create. with_raw_response.create() delegates to that same method, but sets the SDK's raw-response flag, so create returns a LegacyAPIResponse rather than an AsyncStream.
_wrap_async_streaming_response treats whatever create returned as the event stream and stores it as stream_async_iter, and AsyncStreamWrapper.__anext__ calls self.stream_async_iter.__anext__(). For the raw-response path that object is a LegacyAPIResponse, which is not an async iterator — it must have .parse() called on it first.
Verified with a debug hook on _wrap_async_streaming_response:
[wrap] _wrap_async_streaming_response receives stream=openai._legacy_response.LegacyAPIResponse
To Reproduce
Standalone: openai + azure-ai-projects only, no Azure resources needed (the transport is mocked, so the object graph is wrong before any real network call matters).
import asyncio
import httpx
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from azure.core.settings import settings
from azure.core.tracing.ext.opentelemetry_span import OpenTelemetrySpan
from azure.ai.projects.telemetry._responses_instrumentor import ResponsesInstrumentor
from openai import AsyncOpenAI
trace.set_tracer_provider(TracerProvider())
settings.tracing_implementation = OpenTelemetrySpan
SSE = (
'data: {"type":"response.output_text.delta","delta":"Hello","item_id":"m1",'
'"output_index":0,"content_index":0,"sequence_number":1,"logprobs":[]}\n\n'
"data: [DONE]\n\n"
)
transport = httpx.MockTransport(
lambda r: httpx.Response(200, headers={"content-type": "text/event-stream"}, content=SSE.encode())
)
async def main() -> None:
ResponsesInstrumentor().instrument()
client = AsyncOpenAI(api_key="k", http_client=httpx.AsyncClient(transport=transport))
raw = await client.responses.with_raw_response.create(model="gpt-4o", input="hi", stream=True)
print(f"returned type : {type(raw).__module__}.{type(raw).__name__}")
print(f" .parse() : {hasattr(raw, 'parse')}")
print(f" .headers : {hasattr(raw, 'headers')}")
inner = getattr(raw, "stream_async_iter", None)
print(f" .stream_async_iter: {type(inner).__module__}.{type(inner).__name__}")
print(f" __anext__ : {hasattr(inner, '__anext__')}")
async for _ in raw:
pass
asyncio.run(main())
Note both an OpenTelemetry TracerProvider and azure-core-tracing-opentelemetry are required — without them _create_responses_span_from_parameters returns None, the instrumentor returns the result unwrapped, and the bug does not appear. That makes it easy to miss when reproducing.
Expected behavior
with_raw_response.create(..., stream=True) should keep behaving like a raw response when tracing is on: .parse() and .headers available, and the parsed stream iterable — ideally with the wrapper still in the iteration path so telemetry is still recorded.
Actual behavior
returned type : azure.ai.projects.telemetry._responses_instrumentor.AsyncStreamWrapper
.parse() : False <- raw-response API expects True
.headers : False <- raw-response API expects True
.stream_async_iter: openai._legacy_response.LegacyAPIResponse
__anext__ : False <- wrapper iterates this
iterating the returned object:
AttributeError: 'LegacyAPIResponse' object has no attribute '__anext__'
With the instrumentor uninstrumented, the same call correctly returns:
openai._legacy_response.LegacyAPIResponse .parse()=True .headers=True
Environment
azure-ai-projects==2.3.0openai==2.53.0azure-core-tracing-opentelemetry==1.0.0b13,opentelemetry-sdk==1.44.0- Python 3.13, macOS (not platform specific)
Notes
Reported downstream as microsoft/agent-framework#7461, where enabling AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING=true made all streaming agent requests fail. microsoft/agent-framework#7705 works around it by parsing the wrapper's inner raw response and handing it back, so the wrapper stays in the iteration path and telemetry is preserved. That workaround could be dropped once this is fixed upstream.
- Lingua principale
- Python
- Stelle
- 5.6k
- Fork
- 3.4k
- Merge medio
- 2g 1m
- PR unite (30g)
- 218
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Azure/azure-sdk-for-python
-
Evaluation Service Attention
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
Azure/azure-sdk-for-python#49190 · 1 commento · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Update CODEOWNERSAperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
Azure/azure-sdk-for-python#49183 · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Evaluation Service Attention
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
Azure/azure-sdk-for-python#49153 · 1 commento · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Search Service Attention
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
Azure/azure-sdk-for-python#48555 · 1 commento · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Azure.Core customer-reported feature-request needs-team-attention
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
Azure/azure-sdk-for-python#47186 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di Azure/azure-sdk-for-python
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
kornia/kornia#5263 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
approved correction metadata
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
acl-org/acl-anthology#10133 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
BasedHardware/omi#20084 ·
I maintainer di solito rispondono entro 1 giorno
-
bug needs-acceptance wg/evaluation-quality
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
vllm-project/semantic-router#4424 ·
I maintainer di solito rispondono entro 1 giorno