codex-backend-sdk 0.3.7__tar.gz → 0.3.8__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.7 → codex_backend_sdk-0.3.8}/CHANGELOG.md +13 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/PKG-INFO +3 -3
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/README.md +2 -2
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/__init__.py +1 -1
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/_client.py +21 -2
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/resources/openai_oauth.py +41 -29
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/docs/backend-api.md +15 -7
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/pyproject.toml +1 -1
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/test_openai_oauth_resources.py +40 -6
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/uv.lock +1 -1
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/.gitignore +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/LICENSE +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/_models.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/_streaming.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/_transport.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/_utils.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/codex_client.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/oauth.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/pkce.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/resources/__init__.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/resources/_responses_payloads.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/resources/codex.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/resources/files.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/resources/models.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/resources/realtime.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/resources/responses.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/storage.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/examples/agent.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/conftest.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/test_account_info.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/test_basic.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/test_client_retry.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/test_codex_resources.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/test_conversation.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/test_files_resource.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/test_realtime_resource.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/test_reasoning.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/test_responses_resource.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/test_structured_output.py +0 -0
- {codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/tests/test_tools.py +0 -0
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.3.8] - 2026-07-17
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- Routed `client.audio.transcriptions.create(...)` through the ChatGPT-native `/backend-api/transcribe` endpoint instead of the billable Platform `/v1/audio/transcriptions` endpoint.
|
|
9
|
+
- Preserved the OpenAI-shaped `json` and `text` response behavior used by Codex Agent while rejecting unsupported streaming, timestamp, speaker, chunking, SRT, and VTT options explicitly.
|
|
10
|
+
- Added a reusable raw ChatGPT multipart request helper to the client transport.
|
|
11
|
+
|
|
12
|
+
### Documentation
|
|
13
|
+
- Clarified that embeddings still use the OpenAI Platform endpoint and its developer-account quota, while batch transcription now uses the authenticated ChatGPT backend.
|
|
14
|
+
|
|
15
|
+
### Tests
|
|
16
|
+
- Added coverage for ChatGPT transcription routing, account authentication headers, text responses, and unsupported parameters.
|
|
17
|
+
|
|
5
18
|
## [0.3.7] - 2026-07-17
|
|
6
19
|
|
|
7
20
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-backend-sdk
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.8
|
|
4
4
|
Summary: Unofficial Python SDK for the ChatGPT Codex backend API
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -188,8 +188,8 @@ resources (`responses`, `models`, `realtime`) or Codex-only resources (`codex`).
|
|
|
188
188
|
| `GET /backend-api/codex/models` | `client.models.list()` / `client.models.retrieve(...)` | OpenAI-shaped model objects with Codex metadata preserved as extra fields. |
|
|
189
189
|
| `POST /backend-api/codex/realtime/calls` | `client.realtime.calls.create(...)` | Experimental SDP call creation. The protocol is implemented by Codex, but ChatGPT routing is rollout-dependent and may return `404 Not Found`. |
|
|
190
190
|
| `wss://api.openai.com/v1/realtime?model=...` | `client.realtime_websocket_url(...)` / `client.realtime.websocket_headers(...)` | Voice v2 helpers; requires a Realtime API key obtained during OAuth or supplied by the auth store. |
|
|
191
|
-
| `POST /v1/embeddings` | `client.embeddings.create(...)` | Uses the Codex OAuth access token against `api.openai.com`;
|
|
192
|
-
| `POST /
|
|
191
|
+
| `POST /v1/embeddings` | `client.embeddings.create(...)` | Uses the Codex OAuth access token against `api.openai.com`; usage is charged to the associated OpenAI Platform organization. |
|
|
192
|
+
| `POST /backend-api/transcribe` | `client.audio.transcriptions.create(...)` | Uses the authenticated ChatGPT backend for non-streaming batch transcription; no developer API key is required. |
|
|
193
193
|
| `GET /backend-api/wham/usage` | `client.codex.usage()` | Codex/ChatGPT quota and rate-limit status. |
|
|
194
194
|
| `GET /backend-api/wham/config/requirements` | `client.codex.config.requirements()` | Raw managed requirements/config payload for the authenticated account. |
|
|
195
195
|
| `GET /backend-api/wham/tasks/list` | `client.codex.tasks.list(...)` | Raw Codex cloud task listing. |
|
|
@@ -162,8 +162,8 @@ resources (`responses`, `models`, `realtime`) or Codex-only resources (`codex`).
|
|
|
162
162
|
| `GET /backend-api/codex/models` | `client.models.list()` / `client.models.retrieve(...)` | OpenAI-shaped model objects with Codex metadata preserved as extra fields. |
|
|
163
163
|
| `POST /backend-api/codex/realtime/calls` | `client.realtime.calls.create(...)` | Experimental SDP call creation. The protocol is implemented by Codex, but ChatGPT routing is rollout-dependent and may return `404 Not Found`. |
|
|
164
164
|
| `wss://api.openai.com/v1/realtime?model=...` | `client.realtime_websocket_url(...)` / `client.realtime.websocket_headers(...)` | Voice v2 helpers; requires a Realtime API key obtained during OAuth or supplied by the auth store. |
|
|
165
|
-
| `POST /v1/embeddings` | `client.embeddings.create(...)` | Uses the Codex OAuth access token against `api.openai.com`;
|
|
166
|
-
| `POST /
|
|
165
|
+
| `POST /v1/embeddings` | `client.embeddings.create(...)` | Uses the Codex OAuth access token against `api.openai.com`; usage is charged to the associated OpenAI Platform organization. |
|
|
166
|
+
| `POST /backend-api/transcribe` | `client.audio.transcriptions.create(...)` | Uses the authenticated ChatGPT backend for non-streaming batch transcription; no developer API key is required. |
|
|
167
167
|
| `GET /backend-api/wham/usage` | `client.codex.usage()` | Codex/ChatGPT quota and rate-limit status. |
|
|
168
168
|
| `GET /backend-api/wham/config/requirements` | `client.codex.config.requirements()` | Raw managed requirements/config payload for the authenticated account. |
|
|
169
169
|
| `GET /backend-api/wham/tasks/list` | `client.codex.tasks.list(...)` | Raw Codex cloud task listing. |
|
|
@@ -295,14 +295,33 @@ class CodexClient:
|
|
|
295
295
|
body: dict[str, Any],
|
|
296
296
|
timeout: Any = _UNSET,
|
|
297
297
|
) -> dict[str, Any]:
|
|
298
|
+
response = self._post_chatgpt_raw(path, body=body, timeout=timeout)
|
|
299
|
+
return response.json()
|
|
300
|
+
|
|
301
|
+
def _post_chatgpt_raw(
|
|
302
|
+
self,
|
|
303
|
+
path: str,
|
|
304
|
+
*,
|
|
305
|
+
body: Optional[dict[str, Any]] = None,
|
|
306
|
+
files: Any = None,
|
|
307
|
+
data: Any = None,
|
|
308
|
+
headers: Optional[dict[str, str]] = None,
|
|
309
|
+
params: Optional[dict[str, Any]] = None,
|
|
310
|
+
timeout: Any = _UNSET,
|
|
311
|
+
) -> requests.Response:
|
|
298
312
|
self._ensure_auth()
|
|
299
313
|
response = self._request_with_retries(
|
|
300
314
|
"POST",
|
|
301
315
|
f"{CHATGPT_BASE_URL}{path}",
|
|
302
|
-
json=body,
|
|
316
|
+
json=body if files is None and data is None else None,
|
|
317
|
+
files=files,
|
|
318
|
+
data=data,
|
|
319
|
+
headers=headers,
|
|
320
|
+
params=params,
|
|
303
321
|
timeout=self._timeout if not _is_given(timeout) else timeout,
|
|
304
322
|
)
|
|
305
|
-
|
|
323
|
+
response.raise_for_status()
|
|
324
|
+
return response
|
|
306
325
|
|
|
307
326
|
def _request_with_retries(self, method: str, url: str, **kwargs: Any) -> requests.Response:
|
|
308
327
|
use_session = kwargs.pop("_use_session", True)
|
{codex_backend_sdk-0.3.7 → codex_backend_sdk-0.3.8}/codex_backend_sdk/resources/openai_oauth.py
RENAMED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
"""OpenAI
|
|
1
|
+
"""OpenAI-shaped resources authenticated through the Codex ChatGPT session."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from collections.abc import Iterator
|
|
6
5
|
from typing import Any, Optional, TYPE_CHECKING
|
|
7
6
|
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
from .._models import CreateEmbeddingResponse, Transcription
|
|
8
|
+
from .._utils import (
|
|
9
|
+
_UNSET,
|
|
10
|
+
CodexBackendUnsupportedParameterError,
|
|
11
|
+
_add_given,
|
|
12
|
+
_coerce_file,
|
|
13
|
+
_form_value,
|
|
14
|
+
_is_given,
|
|
15
|
+
_jsonable,
|
|
16
|
+
)
|
|
13
17
|
|
|
14
18
|
if TYPE_CHECKING:
|
|
15
19
|
from .._client import CodexClient
|
|
@@ -85,42 +89,50 @@ class AudioTranscriptions:
|
|
|
85
89
|
extra_query: Optional[dict[str, Any]] = None,
|
|
86
90
|
extra_body: Any = None,
|
|
87
91
|
timeout: Any = _UNSET,
|
|
88
|
-
) -> str | Transcription
|
|
92
|
+
) -> str | Transcription:
|
|
89
93
|
if not model:
|
|
90
94
|
raise ValueError(f"Expected a non-empty value for `model` but received {model!r}")
|
|
91
95
|
|
|
96
|
+
if _is_given(response_format) and response_format not in {None, "json", "text"}:
|
|
97
|
+
raise CodexBackendUnsupportedParameterError(
|
|
98
|
+
"The ChatGPT transcription backend supports only `json` and `text` response formats."
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
unsupported = {
|
|
102
|
+
"chunking_strategy": chunking_strategy,
|
|
103
|
+
"include": include,
|
|
104
|
+
"known_speaker_names": known_speaker_names,
|
|
105
|
+
"known_speaker_references": known_speaker_references,
|
|
106
|
+
"stream": stream,
|
|
107
|
+
"timestamp_granularities": timestamp_granularities,
|
|
108
|
+
}
|
|
109
|
+
given_unsupported = [
|
|
110
|
+
name for name, value in unsupported.items()
|
|
111
|
+
if _is_given(value) and value not in {None, False}
|
|
112
|
+
]
|
|
113
|
+
if given_unsupported:
|
|
114
|
+
raise CodexBackendUnsupportedParameterError(
|
|
115
|
+
"The ChatGPT transcription backend does not support: "
|
|
116
|
+
+ ", ".join(sorted(given_unsupported))
|
|
117
|
+
)
|
|
118
|
+
|
|
92
119
|
data = {"model": model}
|
|
93
|
-
_add_given(data, "chunking_strategy", chunking_strategy)
|
|
94
|
-
_add_given(data, "include", include)
|
|
95
|
-
_add_given(data, "known_speaker_names", known_speaker_names)
|
|
96
|
-
_add_given(data, "known_speaker_references", known_speaker_references)
|
|
97
120
|
_add_given(data, "language", language)
|
|
98
121
|
_add_given(data, "prompt", prompt)
|
|
99
122
|
_add_given(data, "response_format", response_format)
|
|
100
|
-
_add_given(data, "stream", stream)
|
|
101
123
|
_add_given(data, "temperature", temperature)
|
|
102
|
-
_add_given(data, "timestamp_granularities", timestamp_granularities)
|
|
103
124
|
if extra_body:
|
|
104
125
|
data.update(_jsonable(extra_body))
|
|
105
126
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
"/audio/transcriptions",
|
|
127
|
+
response = self._client._post_chatgpt_raw(
|
|
128
|
+
"/transcribe",
|
|
109
129
|
files={"file": _coerce_file(file)},
|
|
110
130
|
data={key: _form_value(value) for key, value in data.items()},
|
|
111
131
|
headers=extra_headers,
|
|
112
132
|
params=extra_query,
|
|
113
133
|
timeout=timeout,
|
|
114
|
-
stream=stream_enabled,
|
|
115
134
|
)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return Transcription.model_validate(response.json())
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def _wants_text_response(response_format: Any, response: requests.Response) -> bool:
|
|
124
|
-
if _is_given(response_format) and response_format in {"text", "srt", "vtt"}:
|
|
125
|
-
return True
|
|
126
|
-
return "json" not in response.headers.get("content-type", "")
|
|
135
|
+
transcription = Transcription.model_validate(response.json())
|
|
136
|
+
if _is_given(response_format) and response_format == "text":
|
|
137
|
+
return transcription.text
|
|
138
|
+
return transcription
|
|
@@ -306,11 +306,12 @@ continues to work but Voice v2 requires a separately provisioned API key.
|
|
|
306
306
|
|
|
307
307
|
---
|
|
308
308
|
|
|
309
|
-
##
|
|
309
|
+
## Embeddings and Transcription
|
|
310
310
|
|
|
311
|
-
These
|
|
312
|
-
|
|
313
|
-
|
|
311
|
+
These OpenAI-shaped resources deliberately use different upstreams. Embeddings
|
|
312
|
+
remain an OpenAI Platform call and consume the associated developer-account
|
|
313
|
+
quota. Batch transcription uses the authenticated ChatGPT backend and does not
|
|
314
|
+
require a developer API key.
|
|
314
315
|
|
|
315
316
|
### `POST /v1/embeddings`
|
|
316
317
|
|
|
@@ -328,13 +329,20 @@ but they work with the same Codex OAuth access token stored in
|
|
|
328
329
|
|
|
329
330
|
The response matches the official embeddings shape:
|
|
330
331
|
`{ "object": "list", "data": [{ "object": "embedding", ... }], "usage": ... }`.
|
|
332
|
+
The request is accounted against the OpenAI Platform organization returned by
|
|
333
|
+
the API; ChatGPT OAuth authenticates it but does not include it in a ChatGPT
|
|
334
|
+
subscription.
|
|
331
335
|
|
|
332
|
-
### `POST /
|
|
336
|
+
### `POST /backend-api/transcribe`
|
|
333
337
|
|
|
334
338
|
**SDK method**: `client.audio.transcriptions.create(...)`
|
|
335
339
|
|
|
336
|
-
**Status**: Supported for non-streaming
|
|
337
|
-
|
|
340
|
+
**Status**: Supported for non-streaming ChatGPT batch transcription. The SDK
|
|
341
|
+
uploads multipart audio with the OAuth bearer and `ChatGPT-Account-ID`, and
|
|
342
|
+
supports the `model`, `language`, `prompt`, `temperature`, and `json`/`text`
|
|
343
|
+
response options used by Codex Agent. Streaming, timestamps, speaker references,
|
|
344
|
+
chunking, SRT, and VTT are rejected locally rather than falling back to a
|
|
345
|
+
billable Platform endpoint.
|
|
338
346
|
|
|
339
347
|
### `POST /v1/audio/speech`
|
|
340
348
|
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
1
3
|
from codex_backend_sdk import CreateEmbeddingResponse, OpenAI, Transcription
|
|
4
|
+
from codex_backend_sdk._utils import CodexBackendUnsupportedParameterError
|
|
2
5
|
from codex_backend_sdk.storage import TokenStore
|
|
3
6
|
|
|
4
7
|
|
|
@@ -20,7 +23,7 @@ class FakeOpenAIClient(OpenAI):
|
|
|
20
23
|
def __init__(self):
|
|
21
24
|
super().__init__(model="gpt-test")
|
|
22
25
|
self.openai_posts = []
|
|
23
|
-
self.
|
|
26
|
+
self.chatgpt_raw_posts = []
|
|
24
27
|
self._set_store(TokenStore(
|
|
25
28
|
access_token="chatgpt-token",
|
|
26
29
|
refresh_token="refresh-token",
|
|
@@ -37,8 +40,8 @@ class FakeOpenAIClient(OpenAI):
|
|
|
37
40
|
"usage": {"prompt_tokens": 1, "total_tokens": 1},
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
def
|
|
41
|
-
self.
|
|
43
|
+
def _post_chatgpt_raw(self, path, **kwargs):
|
|
44
|
+
self.chatgpt_raw_posts.append((path, kwargs, self._auth_headers()))
|
|
42
45
|
return FakeJSONResponse()
|
|
43
46
|
|
|
44
47
|
|
|
@@ -65,7 +68,7 @@ def test_embeddings_create_posts_to_openai_with_codex_oauth_token():
|
|
|
65
68
|
assert headers["Authorization"] == "Bearer chatgpt-token"
|
|
66
69
|
|
|
67
70
|
|
|
68
|
-
def
|
|
71
|
+
def test_audio_transcriptions_create_posts_to_chatgpt_backend():
|
|
69
72
|
client = FakeOpenAIClient()
|
|
70
73
|
|
|
71
74
|
response = client.audio.transcriptions.create(
|
|
@@ -77,8 +80,8 @@ def test_audio_transcriptions_create_posts_multipart_like_official_sdk():
|
|
|
77
80
|
|
|
78
81
|
assert isinstance(response, Transcription)
|
|
79
82
|
assert response.text == "hello"
|
|
80
|
-
path, kwargs, headers = client.
|
|
81
|
-
assert path == "/
|
|
83
|
+
path, kwargs, headers = client.chatgpt_raw_posts[0]
|
|
84
|
+
assert path == "/transcribe"
|
|
82
85
|
assert kwargs["files"]["file"] == ("clip.wav", b"wav", "audio/wav")
|
|
83
86
|
assert kwargs["data"] == {
|
|
84
87
|
"model": "gpt-4o-mini-transcribe",
|
|
@@ -86,3 +89,34 @@ def test_audio_transcriptions_create_posts_multipart_like_official_sdk():
|
|
|
86
89
|
"response_format": "json",
|
|
87
90
|
}
|
|
88
91
|
assert headers["Authorization"] == "Bearer chatgpt-token"
|
|
92
|
+
assert headers["ChatGPT-Account-ID"] == "account-id"
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_audio_transcriptions_text_format_returns_string():
|
|
96
|
+
client = FakeOpenAIClient()
|
|
97
|
+
|
|
98
|
+
response = client.audio.transcriptions.create(
|
|
99
|
+
model="gpt-4o-mini-transcribe",
|
|
100
|
+
file=("clip.wav", b"wav", "audio/wav"),
|
|
101
|
+
response_format="text",
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
assert response == "hello"
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def test_audio_transcriptions_rejects_unsupported_options():
|
|
108
|
+
client = FakeOpenAIClient()
|
|
109
|
+
|
|
110
|
+
with pytest.raises(CodexBackendUnsupportedParameterError, match="stream"):
|
|
111
|
+
client.audio.transcriptions.create(
|
|
112
|
+
model="gpt-4o-mini-transcribe",
|
|
113
|
+
file=("clip.wav", b"wav", "audio/wav"),
|
|
114
|
+
stream=True,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
with pytest.raises(CodexBackendUnsupportedParameterError, match="json.*text"):
|
|
118
|
+
client.audio.transcriptions.create(
|
|
119
|
+
model="gpt-4o-mini-transcribe",
|
|
120
|
+
file=("clip.wav", b"wav", "audio/wav"),
|
|
121
|
+
response_format="srt",
|
|
122
|
+
)
|
|
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.7 → codex_backend_sdk-0.3.8}/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
|