Skip to content

Commit ffbe827

Browse files
feat(api): update via SDK Studio
1 parent 79c3d55 commit ffbe827

File tree

3 files changed

+106
-406
lines changed

3 files changed

+106
-406
lines changed

src/codex/_client.py

Lines changed: 62 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from ._types import (
1414
NOT_GIVEN,
1515
Omit,
16+
Headers,
1617
Timeout,
1718
NotGiven,
1819
Transport,
@@ -26,7 +27,7 @@
2627
from ._version import __version__
2728
from .resources import health
2829
from ._streaming import Stream as Stream, AsyncStream as AsyncStream
29-
from ._exceptions import CodexError, APIStatusError
30+
from ._exceptions import APIStatusError
3031
from ._base_client import (
3132
DEFAULT_MAX_RETRIES,
3233
SyncAPIClient,
@@ -48,9 +49,9 @@ class Codex(SyncAPIClient):
4849
with_streaming_response: CodexWithStreamedResponse
4950

5051
# client options
51-
bearer_token: str
52-
api_key: str
53-
access_key: str
52+
bearer_token: str | None
53+
api_key: str | None
54+
access_key: str | None
5455

5556
def __init__(
5657
self,
@@ -86,26 +87,14 @@ def __init__(
8687
"""
8788
if bearer_token is None:
8889
bearer_token = os.environ.get("BEARER_TOKEN")
89-
if bearer_token is None:
90-
raise CodexError(
91-
"The bearer_token client option must be set either by passing bearer_token to the client or by setting the BEARER_TOKEN environment variable"
92-
)
9390
self.bearer_token = bearer_token
9491

9592
if api_key is None:
9693
api_key = os.environ.get("AUTHENTICATED_API_KEY")
97-
if api_key is None:
98-
raise CodexError(
99-
"The api_key client option must be set either by passing api_key to the client or by setting the AUTHENTICATED_API_KEY environment variable"
100-
)
10194
self.api_key = api_key
10295

10396
if access_key is None:
10497
access_key = os.environ.get("PUBLIC_ACCESS_KEY")
105-
if access_key is None:
106-
raise CodexError(
107-
"The access_key client option must be set either by passing access_key to the client or by setting the PUBLIC_ACCESS_KEY environment variable"
108-
)
10998
self.access_key = access_key
11099

111100
if base_url is None:
@@ -150,16 +139,22 @@ def auth_headers(self) -> dict[str, str]:
150139
@property
151140
def _http_bearer(self) -> dict[str, str]:
152141
bearer_token = self.bearer_token
142+
if bearer_token is None:
143+
return {}
153144
return {"Authorization": f"Bearer {bearer_token}"}
154145

155146
@property
156147
def _authenticated_api_key(self) -> dict[str, str]:
157148
api_key = self.api_key
149+
if api_key is None:
150+
return {}
158151
return {"X-API-Key": api_key}
159152

160153
@property
161154
def _public_access_key(self) -> dict[str, str]:
162155
access_key = self.access_key
156+
if access_key is None:
157+
return {}
163158
return {"X-Access-Key": access_key}
164159

165160
@property
@@ -171,6 +166,27 @@ def default_headers(self) -> dict[str, str | Omit]:
171166
**self._custom_headers,
172167
}
173168

169+
@override
170+
def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None:
171+
if self.bearer_token and headers.get("Authorization"):
172+
return
173+
if isinstance(custom_headers.get("Authorization"), Omit):
174+
return
175+
176+
if self.api_key and headers.get("X-API-Key"):
177+
return
178+
if isinstance(custom_headers.get("X-API-Key"), Omit):
179+
return
180+
181+
if self.access_key and headers.get("X-Access-Key"):
182+
return
183+
if isinstance(custom_headers.get("X-Access-Key"), Omit):
184+
return
185+
186+
raise TypeError(
187+
'"Could not resolve authentication method. Expected one of bearer_token, api_key or access_key to be set. Or for one of the `Authorization`, `X-API-Key` or `X-Access-Key` headers to be explicitly omitted"'
188+
)
189+
174190
def copy(
175191
self,
176192
*,
@@ -269,9 +285,9 @@ class AsyncCodex(AsyncAPIClient):
269285
with_streaming_response: AsyncCodexWithStreamedResponse
270286

271287
# client options
272-
bearer_token: str
273-
api_key: str
274-
access_key: str
288+
bearer_token: str | None
289+
api_key: str | None
290+
access_key: str | None
275291

276292
def __init__(
277293
self,
@@ -307,26 +323,14 @@ def __init__(
307323
"""
308324
if bearer_token is None:
309325
bearer_token = os.environ.get("BEARER_TOKEN")
310-
if bearer_token is None:
311-
raise CodexError(
312-
"The bearer_token client option must be set either by passing bearer_token to the client or by setting the BEARER_TOKEN environment variable"
313-
)
314326
self.bearer_token = bearer_token
315327

316328
if api_key is None:
317329
api_key = os.environ.get("AUTHENTICATED_API_KEY")
318-
if api_key is None:
319-
raise CodexError(
320-
"The api_key client option must be set either by passing api_key to the client or by setting the AUTHENTICATED_API_KEY environment variable"
321-
)
322330
self.api_key = api_key
323331

324332
if access_key is None:
325333
access_key = os.environ.get("PUBLIC_ACCESS_KEY")
326-
if access_key is None:
327-
raise CodexError(
328-
"The access_key client option must be set either by passing access_key to the client or by setting the PUBLIC_ACCESS_KEY environment variable"
329-
)
330334
self.access_key = access_key
331335

332336
if base_url is None:
@@ -371,16 +375,22 @@ def auth_headers(self) -> dict[str, str]:
371375
@property
372376
def _http_bearer(self) -> dict[str, str]:
373377
bearer_token = self.bearer_token
378+
if bearer_token is None:
379+
return {}
374380
return {"Authorization": f"Bearer {bearer_token}"}
375381

376382
@property
377383
def _authenticated_api_key(self) -> dict[str, str]:
378384
api_key = self.api_key
385+
if api_key is None:
386+
return {}
379387
return {"X-API-Key": api_key}
380388

381389
@property
382390
def _public_access_key(self) -> dict[str, str]:
383391
access_key = self.access_key
392+
if access_key is None:
393+
return {}
384394
return {"X-Access-Key": access_key}
385395

386396
@property
@@ -392,6 +402,27 @@ def default_headers(self) -> dict[str, str | Omit]:
392402
**self._custom_headers,
393403
}
394404

405+
@override
406+
def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None:
407+
if self.bearer_token and headers.get("Authorization"):
408+
return
409+
if isinstance(custom_headers.get("Authorization"), Omit):
410+
return
411+
412+
if self.api_key and headers.get("X-API-Key"):
413+
return
414+
if isinstance(custom_headers.get("X-API-Key"), Omit):
415+
return
416+
417+
if self.access_key and headers.get("X-Access-Key"):
418+
return
419+
if isinstance(custom_headers.get("X-Access-Key"), Omit):
420+
return
421+
422+
raise TypeError(
423+
'"Could not resolve authentication method. Expected one of bearer_token, api_key or access_key to be set. Or for one of the `Authorization`, `X-API-Key` or `X-Access-Key` headers to be explicitly omitted"'
424+
)
425+
395426
def copy(
396427
self,
397428
*,

tests/conftest.py

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,14 @@ def pytest_collection_modifyitems(items: list[pytest.Function]) -> None:
2828

2929
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
3030

31-
bearer_token = "My Bearer Token"
32-
api_key = "My API Key"
33-
access_key = "My Access Key"
34-
3531

3632
@pytest.fixture(scope="session")
3733
def client(request: FixtureRequest) -> Iterator[Codex]:
3834
strict = getattr(request, "param", True)
3935
if not isinstance(strict, bool):
4036
raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}")
4137

42-
with Codex(
43-
base_url=base_url,
44-
bearer_token=bearer_token,
45-
api_key=api_key,
46-
access_key=access_key,
47-
_strict_response_validation=strict,
48-
) as client:
38+
with Codex(base_url=base_url, _strict_response_validation=strict) as client:
4939
yield client
5040

5141

@@ -55,11 +45,5 @@ async def async_client(request: FixtureRequest) -> AsyncIterator[AsyncCodex]:
5545
if not isinstance(strict, bool):
5646
raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}")
5747

58-
async with AsyncCodex(
59-
base_url=base_url,
60-
bearer_token=bearer_token,
61-
api_key=api_key,
62-
access_key=access_key,
63-
_strict_response_validation=strict,
64-
) as client:
48+
async with AsyncCodex(base_url=base_url, _strict_response_validation=strict) as client:
6549
yield client

0 commit comments

Comments
 (0)