Skip to content

Commit f9080ce

Browse files
authored
Merge pull request #25 from browserbase/main--merge-conflict
NOTICE: Stainless generated code has conflicted with your custom code
2 parents ba613aa + 07f832b commit f9080ce

File tree

13 files changed

+1544
-108
lines changed

13 files changed

+1544
-108
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,4 @@ dist
1515
codegen.log
1616
Brewfile.lock.json
1717
screenshot.png
18-
openapi.v1.yaml
1918
**/.DS_Store

README.md

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,45 @@ The full API of this library can be found in [api.md](api.md).
2828

2929
```python
3030
import os
31+
from playwright.sync_api import Playwright, sync_playwright
3132
from browserbase import Browserbase
3233

33-
client = Browserbase(
34+
BROWSERBASE_API_KEY = os.environ.get("BROWSERBASE_API_KEY")
35+
BROWSERBASE_PROJECT_ID = os.environ.get("BROWSERBASE_PROJECT_ID")
36+
37+
bb = Browserbase(
3438
# This is the default and can be omitted
35-
api_key=os.environ.get("BROWSERBASE_API_KEY"),
39+
api_key=BROWSERBASE_API_KEY,
3640
)
3741

38-
context = client.contexts.create(
39-
project_id="projectId",
40-
)
41-
print(context.id)
42-
```
42+
def run(playwright: Playwright) -> None:
43+
# Create a session on Browserbase
44+
session = bb.sessions.create(project_id=BROWSERBASE_PROJECT_ID)
45+
46+
# Connect to the remote session
47+
chromium = playwright.chromium
48+
browser = chromium.connect_over_cdp(session.connect_url)
49+
context = browser.contexts[0]
50+
page = context.pages[0]
4351

