Skip to content

Commit c076f0e

Browse files
authored
feat(openai): trace streaming audio transcriptions (#375)
Support audio.transcriptions.create(stream=True) for sync and async OpenAI clients, including deterministic span finalization on stream exhaustion, context exit, and early close. resolves #374
1 parent 8acc31c commit c076f0e

34 files changed

Lines changed: 17554 additions & 8 deletions

File tree

py/src/braintrust/integrations/openai/cassettes/1.71.0/test_openai_audio_transcription_streaming.yaml

Lines changed: 664 additions & 0 deletions
Large diffs are not rendered by default.

py/src/braintrust/integrations/openai/cassettes/1.71.0/test_openai_audio_transcription_streaming_async.yaml

Lines changed: 665 additions & 0 deletions
Large diffs are not rendered by default.

py/src/braintrust/integrations/openai/cassettes/1.71.0/test_openai_audio_transcription_streaming_early_close.yaml

Lines changed: 665 additions & 0 deletions
Large diffs are not rendered by default.

py/src/braintrust/integrations/openai/cassettes/1.71.0/test_openai_audio_transcription_streaming_early_close_async.yaml

Lines changed: 666 additions & 0 deletions
Large diffs are not rendered by default.

py/src/braintrust/integrations/openai/cassettes/1.71.0/test_openai_audio_transcription_streaming_no_events_omits_output.yaml

Lines changed: 665 additions & 0 deletions
Large diffs are not rendered by default.

py/src/braintrust/integrations/openai/cassettes/1.71.0/test_openai_audio_transcription_streaming_no_events_omits_output_async.yaml

Lines changed: 666 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
interactions:
2+
- request:
3+
body: '{"messages":[{"role":"user","content":"What''s 12 + 12?"}],"model":"gpt-4o-mini","stream":true,"stream_options":{"include_usage":true}}'
4+
headers:
5+
Accept:
6+
- application/json
7+
Accept-Encoding:
8+
- gzip, deflate
9+
Connection:
10+
- keep-alive
11+
Content-Length:
12+
- '134'
13+
Content-Type:
14+
- application/json
15+
Host:
16+
- api.openai.com
17+
User-Agent:
18+
- AsyncOpenAI/Python 1.71.0
19+
X-Stainless-Arch:
20+
- arm64
21+
X-Stainless-Async:
22+
- async:asyncio
23+
X-Stainless-Lang:
24+
- python
25+
X-Stainless-OS:
26+
- MacOS
27+
X-Stainless-Package-Version:
28+
- 1.71.0
29+
X-Stainless-Runtime:
30+
- CPython
31+
X-Stainless-Runtime-Version:
32+
- 3.12.12
33+
x-stainless-read-timeout:
34+
- '600'
35+
x-stainless-retry-count:
36+
- '0'
37+
method: POST
38+
uri: https://api.openai.com/v1/chat/completions
39+
response:
40+
body:
41+
string: 'data: {"id":"chatcmpl-DaP4BlJRnktlJFzFEEYJb2nNYcWPV","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"SoMNn0qtL"}
42+
43+
44+
data: {"id":"chatcmpl-DaP4BlJRnktlJFzFEEYJb2nNYcWPV","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"12"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"HL9PmhRzp"}
45+
46+
47+
data: {"id":"chatcmpl-DaP4BlJRnktlJFzFEEYJb2nNYcWPV","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"
48+
+"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"bY5MbYvK5"}
49+
50+
51+
data: {"id":"chatcmpl-DaP4BlJRnktlJFzFEEYJb2nNYcWPV","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"
52+
"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"zb8EvnUTmj"}
53+
54+
55+
data: {"id":"chatcmpl-DaP4BlJRnktlJFzFEEYJb2nNYcWPV","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"12"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"YFZfWvRg8"}
56+
57+
58+
data: {"id":"chatcmpl-DaP4BlJRnktlJFzFEEYJb2nNYcWPV","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"
59+
equals"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"UmE1"}
60+
61+
62+
data: {"id":"chatcmpl-DaP4BlJRnktlJFzFEEYJb2nNYcWPV","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"
63+
"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"728KlmxLT6"}
64+
65+
66+
data: {"id":"chatcmpl-DaP4BlJRnktlJFzFEEYJb2nNYcWPV","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"24"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ZM3k56oOf"}
67+
68+
69+
data: {"id":"chatcmpl-DaP4BlJRnktlJFzFEEYJb2nNYcWPV","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"qFjVldMwIa"}
70+
71+
72+
data: {"id":"chatcmpl-DaP4BlJRnktlJFzFEEYJb2nNYcWPV","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"Nn6dj"}
73+
74+
75+
data: {"id":"chatcmpl-DaP4BlJRnktlJFzFEEYJb2nNYcWPV","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[],"usage":{"prompt_tokens":14,"completion_tokens":8,"total_tokens":22,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"mRxnidqNcAS"}
76+
77+
78+
data: [DONE]
79+
80+
81+
'
82+
headers:
83+
CF-Cache-Status:
84+
- DYNAMIC
85+
CF-Ray:
86+
- 9f481cf30e5dde04-YYZ
87+
Connection:
88+
- keep-alive
89+
Content-Type:
90+
- text/event-stream; charset=utf-8
91+
Date:
92+
- Thu, 30 Apr 2026 17:02:15 GMT
93+
Server:
94+
- cloudflare
95+
Strict-Transport-Security:
96+
- max-age=31536000; includeSubDomains; preload
97+
Transfer-Encoding:
98+
- chunked
99+
X-Content-Type-Options:
100+
- nosniff
101+
access-control-expose-headers:
102+
- X-Request-ID
103+
alt-svc:
104+
- h3=":443"; ma=86400
105+
openai-organization:
106+
- braintrust-data
107+
openai-processing-ms:
108+
- '221'
109+
openai-project:
110+
- proj_vsCSXafhhByzWOThMrJcZiw9
111+
openai-version:
112+
- '2020-10-01'
113+
set-cookie:
114+
- __cf_bm=pbIVY7zpuu4wuat1a8K4xMN0v4LTa1FUrzZBtGY0rro-1777568535.524229-1.0.1.1-Q.K3UO0y2ej0n5kWggGo4.2bH2PpDBbwjrJ9vvGudNQqpMrSTI.MTyfu6AO5PFHW8FqUYUW7Bt_ZmM5GIguKbYcj9Pe.L91rElwJArLRTISYGCkR.6l2MrnvT.SK56W8;
115+
HttpOnly; Secure; Path=/; Domain=api.openai.com; Expires=Thu, 30 Apr 2026
116+
17:32:15 GMT
117+
x-openai-proxy-wasm:
118+
- v0.1
119+
x-ratelimit-limit-requests:
120+
- '30000'
121+
x-ratelimit-limit-tokens:
122+
- '150000000'
123+
x-ratelimit-remaining-requests:
124+
- '29999'
125+
x-ratelimit-remaining-tokens:
126+
- '149999995'
127+
x-ratelimit-reset-requests:
128+
- 2ms
129+
x-ratelimit-reset-tokens:
130+
- 0s
131+
x-request-id:
132+
- req_5b860fae164e47f48fb430e5aa986f53
133+
status:
134+
code: 200
135+
message: OK
136+
version: 1
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
interactions:
2+
- request:
3+
body: '{"messages":[{"role":"user","content":"What''s 12 + 12?"}],"model":"gpt-4o-mini","stream":true,"stream_options":{"include_usage":true}}'
4+
headers:
5+
Accept:
6+
- application/json
7+
Accept-Encoding:
8+
- gzip, deflate
9+
Connection:
10+
- keep-alive
11+
Content-Length:
12+
- '134'
13+
Content-Type:
14+
- application/json
15+
Host:
16+
- api.openai.com
17+
User-Agent:
18+
- OpenAI/Python 1.71.0
19+
X-Stainless-Arch:
20+
- arm64
21+
X-Stainless-Async:
22+
- 'false'
23+
X-Stainless-Lang:
24+
- python
25+
X-Stainless-OS:
26+
- MacOS
27+
X-Stainless-Package-Version:
28+
- 1.71.0
29+
X-Stainless-Runtime:
30+
- CPython
31+
X-Stainless-Runtime-Version:
32+
- 3.12.12
33+
x-stainless-read-timeout:
34+
- '600'
35+
x-stainless-retry-count:
36+
- '0'
37+
method: POST
38+
uri: https://api.openai.com/v1/chat/completions
39+
response:
40+
body:
41+
string: 'data: {"id":"chatcmpl-DaP4BexOuEy3PsdzcytN7lZVhuLhX","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"MXTEJgpAt"}
42+
43+
44+
data: {"id":"chatcmpl-DaP4BexOuEy3PsdzcytN7lZVhuLhX","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"12"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"E6YMmttWd"}
45+
46+
47+
data: {"id":"chatcmpl-DaP4BexOuEy3PsdzcytN7lZVhuLhX","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"
48+
+"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"gVJOHdk7V"}
49+
50+
51+
data: {"id":"chatcmpl-DaP4BexOuEy3PsdzcytN7lZVhuLhX","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"
52+
"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"ZxtQBRLy5l"}
53+
54+
55+
data: {"id":"chatcmpl-DaP4BexOuEy3PsdzcytN7lZVhuLhX","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"12"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"VJtbizw5g"}
56+
57+
58+
data: {"id":"chatcmpl-DaP4BexOuEy3PsdzcytN7lZVhuLhX","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"
59+
equals"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"YPvm"}
60+
61+
62+
data: {"id":"chatcmpl-DaP4BexOuEy3PsdzcytN7lZVhuLhX","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"
63+
"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"FjLjLjM2vI"}
64+
65+
66+
data: {"id":"chatcmpl-DaP4BexOuEy3PsdzcytN7lZVhuLhX","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"24"},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"I1lV4r1AW"}
67+
68+
69+
data: {"id":"chatcmpl-DaP4BexOuEy3PsdzcytN7lZVhuLhX","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null,"obfuscation":"fdqg23wFT0"}
70+
71+
72+
data: {"id":"chatcmpl-DaP4BexOuEy3PsdzcytN7lZVhuLhX","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null,"obfuscation":"KPjJE"}
73+
74+
75+
data: {"id":"chatcmpl-DaP4BexOuEy3PsdzcytN7lZVhuLhX","object":"chat.completion.chunk","created":1777568535,"model":"gpt-4o-mini-2024-07-18","service_tier":"default","system_fingerprint":"fp_576e90e2be","choices":[],"usage":{"prompt_tokens":14,"completion_tokens":8,"total_tokens":22,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}},"obfuscation":"Lhks1zTmXQ7"}
76+
77+
78+
data: [DONE]
79+
80+
81+
'
82+
headers:
83+
CF-Cache-Status:
84+
- DYNAMIC
85+
CF-Ray:
86+
- 9f481ceefbc01a24-YYZ
87+
Connection:
88+
- keep-alive
89+
Content-Type:
90+
- text/event-stream; charset=utf-8
91+
Date:
92+
- Thu, 30 Apr 2026 17:02:15 GMT
93+
Server:
94+
- cloudflare
95+
Strict-Transport-Security:
96+
- max-age=31536000; includeSubDomains; preload
97+
Transfer-Encoding:
98+
- chunked
99+
X-Content-Type-Options:
100+
- nosniff
101+
access-control-expose-headers:
102+
- X-Request-ID
103+
alt-svc:
104+
- h3=":443"; ma=86400
105+
openai-organization:
106+
- braintrust-data
107+
openai-processing-ms:
108+
- '271'
109+
openai-project:
110+
- proj_vsCSXafhhByzWOThMrJcZiw9
111+
openai-version:
112+
- '2020-10-01'
113+
set-cookie:
114+
- __cf_bm=SogDOJ7lvQulQpTVUjtFw6ORT.pL6P6J2TyRITOyZnY-1777568534.8733747-1.0.1.1-_d2vjcV7UT.5KQCkbfITFNSGRgNNxmzaNI6l9TC9E3zLG_MXEK05BeZfEnWltucUrvEIRVBeq7z2pr3dIgrTpYVywLHKEuiA.JU5eoRhx06oo.3_Dvjzwzh2zjhJXzqo;
115+
HttpOnly; Secure; Path=/; Domain=api.openai.com; Expires=Thu, 30 Apr 2026
116+
17:32:15 GMT
117+
x-openai-proxy-wasm:
118+
- v0.1
119+
x-ratelimit-limit-requests:
120+
- '30000'
121+
x-ratelimit-limit-tokens:
122+
- '150000000'
123+
x-ratelimit-remaining-requests:
124+
- '29999'
125+
x-ratelimit-remaining-tokens:
126+
- '149999995'
127+
x-ratelimit-reset-requests:
128+
- 2ms
129+
x-ratelimit-reset-tokens:
130+
- 0s
131+
x-request-id:
132+
- req_ded4228fd0564a5b897162b8bd2e1f90
133+
status:
134+
code: 200
135+
message: OK
136+
version: 1

0 commit comments

Comments
 (0)