codex-backend-sdk 0.3.8__tar.gz → 0.3.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/CHANGELOG.md +9 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/PKG-INFO +1 -1
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/__init__.py +1 -1
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/resources/openai_oauth.py +36 -1
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/pyproject.toml +1 -1
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/test_openai_oauth_resources.py +20 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/uv.lock +1 -1
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/.gitignore +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/LICENSE +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/README.md +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/_client.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/_models.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/_streaming.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/_transport.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/_utils.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/codex_client.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/oauth.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/pkce.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/resources/__init__.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/resources/_responses_payloads.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/resources/codex.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/resources/files.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/resources/models.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/resources/realtime.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/resources/responses.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/storage.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/docs/backend-api.md +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/examples/agent.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/conftest.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/test_account_info.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/test_basic.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/test_client_retry.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/test_codex_resources.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/test_conversation.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/test_files_resource.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/test_realtime_resource.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/test_reasoning.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/test_responses_resource.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/test_structured_output.py +0 -0
- {codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/tests/test_tools.py +0 -0
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.3.9] - 2026-07-17
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- Detect anonymous audio buffers by their file signature before ChatGPT transcription uploads, correcting filenames and MIME types when callers provide misleading generic names such as `audio.mp3` for WAV data.
|
|
9
|
+
- Restored reliable `AIClient.audio_to_text(bytes)` integration with `/backend-api/transcribe` without requiring callers to understand multipart backend constraints.
|
|
10
|
+
|
|
11
|
+
### Tests
|
|
12
|
+
- Added regression coverage for WAV buffers carrying an incorrect `.mp3` name and verified the complete Codex Agent transcription path against the real ChatGPT backend.
|
|
13
|
+
|
|
5
14
|
## [0.3.8] - 2026-07-17
|
|
6
15
|
|
|
7
16
|
### Changed
|
{codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/resources/openai_oauth.py
RENAMED
|
@@ -126,7 +126,7 @@ class AudioTranscriptions:
|
|
|
126
126
|
|
|
127
127
|
response = self._client._post_chatgpt_raw(
|
|
128
128
|
"/transcribe",
|
|
129
|
-
files={"file":
|
|
129
|
+
files={"file": _coerce_audio_file(file)},
|
|
130
130
|
data={key: _form_value(value) for key, value in data.items()},
|
|
131
131
|
headers=extra_headers,
|
|
132
132
|
params=extra_query,
|
|
@@ -136,3 +136,38 @@ class AudioTranscriptions:
|
|
|
136
136
|
if _is_given(response_format) and response_format == "text":
|
|
137
137
|
return transcription.text
|
|
138
138
|
return transcription
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _coerce_audio_file(file: Any) -> Any:
|
|
142
|
+
coerced = _coerce_file(file)
|
|
143
|
+
if isinstance(coerced, tuple):
|
|
144
|
+
return coerced
|
|
145
|
+
if not hasattr(coerced, "read"):
|
|
146
|
+
return coerced
|
|
147
|
+
|
|
148
|
+
position = coerced.tell() if hasattr(coerced, "tell") else None
|
|
149
|
+
header = coerced.read(12)
|
|
150
|
+
if position is not None and hasattr(coerced, "seek"):
|
|
151
|
+
coerced.seek(position)
|
|
152
|
+
|
|
153
|
+
detected = _audio_type(header)
|
|
154
|
+
if detected is None:
|
|
155
|
+
return coerced
|
|
156
|
+
extension, mime_type = detected
|
|
157
|
+
name = getattr(coerced, "name", "audio") or "audio"
|
|
158
|
+
stem = str(name).rsplit("/", 1)[-1].rsplit(".", 1)[0] or "audio"
|
|
159
|
+
return (f"{stem}.{extension}", coerced, mime_type)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _audio_type(header: bytes) -> tuple[str, str] | None:
|
|
163
|
+
if header.startswith(b"RIFF") and header[8:12] == b"WAVE":
|
|
164
|
+
return "wav", "audio/wav"
|
|
165
|
+
if header.startswith(b"ID3") or header[:2] in {b"\xff\xfb", b"\xff\xf3", b"\xff\xf2"}:
|
|
166
|
+
return "mp3", "audio/mpeg"
|
|
167
|
+
if header.startswith(b"OggS"):
|
|
168
|
+
return "ogg", "audio/ogg"
|
|
169
|
+
if header.startswith(b"fLaC"):
|
|
170
|
+
return "flac", "audio/flac"
|
|
171
|
+
if header[4:8] == b"ftyp":
|
|
172
|
+
return "m4a", "audio/mp4"
|
|
173
|
+
return None
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
|
|
1
3
|
import pytest
|
|
2
4
|
|
|
3
5
|
from codex_backend_sdk import CreateEmbeddingResponse, OpenAI, Transcription
|
|
@@ -92,6 +94,24 @@ def test_audio_transcriptions_create_posts_to_chatgpt_backend():
|
|
|
92
94
|
assert headers["ChatGPT-Account-ID"] == "account-id"
|
|
93
95
|
|
|
94
96
|
|
|
97
|
+
def test_audio_transcriptions_detects_anonymous_audio_format():
|
|
98
|
+
client = FakeOpenAIClient()
|
|
99
|
+
audio = BytesIO(b"RIFF\x00\x00\x00\x00WAVEfmt ")
|
|
100
|
+
audio.name = "audio.mp3"
|
|
101
|
+
|
|
102
|
+
client.audio.transcriptions.create(
|
|
103
|
+
model="gpt-4o-mini-transcribe",
|
|
104
|
+
file=audio,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
_, kwargs, _ = client.chatgpt_raw_posts[0]
|
|
108
|
+
filename, uploaded, mime_type = kwargs["files"]["file"]
|
|
109
|
+
assert filename == "audio.wav"
|
|
110
|
+
assert uploaded is audio
|
|
111
|
+
assert mime_type == "audio/wav"
|
|
112
|
+
assert audio.tell() == 0
|
|
113
|
+
|
|
114
|
+
|
|
95
115
|
def test_audio_transcriptions_text_format_returns_string():
|
|
96
116
|
client = FakeOpenAIClient()
|
|
97
117
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_backend_sdk-0.3.8 → codex_backend_sdk-0.3.9}/codex_backend_sdk/resources/responses.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|