Skip to content

Commit 6fc9016

Browse files
authored
Merge pull request #6 from browserbase/anirudh/add-basic-examples
add rye + basic examples
2 parents a4dd3d9 + 335a81a commit 6fc9016

12 files changed

+157
-78
lines changed

Diff for: .gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ dist
1414
.envrc
1515
codegen.log
1616
Brewfile.lock.json
17+
screenshot.png
18+
openapi.v1.yaml

Diff for: README.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,18 @@ so that your API Key is not stored in source control.
5050

5151
See the [examples](examples) directory for more usage examples.
5252

53+
> [!NOTE]
54+
> Running the examples requires [Rye](https://rye.astral.sh/) to be installed.
55+
5356
To run the examples, clone this repository and run the following commands from the project root (this directory):
5457

5558
```bash
56-
python3 -m venv .venv
57-
source .venv/bin/activate
58-
python3 -m pip install .
59-
python3 -m examples/02_create_session.py # replace with the example you want to run
59+
rye sync
60+
rye run example playwright_basic # replace with the example you want to run
6061
```
6162

62-
!!! note
63-
Make sure you have a `.env` file that matches the [.env.example](.env.example) file in the root of this repository.
63+
> [!NOTE]
64+
> Make sure you have a `.env` file that matches the [.env.example](.env.example) file in the root of this repository.
6465
6566
## Async usage
6667

Diff for: examples/01_quickstart.py

-28
This file was deleted.

Diff for: examples/02_create_session.py

-44
This file was deleted.

Diff for: examples/__init__.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import os
2+
3+
from dotenv import load_dotenv
4+
5+
from browserbase import Browserbase
6+
7+
# Load our environment variables
8+
load_dotenv(override=True)
9+
10+
# Make sure we have the required environment variables
11+
BROWSERBASE_CONNECT_URL = os.environ.get(
12+
"BROWSERBASE_CONNECT_URL", "wss://connect.browserbase.com"
13+
)
14+
_BROWSERBASE_API_KEY = os.environ.get("BROWSERBASE_API_KEY")
15+
if not _BROWSERBASE_API_KEY:
16+
raise ValueError("BROWSERBASE_API_KEY is not set in environment")
17+
BROWSERBASE_API_KEY: str = _BROWSERBASE_API_KEY
18+
_BROWSERBASE_PROJECT_ID = os.environ.get("BROWSERBASE_PROJECT_ID")
19+
if not _BROWSERBASE_PROJECT_ID:
20+
raise ValueError("BROWSERBASE_PROJECT_ID is not set in environment")
21+
BROWSERBASE_PROJECT_ID = _BROWSERBASE_PROJECT_ID or ""
22+
23+
# Instantiate our Browserbase client
24+
bb = Browserbase(api_key=BROWSERBASE_API_KEY)

Diff for: examples/e2e/README.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# End-to-end tests
2+
3+
This directory contains end-to-end tests that run against a real Browserbase instance.
4+
5+
## Running the tests
6+
7+
To run the tests, you will need to set the following environment variables:
8+
9+
- `BROWSERBASE_API_KEY`: Your Browserbase API key
10+
- `BROWSERBASE_PROJECT_ID`: The ID of the project you want to use for the tests
11+
12+
You can set these variables in a `.env` file in the root of this directory.
13+
14+
Then, run the tests with:
15+
16+
```sh
17+
$ rye run test:e2e
18+
```
19+
20+
## Writing tests
21+
22+
The tests are written using pytest and the [pytest-playwright](https://playwright.dev/python/docs/pytest) plugin.
23+
24+
You can find more information about writing tests in the [pytest documentation](https://docs.pytest.org/en/7.1.x/).
25+
26+
To submit a test, create a new file in the `e2e` directory with a name that describes the test and starts with `test_`.

Diff for: examples/e2e/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

Diff for: examples/e2e/test_playwright_basic.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import pytest
2+
from playwright.sync_api import Playwright, sync_playwright
3+
4+
from browserbase import Browserbase
5+
6+
from .. import (
7+
BROWSERBASE_API_KEY,
8+
playwright_basic,
9+
)
10+
11+
bb = Browserbase(api_key=BROWSERBASE_API_KEY)
12+
13+
14+
@pytest.fixture(scope="session")
15+
def playwright():
16+
with sync_playwright() as p:
17+
yield p
18+
19+
20+
def test_playwright_basic(playwright: Playwright):
21+
playwright_basic.run(playwright)

Diff for: examples/playwright_basic.py

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from playwright.sync_api import Playwright, sync_playwright
2+
3+
from examples import (
4+
BROWSERBASE_API_KEY,
5+
BROWSERBASE_PROJECT_ID,
6+
BROWSERBASE_CONNECT_URL,
7+
bb,
8+
)
9+
10+
11+
def run(playwright: Playwright):
12+
# Create a session on Browserbase
13+
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}"
16+
17+
# Connect to the remote session
18+
connect_url = (
19+
f"{BROWSERBASE_CONNECT_URL}?sessionId={session.id}&apiKey={BROWSERBASE_API_KEY}"
20+
)
21+
chromium = playwright.chromium
22+
browser = chromium.connect_over_cdp(connect_url)
23+
context = browser.contexts[0]
24+
page = context.pages[0]
25+
26+
# Execute Playwright actions on the remote browser tab
27+
page.goto("https://news.ycombinator.com/")
28+
page_title = page.title()
29+
assert (
30+
page_title == "Hacker News"
31+
), f"Page title is not 'Hacker News', it is '{page_title}'"
32+
page.screenshot(path="screenshot.png")
33+
34+
page.close()
35+
browser.close()
36+
print("Done!")
37+
38+
39+
if __name__ == "__main__":
40+
with sync_playwright() as playwright:
41+
run(playwright)

Diff for: pyproject.toml

+8
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,15 @@ dev-dependencies = [
5050
"respx",
5151
"pytest",
5252
"pytest-asyncio",
53+
"pytest-playwright",
5354
"ruff",
5455
"time-machine",
5556
"nox",
5657
"dirty-equals>=0.6.0",
5758
"importlib-metadata>=6.7.0",
5859
"rich>=13.7.1",
60+
"python-dotenv",
61+
"playwright",
5962
]
6063

6164
[tool.rye.scripts]
@@ -79,10 +82,15 @@ format = { chain = [
7982

8083
"check:importable" = "python -c 'import browserbase'"
8184

85+
"example" = "python -c 'import sys; from pathlib import Path; example = Path(\"examples\") / (sys.argv[1] + \".py\"); exec(open(example).read())'"
86+
87+
"test:e2e" = "python -m pytest examples/e2e"
88+
8289
typecheck = { chain = [
8390
"typecheck:pyright",
8491
"typecheck:mypy"
8592
]}
93+
8694
"typecheck:pyright" = "pyright"
8795
"typecheck:verify-types" = "pyright --verifytypes browserbase --ignoreexternal"
8896
"typecheck:mypy" = "mypy ."

Diff for: requirements-dev.lock

+26
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# all-features: true
88
# with-sources: false
99
# generate-hashes: false
10+
# universal: false
1011

1112
-e file:.
1213
annotated-types==0.6.0
@@ -21,6 +22,9 @@ attrs==23.1.0
2122
certifi==2023.7.22
2223
# via httpcore
2324
# via httpx
25+
# via requests
26+
charset-normalizer==3.4.0
27+
# via requests
2428
colorlog==6.7.0
2529
# via nox
2630
dirty-equals==0.6.0
@@ -32,6 +36,8 @@ exceptiongroup==1.1.3
3236
# via anyio
3337
filelock==3.12.4
3438
# via virtualenv
39+
greenlet==3.1.1
40+
# via playwright
3541
h11==0.14.0
3642
# via httpcore
3743
httpcore==1.0.2
@@ -42,6 +48,7 @@ httpx==0.25.2
4248
idna==3.4
4349
# via anyio
4450
# via httpx
51+
# via requests
4552
importlib-metadata==7.0.0
4653
iniconfig==2.0.0
4754
# via pytest
@@ -60,6 +67,8 @@ packaging==23.2
6067
# via pytest
6168
platformdirs==3.11.0
6269
# via virtualenv
70+
playwright==1.48.0
71+
# via pytest-playwright
6372
pluggy==1.3.0
6473
# via pytest
6574
py==1.11.0
@@ -68,16 +77,28 @@ pydantic==2.7.1
6877
# via browserbase
6978
pydantic-core==2.18.2
7079
# via pydantic
80+
pyee==12.0.0
81+
# via playwright
7182
pygments==2.18.0
7283
# via rich
7384
pyright==1.1.380
7485
pytest==7.1.1
7586
# via pytest-asyncio
87+
# via pytest-base-url
88+
# via pytest-playwright
7689
pytest-asyncio==0.21.1
90+
pytest-base-url==2.1.0
91+
# via pytest-playwright
92+
pytest-playwright==0.5.2
7793
python-dateutil==2.8.2
7894
# via time-machine
95+
python-dotenv==1.0.1
96+
python-slugify==8.0.4
97+
# via pytest-playwright
7998
pytz==2023.3.post1
8099
# via dirty-equals
100+
requests==2.32.3
101+
# via pytest-base-url
81102
respx==0.20.2
82103
rich==13.7.1
83104
ruff==0.6.9
@@ -89,6 +110,8 @@ sniffio==1.3.0
89110
# via anyio
90111
# via browserbase
91112
# via httpx
113+
text-unidecode==1.3
114+
# via python-slugify
92115
time-machine==2.9.0
93116
tomli==2.0.1
94117
# via mypy
@@ -99,6 +122,9 @@ typing-extensions==4.8.0
99122
# via mypy
100123
# via pydantic
101124
# via pydantic-core
125+
# via pyee
126+
urllib3==2.2.3
127+
# via requests
102128
virtualenv==20.24.5
103129
# via nox
104130
zipp==3.17.0

Diff for: requirements.lock

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# all-features: true
88
# with-sources: false
99
# generate-hashes: false
10+
# universal: false
1011

1112
-e file:.
1213
annotated-types==0.6.0

0 commit comments

Comments
 (0)