1313from ._types import (
1414 NOT_GIVEN ,
1515 Omit ,
16+ Headers ,
1617 Timeout ,
1718 NotGiven ,
1819 Transport ,
2627from ._version import __version__
2728from .resources import health
2829from ._streaming import Stream as Stream , AsyncStream as AsyncStream
29- from ._exceptions import CodexError , APIStatusError
30+ from ._exceptions import APIStatusError
3031from ._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 * ,
0 commit comments