1313from ._types import (
1414 NOT_GIVEN ,
1515 Omit ,
16- Headers ,
1716 Timeout ,
1817 NotGiven ,
1918 Transport ,
2423from ._version import __version__
2524from .resources import auth , query , documents , collections
2625from ._streaming import Stream as Stream , AsyncStream as AsyncStream
27- from ._exceptions import APIStatusError
26+ from ._exceptions import APIStatusError , HyperspellError
2827from ._base_client import (
2928 DEFAULT_MAX_RETRIES ,
3029 SyncAPIClient ,
@@ -54,12 +53,14 @@ class Hyperspell(SyncAPIClient):
5453 with_streaming_response : HyperspellWithStreamedResponse
5554
5655 # client options
57- api_key : str | None
56+ api_key : str
57+ user_id : str | None
5858
5959 def __init__ (
6060 self ,
6161 * ,
6262 api_key : str | None = None ,
63+ user_id : str | None = None ,
6364 base_url : str | httpx .URL | None = None ,
6465 timeout : Union [float , Timeout , None , NotGiven ] = NOT_GIVEN ,
6566 max_retries : int = DEFAULT_MAX_RETRIES ,
@@ -85,8 +86,14 @@ def __init__(
8586 """
8687 if api_key is None :
8788 api_key = os .environ .get ("HYPERSPELL_TOKEN" )
89+ if api_key is None :
90+ raise HyperspellError (
91+ "The api_key client option must be set either by passing api_key to the client or by setting the HYPERSPELL_TOKEN environment variable"
92+ )
8893 self .api_key = api_key
8994
95+ self .user_id = user_id
96+
9097 if base_url is None :
9198 base_url = os .environ .get ("HYPERSPELL_BASE_URL" )
9299 if base_url is None :
@@ -120,8 +127,6 @@ def qs(self) -> Querystring:
120127 @override
121128 def auth_headers (self ) -> dict [str , str ]:
122129 api_key = self .api_key
123- if api_key is None :
124- return {}
125130 return {"Authorization" : f"Bearer { api_key } " }
126131
127132 @property
@@ -133,21 +138,11 @@ def default_headers(self) -> dict[str, str | Omit]:
133138 ** self ._custom_headers ,
134139 }
135140
136- @override
137- def _validate_headers (self , headers : Headers , custom_headers : Headers ) -> None :
138- if self .api_key and headers .get ("Authorization" ):
139- return
140- if isinstance (custom_headers .get ("Authorization" ), Omit ):
141- return
142-
143- raise TypeError (
144- '"Could not resolve authentication method. Expected the api_key to be set. Or for the `Authorization` headers to be explicitly omitted"'
145- )
146-
147141 def copy (
148142 self ,
149143 * ,
150144 api_key : str | None = None ,
145+ user_id : str | None = None ,
151146 base_url : str | httpx .URL | None = None ,
152147 timeout : float | Timeout | None | NotGiven = NOT_GIVEN ,
153148 http_client : httpx .Client | None = None ,
@@ -182,6 +177,7 @@ def copy(
182177 http_client = http_client or self ._client
183178 return self .__class__ (
184179 api_key = api_key or self .api_key ,
180+ user_id = user_id or self .user_id ,
185181 base_url = base_url or self .base_url ,
186182 timeout = self .timeout if isinstance (timeout , NotGiven ) else timeout ,
187183 http_client = http_client ,
@@ -239,12 +235,14 @@ class AsyncHyperspell(AsyncAPIClient):
239235 with_streaming_response : AsyncHyperspellWithStreamedResponse
240236
241237 # client options
242- api_key : str | None
238+ api_key : str
239+ user_id : str | None
243240
244241 def __init__ (
245242 self ,
246243 * ,
247244 api_key : str | None = None ,
245+ user_id : str | None = None ,
248246 base_url : str | httpx .URL | None = None ,
249247 timeout : Union [float , Timeout , None , NotGiven ] = NOT_GIVEN ,
250248 max_retries : int = DEFAULT_MAX_RETRIES ,
@@ -270,8 +268,14 @@ def __init__(
270268 """
271269 if api_key is None :
272270 api_key = os .environ .get ("HYPERSPELL_TOKEN" )
271+ if api_key is None :
272+ raise HyperspellError (
273+ "The api_key client option must be set either by passing api_key to the client or by setting the HYPERSPELL_TOKEN environment variable"
274+ )
273275 self .api_key = api_key
274276
277+ self .user_id = user_id
278+
275279 if base_url is None :
276280 base_url = os .environ .get ("HYPERSPELL_BASE_URL" )
277281 if base_url is None :
@@ -305,8 +309,6 @@ def qs(self) -> Querystring:
305309 @override
306310 def auth_headers (self ) -> dict [str , str ]:
307311 api_key = self .api_key
308- if api_key is None :
309- return {}
310312 return {"Authorization" : f"Bearer { api_key } " }
311313
312314 @property
@@ -318,21 +320,11 @@ def default_headers(self) -> dict[str, str | Omit]:
318320 ** self ._custom_headers ,
319321 }
320322
321- @override
322- def _validate_headers (self , headers : Headers , custom_headers : Headers ) -> None :
323- if self .api_key and headers .get ("Authorization" ):
324- return
325- if isinstance (custom_headers .get ("Authorization" ), Omit ):
326- return
327-
328- raise TypeError (
329- '"Could not resolve authentication method. Expected the api_key to be set. Or for the `Authorization` headers to be explicitly omitted"'
330- )
331-
332323 def copy (
333324 self ,
334325 * ,
335326 api_key : str | None = None ,
327+ user_id : str | None = None ,
336328 base_url : str | httpx .URL | None = None ,
337329 timeout : float | Timeout | None | NotGiven = NOT_GIVEN ,
338330 http_client : httpx .AsyncClient | None = None ,
@@ -367,6 +359,7 @@ def copy(
367359 http_client = http_client or self ._client
368360 return self .__class__ (
369361 api_key = api_key or self .api_key ,
362+ user_id = user_id or self .user_id ,
370363 base_url = base_url or self .base_url ,
371364 timeout = self .timeout if isinstance (timeout , NotGiven ) else timeout ,
372365 http_client = http_client ,
0 commit comments