Skip to content

Commit 44e3773

Browse files
committed
docs: Add app preview example section
1 parent 37b5c49 commit 44e3773

2 files changed

Lines changed: 289 additions & 0 deletions

File tree

docs.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@
5050
"docs/use-cases/ci-cd"
5151
]
5252
},
53+
{
54+
"group": "Examples",
55+
"pages": [
56+
"docs/examples/app-preview"
57+
]
58+
},
5359
{
5460
"group": "Agents in sandbox",
5561
"pages": [

docs/examples/app-preview.mdx

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
---
2+
title: "App preview with Kernel"
3+
description: "Deploy a web app in an E2B sandbox and use a Kernel cloud browser to screenshot every route and generate a preview report."
4+
icon: "camera"
5+
---
6+
7+
Deploy a web application inside an E2B sandbox, get a public URL, then use a [Kernel](https://www.kernel.computer/) cloud browser to visit every route, capture screenshots, and produce a structured preview report — all without running a browser locally.
8+
9+
## Architecture
10+
11+
This example combines two services:
12+
13+
1. **E2B Sandbox** — a secure cloud environment where the web app runs. E2B exposes the app at a public HTTPS URL via `sandbox.get_host(port)`.
14+
2. **Kernel Cloud Browser** — a remote Chromium instance controlled through Playwright's CDP protocol. It navigates the public URL, takes screenshots, and collects page metadata.
15+
16+
The orchestrator script on your machine creates the sandbox, deploys the app, and then runs a browsing script _inside_ the sandbox that connects to a Kernel browser and screenshots each route.
17+
18+
## Prerequisites
19+
20+
- An [E2B API key](https://e2b.dev/dashboard?tab=keys)
21+
- A [Kernel API key](https://www.kernel.computer/)
22+
- Python 3.10+
23+
24+
```bash
25+
pip install e2b-code-interpreter
26+
```
27+
28+
Set both keys in your environment:
29+
30+
```bash .env
31+
E2B_API_KEY=e2b_***
32+
KERNEL_API_KEY=kernel_***
33+
```
34+
35+
## How it works
36+
37+
<Steps>
38+
<Step title="Create the sandbox">
39+
Start an E2B sandbox using the `kernel-browser` template, which comes with the Kernel SDK and Playwright client pre-installed. No local browser binary is needed — Kernel provides the browser remotely.
40+
41+
```python
42+
from e2b_code_interpreter import Sandbox
43+
44+
sandbox = Sandbox.create(
45+
"kernel-browser",
46+
envs={"KERNEL_API_KEY": os.environ["KERNEL_API_KEY"]},
47+
timeout=300,
48+
)
49+
```
50+
</Step>
51+
52+
<Step title="Deploy the web app">
53+
Write a FastAPI application into the sandbox and start it as a background process on port 8000.
54+
55+
```python
56+
sandbox.files.write("/home/user/app.py", FASTAPI_APP)
57+
sandbox.commands.run(
58+
"pip install --break-system-packages fastapi uvicorn",
59+
timeout=60,
60+
)
61+
sandbox.commands.run(
62+
"uvicorn app:app --host 0.0.0.0 --port 8000",
63+
background=True,
64+
cwd="/home/user",
65+
)
66+
```
67+
</Step>
68+
69+
<Step title="Get the public URL">
70+
E2B exposes any sandbox port as a public HTTPS endpoint.
71+
72+
```python
73+
host = sandbox.get_host(8000)
74+
app_url = f"https://{host}"
75+
```
76+
</Step>
77+
78+
<Step title="Browse with Kernel">
79+
A script running inside the sandbox creates a Kernel cloud browser, connects via Playwright CDP, and visits each route to take screenshots.
80+
81+
```python
82+
from kernel import Kernel
83+
from playwright.sync_api import sync_playwright
84+
85+
kernel = Kernel()
86+
kb = kernel.browsers.create()
87+
88+
with sync_playwright() as pw:
89+
browser = pw.chromium.connect_over_cdp(kb.cdp_ws_url)
90+
page = browser.new_page()
91+
page.set_viewport_size({"width": 1280, "height": 720})
92+
93+
page.goto(app_url, wait_until="networkidle")
94+
page.screenshot(path="/home/user/screenshots/home.png")
95+
```
96+
</Step>
97+
98+
<Step title="Generate the preview report">
99+
After visiting every route, the script writes a JSON report with page titles and screenshot paths. The orchestrator reads it back from the sandbox.
100+
101+
```python
102+
import json
103+
104+
report = json.loads(
105+
sandbox.files.read("/home/user/preview_report.json")
106+
)
107+
for entry in report:
108+
print(f"Route: {entry['route']} — Title: {entry['title']}")
109+
```
110+
</Step>
111+
</Steps>
112+
113+
## Full example
114+
115+
```python app_preview.py
116+
"""
117+
App Preview — E2B + Kernel
118+
119+
Spins up a web app inside an E2B sandbox, exposes it at a public URL,
120+
then uses a Kernel cloud browser to navigate the app, take screenshots
121+
of each route, and generate a visual preview report.
122+
"""
123+
124+
import os
125+
import time
126+
import json
127+
128+
from e2b_code_interpreter import Sandbox
129+
130+
# A sample FastAPI app to deploy inside the sandbox
131+
FASTAPI_APP = '''
132+
from fastapi import FastAPI
133+
from fastapi.responses import HTMLResponse
134+
135+
app = FastAPI()
136+
137+
@app.get("/", response_class=HTMLResponse)
138+
def home():
139+
return """
140+
<!DOCTYPE html>
141+
<html>
142+
<head><title>My App</title></head>
143+
<body><h1>Welcome to My App</h1></body>
144+
</html>
145+
"""
146+
147+
@app.get("/about", response_class=HTMLResponse)
148+
def about():
149+
return """
150+
<!DOCTYPE html>
151+
<html>
152+
<head><title>About</title></head>
153+
<body><h1>About</h1><p>E2B + Kernel integration demo.</p></body>
154+
</html>
155+
"""
156+
157+
@app.get("/api/status")
158+
def status():
159+
return {"status": "ok", "sandbox": "e2b", "browser": "kernel"}
160+
'''
161+
162+
# Script that runs inside the sandbox to browse the app with Kernel
163+
BROWSE_SCRIPT = '''
164+
import sys
165+
import json
166+
from kernel import Kernel
167+
from playwright.sync_api import sync_playwright
168+
169+
app_url = sys.argv[1]
170+
routes = ["/", "/about"]
171+
172+
kernel = Kernel()
173+
kb = kernel.browsers.create()
174+
175+
results = []
176+
177+
with sync_playwright() as pw:
178+
browser = pw.chromium.connect_over_cdp(kb.cdp_ws_url)
179+
page = browser.new_page()
180+
page.set_viewport_size({"width": 1280, "height": 720})
181+
182+
for route in routes:
183+
url = f"{app_url}{route}"
184+
page.goto(url, wait_until="networkidle", timeout=15000)
185+
186+
# Take screenshot
187+
safe_name = route.strip("/").replace("/", "_") or "home"
188+
screenshot_path = f"/home/user/screenshots/{safe_name}.png"
189+
page.screenshot(path=screenshot_path)
190+
191+
# Collect page info
192+
results.append({
193+
"route": route,
194+
"title": page.title(),
195+
"screenshot": screenshot_path,
196+
})
197+
198+
browser.close()
199+
200+
with open("/home/user/preview_report.json", "w") as f:
201+
json.dump(results, f)
202+
'''
203+
204+
205+
def main():
206+
sandbox = Sandbox.create(
207+
"kernel-browser",
208+
envs={"KERNEL_API_KEY": os.environ["KERNEL_API_KEY"]},
209+
timeout=300,
210+
)
211+
212+
try:
213+
# Deploy and start the FastAPI app
214+
sandbox.files.write("/home/user/app.py", FASTAPI_APP)
215+
sandbox.commands.run("mkdir -p /home/user/screenshots", timeout=5)
216+
sandbox.commands.run(
217+
"pip install --break-system-packages fastapi uvicorn",
218+
timeout=60,
219+
)
220+
sandbox.commands.run(
221+
"uvicorn app:app --host 0.0.0.0 --port 8000",
222+
background=True,
223+
cwd="/home/user",
224+
)
225+
time.sleep(3)
226+
227+
# Get the public URL
228+
host = sandbox.get_host(8000)
229+
app_url = f"https://{host}"
230+
print(f"App is live at: {app_url}")
231+
232+
# Use Kernel browser to preview the app
233+
sandbox.files.write("/home/user/browse.py", BROWSE_SCRIPT)
234+
result = sandbox.commands.run(
235+
f'python3 /home/user/browse.py "{app_url}"',
236+
timeout=120,
237+
)
238+
239+
# Read the preview report
240+
report = json.loads(
241+
sandbox.files.read("/home/user/preview_report.json")
242+
)
243+
for entry in report:
244+
print(f"Route: {entry['route']} — Title: {entry['title']}")
245+
246+
finally:
247+
sandbox.kill()
248+
249+
250+
if __name__ == "__main__":
251+
main()
252+
```
253+
254+
## Key concepts
255+
256+
| Concept | Detail |
257+
|---|---|
258+
| **E2B template** | `kernel-browser` — pre-built with the Kernel SDK and Playwright client |
259+
| **Public URL** | `sandbox.get_host(port)` returns an HTTPS hostname |
260+
| **Background process** | `sandbox.commands.run(..., background=True)` starts the web server without blocking |
261+
| **Kernel browser** | `kernel.browsers.create()` spins up a remote Chromium; connect via `kb.cdp_ws_url` |
262+
| **CDP connection** | Playwright's `connect_over_cdp()` drives the remote browser with full API access |
263+
264+
## Adapting this example
265+
266+
- **Your own app** — replace `FASTAPI_APP` with any web framework (Next.js, Flask, Express). Adjust the install commands and start script accordingly.
267+
- **More routes** — add paths to the `routes` list in `BROWSE_SCRIPT` to screenshot additional pages.
268+
- **Visual regression** — compare screenshots across deploys to catch UI regressions automatically.
269+
- **CI integration** — run this as a post-deploy step to generate preview links and thumbnails for pull requests.
270+
271+
## Related guides
272+
273+
<CardGroup cols={3}>
274+
<Card title="Sandbox lifecycle" icon="rotate" href="/docs/sandbox">
275+
Create, manage, and control sandbox lifecycle
276+
</Card>
277+
<Card title="Running commands" icon="terminal" href="/docs/commands">
278+
Run terminal commands inside the sandbox
279+
</Card>
280+
<Card title="Computer use" icon="desktop" href="/docs/use-cases/computer-use">
281+
Build AI agents that control virtual desktops
282+
</Card>
283+
</CardGroup>

0 commit comments

Comments
 (0)