Skip to content

Commit e3dc9c3

Browse files
authored
Advanced samples (#16)
- Moves persisted browser sample to sample-app - also just creates a persisted browser (I find I often need one for manual testing) - advanced-samples actions: example CAPTCHA solver
1 parent 4a661d7 commit e3dc9c3

File tree

23 files changed

+334
-262
lines changed

23 files changed

+334
-262
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ create-kernel-app [app-name] [options]
3838
- `sample-app`: Basic template with Playwright integration
3939
- `browser-use`: Template with Browser Use SDK (Python only)
4040
- `stagehand`: Template with Stagehand SDK (Typescript only)
41-
- `persistent-browser`: Implements `sample-app` using a persistent browser
41+
- `advanced-sample`: Implements sample apps using advanced Kernel configs
4242
- `computer-use`: Implements a prompt loop using Anthropic Computer Use
4343

4444
### Examples
@@ -125,7 +125,7 @@ These are the sample apps currently available when you run `npx @onkernel/create
125125
| **sample-app** | Returns the page title of a specified URL | Playwright | `{ url }` |
126126
| **browser-use** | Completes a specified task | Browser Use | `{ task }` |
127127
| **stagehand** | Returns the first result of a specified Google search | Stagehand | `{ query }` |
128-
| **persistent-browser** | Implements `sample-app` using a persistent browser | Playwright | `{ url }` |
128+
| **advanced-sample** | Implements sample apps using advanced Kernel configs | n/a |
129129
| **computer-use** | Implements a prompt loop | Anthropic Computer Use API | `{ query }` |
130130

131131
## Documentation

index.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type TemplateKey =
1717
| "sample-app"
1818
| "browser-use"
1919
| "stagehand"
20-
| "persistent-browser"
20+
| "advanced-sample"
2121
| "computer-use";
2222
type LanguageInfo = { name: string; shorthand: string };
2323
type TemplateInfo = {
@@ -32,7 +32,7 @@ const LANGUAGE_PYTHON = "python";
3232
const TEMPLATE_SAMPLE_APP = "sample-app";
3333
const TEMPLATE_BROWSER_USE = "browser-use";
3434
const TEMPLATE_STAGEHAND = "stagehand";
35-
const TEMPLATE_PERSISTENT_BROWSER = "persistent-browser";
35+
const TEMPLATE_ADVANCED_SAMPLE = "advanced-sample";
3636
const TEMPLATE_COMPUTER_USE = "computer-use";
3737
const LANGUAGE_SHORTHAND_TS = "ts";
3838
const LANGUAGE_SHORTHAND_PY = "py";
@@ -62,10 +62,10 @@ const TEMPLATES: Record<TemplateKey, TemplateInfo> = {
6262
description: "Implements the Stagehand SDK",
6363
languages: [LANGUAGE_TYPESCRIPT],
6464
},
65-
[TEMPLATE_PERSISTENT_BROWSER]: {
66-
name: "Persistent Browser",
65+
[TEMPLATE_ADVANCED_SAMPLE]: {
66+
name: "Advanced Samples",
6767
description:
68-
"Implements a persistent browser that maintains state across invocations",
68+
"Implements sample actions with advanced Kernel configs",
6969
languages: [LANGUAGE_TYPESCRIPT, LANGUAGE_PYTHON],
7070
},
7171
[TEMPLATE_COMPUTER_USE]: {
@@ -84,8 +84,8 @@ const INVOKE_SAMPLES: Record<
8484
'kernel invoke ts-basic get-page-title --payload \'{"url": "https://www.google.com"}\'',
8585
[TEMPLATE_STAGEHAND]:
8686
'kernel invoke ts-stagehand stagehand-task --payload \'{"query": "Best wired earbuds"}\'',
87-
[TEMPLATE_PERSISTENT_BROWSER]:
88-
'kernel invoke ts-persistent-browser persistent-browser-task --payload \'{"url": "https://news.ycombinator.com/"}\'',
87+
[TEMPLATE_ADVANCED_SAMPLE]:
88+
'kernel invoke ts-advanced test-captcha-solver',
8989
[TEMPLATE_COMPUTER_USE]:
9090
'kernel invoke ts-cu cu-task --payload \'{"query": "Return the first url of a search result for NYC restaurant reviews Pete Wells"}\'',
9191
},
@@ -94,8 +94,8 @@ const INVOKE_SAMPLES: Record<
9494
'kernel invoke python-basic get-page-title --payload \'{"url": "https://www.google.com"}\'',
9595
[TEMPLATE_BROWSER_USE]:
9696
'kernel invoke python-bu bu-task --payload \'{"task": "Compare the price of gpt-4o and DeepSeek-V3"}\'',
97-
[TEMPLATE_PERSISTENT_BROWSER]:
98-
'kernel invoke python-persistent-browser persistent-browser-task --payload \'{"url": "https://news.ycombinator.com/"}\'',
97+
[TEMPLATE_ADVANCED_SAMPLE]:
98+
'kernel invoke python-advanced test-captcha-solver',
9999
[TEMPLATE_COMPUTER_USE]:
100100
'kernel invoke python-cu cu-task --payload \'{"query": "Return the first url of a search result for NYC restaurant reviews Pete Wells"}\'',
101101
},
@@ -110,8 +110,8 @@ const REGISTERED_APP_NAMES: Record<
110110
'ts-basic',
111111
[TEMPLATE_STAGEHAND]:
112112
'ts-stagehand',
113-
[TEMPLATE_PERSISTENT_BROWSER]:
114-
'ts-persistent-browser',
113+
[TEMPLATE_ADVANCED_SAMPLE]:
114+
'ts-advanced',
115115
[TEMPLATE_COMPUTER_USE]:
116116
'ts-cu',
117117
},
@@ -120,8 +120,8 @@ const REGISTERED_APP_NAMES: Record<
120120
'python-basic',
121121
[TEMPLATE_BROWSER_USE]:
122122
'python-bu',
123-
[TEMPLATE_PERSISTENT_BROWSER]:
124-
'python-persistent-browser',
123+
[TEMPLATE_ADVANCED_SAMPLE]:
124+
'python-advanced',
125125
[TEMPLATE_COMPUTER_USE]:
126126
'python-cu',
127127
},
@@ -336,13 +336,13 @@ function printNextSteps(
336336
): void {
337337
// Determine which sample command to show based on language and template
338338
const deployCommand =
339-
language === LANGUAGE_TYPESCRIPT && (template === TEMPLATE_SAMPLE_APP || template === TEMPLATE_PERSISTENT_BROWSER)
339+
language === LANGUAGE_TYPESCRIPT && (template === TEMPLATE_SAMPLE_APP || template === TEMPLATE_ADVANCED_SAMPLE)
340340
? "kernel deploy index.ts"
341341
: language === LANGUAGE_TYPESCRIPT && template === TEMPLATE_STAGEHAND
342342
? "kernel deploy index.ts --env OPENAI_API_KEY=XXX"
343343
: language === LANGUAGE_TYPESCRIPT && template === TEMPLATE_COMPUTER_USE
344344
? "kernel deploy index.ts --env ANTHROPIC_API_KEY=XXX"
345-
: language === LANGUAGE_PYTHON && template === TEMPLATE_SAMPLE_APP
345+
: language === LANGUAGE_PYTHON && (template === TEMPLATE_SAMPLE_APP || template === TEMPLATE_ADVANCED_SAMPLE)
346346
? "kernel deploy main.py"
347347
: language === LANGUAGE_PYTHON && template === TEMPLATE_BROWSER_USE
348348
? "kernel deploy main.py --env OPENAI_API_KEY=XXX"
@@ -384,7 +384,7 @@ program
384384
)
385385
.option(
386386
"-t, --template <template>",
387-
`Template type (${TEMPLATE_SAMPLE_APP}, ${TEMPLATE_BROWSER_USE}, ${TEMPLATE_STAGEHAND}, ${TEMPLATE_PERSISTENT_BROWSER}, ${TEMPLATE_COMPUTER_USE})`
387+
`Template type (${TEMPLATE_SAMPLE_APP}, ${TEMPLATE_BROWSER_USE}, ${TEMPLATE_STAGEHAND}, ${TEMPLATE_ADVANCED_SAMPLE}, ${TEMPLATE_COMPUTER_USE})`
388388
)
389389
.action(
390390
async (
File renamed without changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Kernel Python Advanced Sample App
2+
3+
This is a collection of Kernel actions that demonstrate how to use the Kernel SDK.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import kernel
2+
from kernel import Kernel
3+
from playwright.async_api import async_playwright
4+
5+
client = Kernel()
6+
app = kernel.App("python-advanced")
7+
8+
"""
9+
Example showing Kernel's auto-CAPTCHA solver.
10+
Visit the live view url to see the Kernel browser auto-solve the CAPTCHA on the site.
11+
12+
Args:
13+
ctx: Kernel context containing invocation information
14+
Returns:
15+
None
16+
17+
Invoke this via CLI:
18+
export KERNEL_API_KEY=<your_api_key>
19+
kernel deploy main.py # If you haven't already deployed this app
20+
kernel invoke py-advanced test_captcha_solver
21+
kernel logs py-advanced -f # Open in separate tab
22+
"""
23+
@app.action("test-captcha-solver")
24+
async def test_captcha_solver(ctx: kernel.KernelContext) -> None:
25+
kernel_browser = client.browsers.create(
26+
invocation_id=ctx.invocation_id,
27+
stealth=True,
28+
persistence={"id": "captcha-solver"}
29+
)
30+
31+
async with async_playwright() as playwright:
32+
browser = await playwright.chromium.connect_over_cdp(kernel_browser.cdp_ws_url)
33+
34+
# Get or create context and page
35+
contexts = browser.contexts
36+
context = contexts[0] if contexts else await browser.new_context()
37+
pages = context.pages
38+
page = pages[0] if pages else await context.new_page()
39+
40+
# Access the live view. Retrieve this live_view_url from the Kernel logs in your CLI:
41+
# export KERNEL_API_KEY=<Your API key>
42+
# kernel logs py-advanced --follow
43+
print("Kernel browser live view url: ", kernel_browser.browser_live_view_url)
44+
45+
# Navigate to a site with a CAPTCHA
46+
try:
47+
await page.wait_for_timeout(10000) # Add a delay to give you time to visit the live view url
48+
await page.goto("https://www.google.com/recaptcha/api2/demo")
49+
except Exception as e:
50+
print(f"Error during navigation: {e}")
51+
raise
52+
# Watch Kernel auto-solve the CAPTCHA!
53+
await browser.close()
54+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[project]
2+
name = "kernel-python-advanced"
3+
version = "0.1.0"
4+
description = "Sample application implementing advanced Kernel configs"
5+
readme = "README.md"
6+
requires-python = ">=3.11"
7+
dependencies = [
8+
"kernel>=0.5.0",
9+
"playwright>=1.52.0"
10+
]
11+
12+
[dependency-groups]
13+
dev = ["mypy>=1.15.0"]

templates/python/persistent-browser/uv.lock renamed to templates/python/advanced-sample/uv.lock

Lines changed: 33 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

templates/python/persistent-browser/README.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

templates/python/persistent-browser/main.py

Lines changed: 0 additions & 77 deletions
This file was deleted.

0 commit comments

Comments
 (0)