44-
While you can provide an `api_key` keyword argument,
45-
we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/)
46-
to add `BROWSERBASE_API_KEY="My API Key"` to your `.env` file
47-
so that your API Key is not stored in source control.
52+
# Execute Playwright actions on the remote browser tab
53+
page.goto("https://news.ycombinator.com/")
54+
page_title = page.title()
55+
assert (
56+
page_title == "Hacker News"
57+
), f"Page title is not 'Hacker News', it is '{page_title}'"
58+
page.screenshot(path="screenshot.png")
59+
60+
page.close()
61+
browser.close()
62+
print("Done!")
63+
64+
65+
if __name__ == "__main__":
66+
with sync_playwright() as playwright:
67+
run(playwright)
68+
69+
```
4870

4971
## Examples
5072

@@ -63,33 +85,6 @@ rye run example playwright_basic # replace with the example you want to run
6385
> [!NOTE]
6486
> Make sure you have a `.env` file that matches the [.env.example](.env.example) file in the root of this repository.
6587
66-
## Async usage
67-
68-
Simply import `AsyncBrowserbase` instead of `Browserbase` and use `await` with each API call:
69-
70-
```python
71-
import os
72-
import asyncio
73-
from browserbase import AsyncBrowserbase
74-
75-
client = AsyncBrowserbase(
76-
# This is the default and can be omitted
77-
api_key=os.environ.get("BROWSERBASE_API_KEY"),
78-
)
79-
80-
81-
async def main() -> None:
82-
context = await client.contexts.create(
83-
project_id="projectId",
84-
)
85-
print(context.id)
86-
87-
88-
asyncio.run(main())
89-
```
90-
91-
Functionality between the synchronous and asynchronous clients is otherwise identical.
92-
9388
## Using types
9489

9590
Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:

examples/e2e/test_playwright.py

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1+
import os
2+
from typing import Generator
3+
14
import pytest
2-
from playwright.sync_api import Playwright, sync_playwright
35
from dotenv import load_dotenv
4-
import os
6+
from playwright.sync_api import Playwright, sync_playwright
57
from browserbase import Browserbase
68

79
from .. import (
810
BROWSERBASE_API_KEY,
911
playwright_basic,
12+
playwright_proxy,
13+
playwright_upload,
1014
playwright_captcha,
1115
playwright_contexts,
1216
playwright_downloads,
@@ -15,28 +19,58 @@
1519
bb = Browserbase(api_key=BROWSERBASE_API_KEY)
1620
load_dotenv()
1721

18-
SKIP_CAPTCHA_SOLVING = os.getenv("SKIP_CAPTCHA_SOLVING", "true").lower() == "true"
22+
CI = os.getenv("CI", "false").lower() == "true"
1923

2024

2125
@pytest.fixture(scope="session")
22-
def playwright():
26+
def playwright() -> Generator[Playwright, None, None]:
2327
with sync_playwright() as p:
2428
yield p
2529

26-
27-
def test_playwright_basic(playwright: Playwright):
30+
def test_playwright_basic(playwright: Playwright) -> None:
2831
playwright_basic.run(playwright)
2932

3033

31-
def test_playwright_captcha(playwright: Playwright):
32-
if SKIP_CAPTCHA_SOLVING:
33-
pytest.skip("Skipping captcha solving")
34+
@pytest.mark.skipif(True, reason="Flaky and fails often")
35+
def test_playwright_captcha(playwright: Playwright) -> None:
3436
playwright_captcha.run(playwright)
3537

3638

37-
def test_playwright_contexts(playwright: Playwright):
39+
def test_playwright_contexts(playwright: Playwright) -> None:
3840
playwright_contexts.run(playwright)
3941

4042

41-
def test_playwright_downloads(playwright: Playwright):
43+
def test_playwright_downloads(playwright: Playwright) -> None:
4244
playwright_downloads.run(playwright)
45+
46+
47+
def test_playwright_proxy_enable_via_create_session(playwright: Playwright) -> None:
48+
playwright_proxy.run_enable_via_create_session(playwright)
49+
50+
51+
def test_playwright_proxy_enable_via_querystring(playwright: Playwright) -> None:
52+
playwright_proxy.run_enable_via_querystring_with_created_session(playwright)
53+
54+
55+
@pytest.mark.skipif(CI, reason="Flaky and fails on CI")
56+
def test_playwright_proxy_geolocation_country(playwright: Playwright) -> None:
57+
playwright_proxy.run_geolocation_country(playwright)
58+
59+
60+
@pytest.mark.skipif(CI, reason="Flaky and fails on CI")
61+
def test_playwright_proxy_geolocation_state(playwright: Playwright) -> None:
62+
playwright_proxy.run_geolocation_state(playwright)
63+
64+
65+
@pytest.mark.skipif(CI, reason="Flaky and fails on CI")
66+
def test_playwright_proxy_geolocation_american_city(playwright: Playwright) -> None:
67+
playwright_proxy.run_geolocation_american_city(playwright)
68+
69+
70+
@pytest.mark.skipif(CI, reason="Flaky and fails on CI")
71+
def test_playwright_proxy_geolocation_non_american_city(playwright: Playwright) -> None:
72+
playwright_proxy.run_geolocation_non_american_city(playwright)
73+
74+
75+
def test_playwright_upload(playwright: Playwright) -> None:
76+
playwright_upload.run(playwright)

examples/packages/logo.png

5.81 KB
Loading

examples/playwright_basic.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
1+
import os
2+
13
from playwright.sync_api import Playwright, sync_playwright
24

3-
from examples import (
4-
BROWSERBASE_API_KEY,
5-
BROWSERBASE_PROJECT_ID,
6-
BROWSERBASE_CONNECT_URL,
7-
bb,
5+
from browserbase import Browserbase
6+
7+
BROWSERBASE_API_KEY = os.environ.get("BROWSERBASE_API_KEY", "")
8+
if not BROWSERBASE_API_KEY:
9+
raise ValueError("BROWSERBASE_API_KEY is not set")
10+
BROWSERBASE_PROJECT_ID = os.environ.get("BROWSERBASE_PROJECT_ID", "")
11+
if not BROWSERBASE_PROJECT_ID:
12+
raise ValueError("BROWSERBASE_PROJECT_ID is not set")
13+
14+
bb = Browserbase(
15+
# This is the default and can be omitted
16+
api_key=BROWSERBASE_API_KEY,
817
)
918

1019

11-
def run(playwright: Playwright):
20+
def run(playwright: Playwright) -> None:
1221
# Create a session on Browserbase
1322
session = bb.sessions.create(project_id=BROWSERBASE_PROJECT_ID)
14-
assert session.id is not None
15-
assert session.status == "RUNNING", f"Session status is {session.status}"
1623

1724
# Connect to the remote session
18-
connect_url = (
19-
f"{BROWSERBASE_CONNECT_URL}?sessionId={session.id}&apiKey={BROWSERBASE_API_KEY}"
20-
)
2125
chromium = playwright.chromium
22-
browser = chromium.connect_over_cdp(connect_url)
26+
browser = chromium.connect_over_cdp(session.connect_url)
2327
context = browser.contexts[0]
2428
page = context.pages[0]
2529

examples/playwright_captcha.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from playwright.sync_api import Playwright, sync_playwright, ConsoleMessage
1+
from playwright.sync_api import Playwright, ConsoleMessage, sync_playwright
22

33

44
from examples import (
@@ -12,7 +12,7 @@
1212
OVERRIDE_TIMEOUT = 60000 # 60 seconds, adjust as needed
1313

1414

15-
def run(playwright: Playwright):
15+
def run(playwright: Playwright) -> None:
1616
# Create a session on Browserbase
1717
session = bb.sessions.create(project_id=BROWSERBASE_PROJECT_ID)
1818
assert session.id is not None
@@ -32,7 +32,7 @@ def run(playwright: Playwright):
3232

3333
# Browserbase logs messages to the console to indicate when captcha solving has started and finished
3434
# We can track these messages to know when the captcha solving has started and finished
35-
def handle_console(msg: ConsoleMessage):
35+
def handle_console(msg: ConsoleMessage) -> None:
3636
nonlocal captcha_solving_started, captcha_solving_finished
3737
if msg.text == "browserbase-solving-started":
3838
captcha_solving_started = True

examples/playwright_contexts.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
from playwright.sync_api import Playwright, sync_playwright, Browser, Cookie
2-
from browserbase.types.session_create_params import (
3-
BrowserSettings,
4-
BrowserSettingsContext,
5-
)
61
import time
72
from typing import Optional
83

4+
from playwright.sync_api import Cookie, Browser, Playwright, sync_playwright
5+
6+
97
from examples import (
108
BROWSERBASE_API_KEY,
119
BROWSERBASE_PROJECT_ID,
1210
BROWSERBASE_CONNECT_URL,
1311
bb,
1412
)
13+
from browserbase.types.session_create_params import (
14+
BrowserSettings,
15+
BrowserSettingsContext,
16+
)
17+
1518

1619
CONTEXT_TEST_URL = "https://www.browserbase.com"
1720
SECOND = 1000
@@ -27,7 +30,7 @@ def find_cookie(browser: Browser, name: str) -> Optional[Cookie]:
2730
return next((cookie for cookie in cookies if cookie.get("name") == name), None)
2831

2932

30-
def run(playwright: Playwright):
33+
def run(playwright: Playwright) -> None:
3134
context_id = None
3235
session_id = None
3336
test_cookie_name = None

examples/playwright_downloads.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import io
12
import re
23
import zipfile
3-
import io
4+
45
from playwright.sync_api import Playwright, sync_playwright
6+
7+
58
from examples import (
69
BROWSERBASE_API_KEY,
710
BROWSERBASE_PROJECT_ID,
@@ -17,7 +20,7 @@ def get_download(session_id: str) -> bytes:
1720
return response.read()
1821

1922

20-
def run(playwright: Playwright):
23+
def run(playwright: Playwright) -> None:
2124
# Create a session on Browserbase
2225
session = bb.sessions.create(project_id=BROWSERBASE_PROJECT_ID)
2326
assert session.id is not None

0 commit comments

Comments
 (0)