3
3
from __future__ import annotations
4
4
5
5
import os
6
- from typing import Any , Union , Mapping
7
- from typing_extensions import Self , override
6
+ from typing import Any , Dict , Union , Mapping , cast
7
+ from typing_extensions import Self , Literal , override
8
8
9
9
import httpx
10
10
33
33
)
34
34
35
35
__all__ = [
36
+ "ENVIRONMENTS" ,
36
37
"Timeout" ,
37
38
"Transport" ,
38
39
"ProxiesTypes" ,
44
45
"AsyncClient" ,
45
46
]
46
47
48
+ ENVIRONMENTS : Dict [str , str ] = {
49
+ "production" : "https://api.browserbase.com" ,
50
+ "development" : "https://api.dev.browserbase.com" ,
51
+ "local" : "http://api.localhost" ,
52
+ }
53
+
47
54
48
55
class Browserbase (SyncAPIClient ):
49
56
contexts : resources .ContextsResource
@@ -56,11 +63,14 @@ class Browserbase(SyncAPIClient):
56
63
# client options
57
64
api_key : str
58
65
66
+ _environment : Literal ["production" , "development" , "local" ] | NotGiven
67
+
59
68
def __init__ (
60
69
self ,
61
70
* ,
62
71
api_key : str | None = None ,
63
- base_url : str | httpx .URL | None = None ,
72
+ environment : Literal ["production" , "development" , "local" ] | NotGiven = NOT_GIVEN ,
73
+ base_url : str | httpx .URL | None | NotGiven = NOT_GIVEN ,
64
74
timeout : Union [float , Timeout , None , NotGiven ] = NOT_GIVEN ,
65
75
max_retries : int = DEFAULT_MAX_RETRIES ,
66
76
default_headers : Mapping [str , str ] | None = None ,
@@ -91,10 +101,31 @@ def __init__(
91
101
)
92
102
self .api_key = api_key
93
103
94
- if base_url is None :
95
- base_url = os .environ .get ("BROWSERBASE_BASE_URL" )
96
- if base_url is None :
97
- base_url = f"https://api.dev.browserbase.com"
104
+ self ._environment = environment
105
+
106
+ base_url_env = os .environ .get ("BROWSERBASE_BASE_URL" )
107
+ if is_given (base_url ) and base_url is not None :
108
+ # cast required because mypy doesn't understand the type narrowing
109
+ base_url = cast ("str | httpx.URL" , base_url ) # pyright: ignore[reportUnnecessaryCast]
110
+ elif is_given (environment ):
111
+ if base_url_env and base_url is not None :
112
+ raise ValueError (
113
+ "Ambiguous URL; The `BROWSERBASE_BASE_URL` env var and the `environment` argument are given. If you want to use the environment, you must pass base_url=None" ,
114
+ )
115
+
116
+ try :
117
+ base_url = ENVIRONMENTS [environment ]
118
+ except KeyError as exc :
119
+ raise ValueError (f"Unknown environment: { environment } " ) from exc
120
+ elif base_url_env is not None :
121
+ base_url = base_url_env
122
+ else :
123
+ self ._environment = environment = "production"
124
+
125
+ try :
126
+ base_url = ENVIRONMENTS [environment ]
127
+ except KeyError as exc :
128
+ raise ValueError (f"Unknown environment: { environment } " ) from exc
98
129
99
130
super ().__init__ (
100
131
version = __version__ ,
@@ -138,6 +169,7 @@ def copy(
138
169
self ,
139
170
* ,
140
171
api_key : str | None = None ,
172
+ environment : Literal ["production" , "development" , "local" ] | None = None ,
141
173
base_url : str | httpx .URL | None = None ,
142
174
timeout : float | Timeout | None | NotGiven = NOT_GIVEN ,
143
175
http_client : httpx .Client | None = None ,
@@ -173,6 +205,7 @@ def copy(
173
205
return self .__class__ (
174
206
api_key = api_key or self .api_key ,
175
207
base_url = base_url or self .base_url ,
208
+ environment = environment or self ._environment ,
176
209
timeout = self .timeout if isinstance (timeout , NotGiven ) else timeout ,
177
210
http_client = http_client ,
178
211
max_retries = max_retries if is_given (max_retries ) else self .max_retries ,
@@ -230,11 +263,14 @@ class AsyncBrowserbase(AsyncAPIClient):
230
263
# client options
231
264
api_key : str
232
265
266
+ _environment : Literal ["production" , "development" , "local" ] | NotGiven
267
+
233
268
def __init__ (
234
269
self ,
235
270
* ,
236
271
api_key : str | None = None ,
237
- base_url : str | httpx .URL | None = None ,
272
+ environment : Literal ["production" , "development" , "local" ] | NotGiven = NOT_GIVEN ,
273
+ base_url : str | httpx .URL | None | NotGiven = NOT_GIVEN ,
238
274
timeout : Union [float , Timeout , None , NotGiven ] = NOT_GIVEN ,
239
275
max_retries : int = DEFAULT_MAX_RETRIES ,
240
276
default_headers : Mapping [str , str ] | None = None ,
@@ -265,10 +301,31 @@ def __init__(
265
301
)
266
302
self .api_key = api_key
267
303
268
- if base_url is None :
269
- base_url = os .environ .get ("BROWSERBASE_BASE_URL" )
270
- if base_url is None :
271
- base_url = f"https://api.dev.browserbase.com"
304
+ self ._environment = environment
305
+
306
+ base_url_env = os .environ .get ("BROWSERBASE_BASE_URL" )
307
+ if is_given (base_url ) and base_url is not None :
308
+ # cast required because mypy doesn't understand the type narrowing
309
+ base_url = cast ("str | httpx.URL" , base_url ) # pyright: ignore[reportUnnecessaryCast]
310
+ elif is_given (environment ):
311
+ if base_url_env and base_url is not None :
312
+ raise ValueError (
313
+ "Ambiguous URL; The `BROWSERBASE_BASE_URL` env var and the `environment` argument are given. If you want to use the environment, you must pass base_url=None" ,
314
+ )
315
+
316
+ try :
317
+ base_url = ENVIRONMENTS [environment ]
318
+ except KeyError as exc :
319
+ raise ValueError (f"Unknown environment: { environment } " ) from exc
320
+ elif base_url_env is not None :
321
+ base_url = base_url_env
322
+ else :
323
+ self ._environment = environment = "production"
324
+
325
+ try :
326
+ base_url = ENVIRONMENTS [environment ]
327
+ except KeyError as exc :
328
+ raise ValueError (f"Unknown environment: { environment } " ) from exc
272
329
273
330
super ().__init__ (
274
331
version = __version__ ,
@@ -312,6 +369,7 @@ def copy(
312
369
self ,
313
370
* ,
314
371
api_key : str | None = None ,
372
+ environment : Literal ["production" , "development" , "local" ] | None = None ,
315
373
base_url : str | httpx .URL | None = None ,
316
374
timeout : float | Timeout | None | NotGiven = NOT_GIVEN ,
317
375
http_client : httpx .AsyncClient | None = None ,
@@ -347,6 +405,7 @@ def copy(
347
405
return self .__class__ (
348
406
api_key = api_key or self .api_key ,
349
407
base_url = base_url or self .base_url ,
408
+ environment = environment or self ._environment ,
350
409
timeout = self .timeout if isinstance (timeout , NotGiven ) else timeout ,
351
410
http_client = http_client ,
352
411
max_retries = max_retries if is_given (max_retries ) else self .max_retries ,
0 commit comments