diff --git a/README.md b/README.md index 8bd1f79..3c33f53 100644 --- a/README.md +++ b/README.md @@ -233,6 +233,14 @@ See [`bu_agent_sdk/examples/`](./bu_agent_sdk/examples/) for more: - `claude_code.py` - Full Claude Code clone with sandboxed filesystem - `dependency_injection.py` - FastAPI-style dependency injection +### Browser Use Cloud API (Direct Access) + +See [`examples/direct-api/`](./examples/direct-api/) for examples calling the [Browser Use Cloud API](https://docs.browser-use.com/cloud/api-v3) directly without an SDK: + +- `custom_proxy.sh` - curl/bash script for custom proxy +- `custom_proxy.py` - Python with requests (no SDK) +- `custom_proxy.ts` - TypeScript/Node.js with fetch (no SDK) + ## The Bitter Truth Every abstraction is a liability. Every "helper" is a failure point. diff --git a/examples/direct-api/README.md b/examples/direct-api/README.md new file mode 100644 index 0000000..5873f5b --- /dev/null +++ b/examples/direct-api/README.md @@ -0,0 +1,68 @@ +# Browser Use Cloud API - Direct Access Examples + +Examples for calling the [Browser Use Cloud API](https://docs.browser-use.com/cloud/api-v3) directly without using an SDK. + +## Custom Proxy + +Create browser sessions routed through your own HTTP or SOCKS5 proxy server. Requires a Custom Enterprise plan. + +### Environment Variables + +All examples use these environment variables: + +| Variable | Required | Description | +|----------|----------|-------------| +| `BROWSER_USE_API_KEY` | Yes | Your Browser Use API key | +| `PROXY_HOST` | Yes | Proxy server hostname | +| `PROXY_PORT` | Yes | Proxy server port | +| `PROXY_USERNAME` | No | Proxy authentication username | +| `PROXY_PASSWORD` | No | Proxy authentication password | + +### curl / Bash + +```bash +export BROWSER_USE_API_KEY="your-api-key" +export PROXY_HOST="proxy.example.com" +export PROXY_PORT="8080" +./custom_proxy.sh +``` + +### Python (requests) + +```bash +pip install requests +export BROWSER_USE_API_KEY="your-api-key" +export PROXY_HOST="proxy.example.com" +export PROXY_PORT="8080" +python custom_proxy.py +``` + +### TypeScript / Node.js + +```bash +export BROWSER_USE_API_KEY="your-api-key" +export PROXY_HOST="proxy.example.com" +export PROXY_PORT="8080" +npx tsx custom_proxy.ts +``` + +## API Reference + +- [Create Browser Session](https://docs.browser-use.com/cloud/api-v3/browsers/create-browser-session) +- [Custom Proxy Documentation](https://docs.browser-use.com/cloud/browser/proxies#custom-proxy) + +## Response + +All examples return: + +```json +{ + "id": "session-uuid", + "status": "active", + "cdpUrl": "wss://...", + "liveUrl": "https://..." +} +``` + +- **cdpUrl**: Chrome DevTools Protocol URL for connecting Playwright, Puppeteer, or any CDP client +- **liveUrl**: URL to view the browser session in real-time diff --git a/examples/direct-api/custom_proxy.py b/examples/direct-api/custom_proxy.py new file mode 100644 index 0000000..c908bc0 --- /dev/null +++ b/examples/direct-api/custom_proxy.py @@ -0,0 +1,98 @@ +""" +Browser Use Cloud API - Custom Proxy Example +Direct API access using requests (no SDK required) + +This example shows how to create a browser session with a custom proxy +using the Browser Use Cloud API directly. + +Usage: + export BROWSER_USE_API_KEY="your-api-key" + export PROXY_HOST="proxy.example.com" + export PROXY_PORT="8080" + export PROXY_USERNAME="user" # optional + export PROXY_PASSWORD="pass" # optional + python custom_proxy.py +""" + +import os +import requests + +API_BASE = "https://api.browser-use.com/api/v3" + + +def create_browser_with_custom_proxy( + host: str, + port: int, + username: str | None = None, + password: str | None = None, + timeout_minutes: int = 60, +) -> dict: + """Create a browser session routed through a custom proxy.""" + api_key = os.environ.get("BROWSER_USE_API_KEY") + if not api_key: + raise ValueError("BROWSER_USE_API_KEY environment variable is required") + + custom_proxy = {"host": host, "port": port} + if username and password: + custom_proxy["username"] = username + custom_proxy["password"] = password + + response = requests.post( + f"{API_BASE}/browsers", + headers={ + "Content-Type": "application/json", + "X-Browser-Use-API-Key": api_key, + }, + json={ + "customProxy": custom_proxy, + "timeout": timeout_minutes, + }, + ) + response.raise_for_status() + return response.json() + + +def stop_browser(session_id: str) -> None: + """Stop a browser session.""" + api_key = os.environ.get("BROWSER_USE_API_KEY") + requests.post( + f"{API_BASE}/browsers/{session_id}/stop", + headers={"X-Browser-Use-API-Key": api_key}, + ) + + +def main(): + host = os.environ.get("PROXY_HOST") + port = os.environ.get("PROXY_PORT") + username = os.environ.get("PROXY_USERNAME") + password = os.environ.get("PROXY_PASSWORD") + + if not host or not port: + raise ValueError("PROXY_HOST and PROXY_PORT environment variables are required") + + print(f"Creating browser session with custom proxy {host}:{port}...") + + session = create_browser_with_custom_proxy( + host=host, + port=int(port), + username=username, + password=password, + ) + + print(f"Session ID: {session['id']}") + print(f"CDP URL: {session['cdpUrl']}") + print(f"Live URL: {session['liveUrl']}") + print() + print("Use the CDP URL to connect with Playwright, Puppeteer, or any CDP client.") + print("Use the Live URL to view the browser in real-time.") + + # Example: Connect with Playwright + # from playwright.sync_api import sync_playwright + # with sync_playwright() as p: + # browser = p.chromium.connect_over_cdp(session['cdpUrl']) + # page = browser.new_page() + # page.goto("https://example.com") + + +if __name__ == "__main__": + main() diff --git a/examples/direct-api/custom_proxy.sh b/examples/direct-api/custom_proxy.sh new file mode 100755 index 0000000..14cb59e --- /dev/null +++ b/examples/direct-api/custom_proxy.sh @@ -0,0 +1,96 @@ +#!/bin/bash +# Browser Use Cloud API - Custom Proxy Example +# Direct API access using curl (no SDK required) +# +# This example shows how to create a browser session with a custom proxy +# using the Browser Use Cloud API directly. +# +# Requirements: +# - curl +# - jq (optional, for JSON parsing) +# +# Usage: +# export BROWSER_USE_API_KEY="your-api-key" +# export PROXY_HOST="proxy.example.com" +# export PROXY_PORT="8080" +# export PROXY_USERNAME="user" # optional +# export PROXY_PASSWORD="pass" # optional +# ./custom_proxy.sh + +set -e + +API_BASE="https://api.browser-use.com/api/v3" + +: "${BROWSER_USE_API_KEY:?Error: BROWSER_USE_API_KEY environment variable is required}" +: "${PROXY_HOST:?Error: PROXY_HOST environment variable is required}" +: "${PROXY_PORT:?Error: PROXY_PORT environment variable is required}" + +# Build the custom proxy JSON +if [ -n "$PROXY_USERNAME" ] && [ -n "$PROXY_PASSWORD" ]; then + CUSTOM_PROXY=$(cat </dev/null || echo "$RESPONSE" + exit 1 +fi + +# Extract session info +SESSION_ID=$(echo "$RESPONSE" | jq -r '.id' 2>/dev/null) +CDP_URL=$(echo "$RESPONSE" | jq -r '.cdpUrl' 2>/dev/null) +LIVE_URL=$(echo "$RESPONSE" | jq -r '.liveUrl' 2>/dev/null) + +echo "" +echo "Session created successfully!" +echo "Session ID: $SESSION_ID" +echo "CDP URL: $CDP_URL" +echo "Live URL: $LIVE_URL" +echo "" +echo "Use the CDP URL to connect with Playwright, Puppeteer, or any CDP client." +echo "Use the Live URL to view the browser in real-time." + +# Stop the session (cleanup) +stop_session() { + echo "" + echo "Stopping session $SESSION_ID..." + curl -s -X POST "$API_BASE/browsers/$SESSION_ID/stop" \ + -H "X-Browser-Use-API-Key: $BROWSER_USE_API_KEY" + echo "Session stopped." +} + +# Uncomment to auto-stop on script exit: +# trap stop_session EXIT diff --git a/examples/direct-api/custom_proxy.ts b/examples/direct-api/custom_proxy.ts new file mode 100644 index 0000000..d5a4efc --- /dev/null +++ b/examples/direct-api/custom_proxy.ts @@ -0,0 +1,115 @@ +/** + * Browser Use Cloud API - Custom Proxy Example + * Direct API access using fetch (no SDK required) + * + * This example shows how to create a browser session with a custom proxy + * using the Browser Use Cloud API directly. + * + * Usage: + * export BROWSER_USE_API_KEY="your-api-key" + * export PROXY_HOST="proxy.example.com" + * export PROXY_PORT="8080" + * export PROXY_USERNAME="user" // optional + * export PROXY_PASSWORD="pass" // optional + * npx tsx custom_proxy.ts + */ + +const API_BASE = "https://api.browser-use.com/api/v3"; + +interface CustomProxy { + host: string; + port: number; + username?: string; + password?: string; +} + +interface BrowserSession { + id: string; + status: "active" | "stopped"; + cdpUrl: string | null; + liveUrl: string | null; + timeoutAt: string; + startedAt: string; +} + +async function createBrowserWithCustomProxy( + proxy: CustomProxy, + timeoutMinutes: number = 60 +): Promise { + const apiKey = process.env.BROWSER_USE_API_KEY; + if (!apiKey) { + throw new Error("BROWSER_USE_API_KEY environment variable is required"); + } + + const response = await fetch(`${API_BASE}/browsers`, { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-Browser-Use-API-Key": apiKey, + }, + body: JSON.stringify({ + customProxy: proxy, + timeout: timeoutMinutes, + }), + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(`API error: ${JSON.stringify(error)}`); + } + + return response.json(); +} + +async function stopBrowser(sessionId: string): Promise { + const apiKey = process.env.BROWSER_USE_API_KEY; + await fetch(`${API_BASE}/browsers/${sessionId}/stop`, { + method: "POST", + headers: { + "X-Browser-Use-API-Key": apiKey!, + }, + }); +} + +async function main() { + const host = process.env.PROXY_HOST; + const port = process.env.PROXY_PORT; + const username = process.env.PROXY_USERNAME; + const password = process.env.PROXY_PASSWORD; + + if (!host || !port) { + throw new Error( + "PROXY_HOST and PROXY_PORT environment variables are required" + ); + } + + console.log(`Creating browser session with custom proxy ${host}:${port}...`); + + const proxy: CustomProxy = { + host, + port: parseInt(port, 10), + }; + if (username && password) { + proxy.username = username; + proxy.password = password; + } + + const session = await createBrowserWithCustomProxy(proxy); + + console.log(`Session ID: ${session.id}`); + console.log(`CDP URL: ${session.cdpUrl}`); + console.log(`Live URL: ${session.liveUrl}`); + console.log(); + console.log( + "Use the CDP URL to connect with Playwright, Puppeteer, or any CDP client." + ); + console.log("Use the Live URL to view the browser in real-time."); + + // Example: Connect with Puppeteer + // import puppeteer from 'puppeteer-core'; + // const browser = await puppeteer.connect({ browserWSEndpoint: session.cdpUrl! }); + // const page = await browser.newPage(); + // await page.goto('https://example.com'); +} + +main().catch(console.error);