Intelligent web automation powered by Playwright, MCP, and OpenAI LLM
Project description
Browsy Automation
Intelligent web automation powered by Playwright, MCP, and OpenAI LLM
Browsy is a powerful Python library that enables natural language-driven web automation. Simply describe what you want to do, and Browsy handles the browser interaction, navigation, data extraction, and more using AI.
โจ Features
- ๐ค Natural Language Control - Describe tasks in plain English
- ๐ Playwright-Powered - Robust browser automation under the hood
- ๐ง OpenAI Integration - GPT models understand and execute complex tasks
- ๐ก Progress Streaming - Real-time updates via async generators
- ๐ฌ Conversation History - Contextual multi-step automation
- ๐ Fast API Server - Optional REST API with Server-Sent Events
- ๐ฅ๏ธ CLI Tool - Command-line interface for quick tasks
- ๐ง Highly Configurable - Customize models, timeouts, and more
๐ Quick Start
Installation
# Core library
pip install browsy-automation
# With API server support
pip install browsy-automation[api]
# With CLI tool
pip install browsy-automation[cli]
# Everything
pip install browsy-automation[all]
Basic Usage
import asyncio
from browsy import BrowsyEngine
async def main():
# Initialize engine
engine = BrowsyEngine(openai_api_key="sk-...")
await engine.initialize()
# Execute task with progress streaming
async for event in engine.execute("Go to github.com and get trending repos"):
if event.type == "progress":
print(f"{event.progress}%: {event.message}")
elif event.type == "result":
print(f"Result:\n{event.result}")
await engine.cleanup()
asyncio.run(main())
Context Manager (Recommended)
from browsy import BrowsyEngine
async with BrowsyEngine(openai_api_key="sk-...") as engine:
result = await engine.execute_sync("Navigate to example.com and extract the page title")
if result.success:
print(result.result)
CLI Usage
# Execute a task
browsy query "Go to github.com and find the most starred Python repo"
# Start API server
browsy serve --port 5000
# Initialize config
browsy config --init
# Show version
browsy info
๐ Documentation
Configuration
Browsy supports multiple configuration methods:
1. Constructor Arguments
from browsy import BrowsyEngine, BrowsyConfig
engine = BrowsyEngine(
openai_api_key="sk-...",
openai_model="gpt-4o-mini",
playwright_headless=True,
max_tokens=10000,
)
2. Config Object
from browsy import BrowsyConfig, BrowsyEngine
config = BrowsyConfig(
openai_api_key="sk-...",
openai_model="gpt-4o-mini",
playwright_headless=True,
)
engine = BrowsyEngine(config=config)
3. Environment Variables
export BROWSY_OPENAI_API_KEY="sk-..."
export BROWSY_OPENAI_MODEL="gpt-4o-mini"
export BROWSY_PLAYWRIGHT_HEADLESS="true"
from browsy import BrowsyEngine
# Automatically loads from environment
engine = BrowsyEngine()
4. Config File
# ~/.browsy/config.yaml
openai_model: gpt-4o-mini
max_tokens: 10000
playwright_headless: true
use_history: true
log_level: warning
from browsy import BrowsyConfig, BrowsyEngine
config = BrowsyConfig.from_file("~/.browsy/config.yaml")
engine = BrowsyEngine(config=config)
Core API
BrowsyEngine
Main interface for web automation.
Methods:
async initialize()- Initialize MCP agent and browserasync execute(query, session_id=None, use_history=True, max_tokens=10000)- Execute task with progress streamingasync execute_sync(query, ...)- Execute task and wait for completionasync cleanup()- Clean up resourcesget_session(session_id)- Get session informationlist_sessions()- List all sessionsget_stats()- Get usage statistics
Context Manager:
async with BrowsyEngine(openai_api_key="sk-...") as engine:
# Engine automatically initializes and cleans up
result = await engine.execute_sync("Your task here")
Progress Streaming
The execute() method yields events as the task progresses:
async for event in engine.execute("Your task"):
if event.type == "progress":
print(f"Stage: {event.stage}")
print(f"Progress: {event.progress}%")
print(f"Message: {event.message}")
elif event.type == "result":
print(f"Success! Result: {event.result}")
print(f"Elapsed: {event.elapsed}s")
elif event.type == "error":
print(f"Error: {event.message}")
Event Types:
ProgressEvent- Progress update with stage, message, progress %ResultEvent- Final result with data and elapsed timeErrorEvent- Error with message and details
Progress Stages:
initializing- Setting up agentinitialized- Agent readyconnecting- Connecting to browserconnected- Browser readyprocessing- Executing taskcompleting- Generating responsecomplete- Task finished
Session Management
Sessions maintain conversation history for contextual automation:
# Create a session
session = engine.session_manager.create_session()
session_id = session.session_id
# Execute queries in the same session
await engine.execute("Go to github.com", session_id=session_id)
await engine.execute("Find Python repos", session_id=session_id) # Uses previous context
await engine.execute("Click on the first one", session_id=session_id) # Continues conversation
# Get session info
session_info = engine.get_session(session_id)
print(f"Queries: {session_info.query_count}")
# List all sessions
sessions = engine.list_sessions()
# Delete session
engine.delete_session(session_id)
FastAPI Integration
Embed in Existing App
from fastapi import FastAPI
from browsy.api import create_browsy_router
from browsy import BrowsyConfig
app = FastAPI()
# Create Browsy router
config = BrowsyConfig(openai_api_key="sk-...")
browsy_router = create_browsy_router(config)
# Include in your app
app.include_router(browsy_router, prefix="/api/browsy")
# Your other routes...
Standalone Server
from browsy.api import create_app
from browsy import BrowsyConfig
config = BrowsyConfig(openai_api_key="sk-...")
app = create_app(config)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=5000)
API Endpoints:
GET /api/health- Health checkPOST /api/query- Execute query (SSE streaming)POST /api/query/sync- Execute query (synchronous)GET /api/sessions- List sessionsGET /api/sessions/{id}- Get session detailsDELETE /api/sessions/{id}- Delete sessionGET /api/stats- Usage statistics
Example Request:
curl -X POST http://localhost:5000/api/query \
-H "Content-Type: application/json" \
-d '{"query": "Go to example.com and get the page title"}'
๐ฏ Use Cases
Web Scraping
async with BrowsyEngine(openai_api_key="sk-...") as engine:
result = await engine.execute_sync(
"Go to news.ycombinator.com and extract the top 10 post titles"
)
print(result.result)
Form Automation
async with BrowsyEngine(openai_api_key="sk-...") as engine:
await engine.execute_sync(
"Navigate to example.com/contact, "
"fill in name as 'John Doe', "
"email as 'john@example.com', "
"and submit the form"
)
Data Extraction
async with BrowsyEngine(openai_api_key="sk-...") as engine:
result = await engine.execute_sync(
"Go to amazon.com, search for 'iPhone', "
"and extract prices of the first 5 results"
)
print(result.result)
Testing
async with BrowsyEngine(openai_api_key="sk-...") as engine:
result = await engine.execute_sync(
"Go to myapp.com, click login, "
"enter username 'testuser' and password 'testpass', "
"submit, and verify we see 'Welcome testuser'"
)
assert "Welcome testuser" in result.result
๐ ๏ธ Advanced Usage
Custom MCP Configuration
config = BrowsyConfig(
openai_api_key="sk-...",
playwright_command="npx",
playwright_args=["@playwright/mcp@latest", "--headless", "--browser=chromium"],
log_level="debug",
log_path="logs/browsy-{timestamp}.jsonl",
)
engine = BrowsyEngine(config=config)
Statistics and Monitoring
# Get usage stats
stats = engine.get_stats()
print(f"Total queries: {stats['total_queries']}")
print(f"Success rate: {stats['success_rate']}%")
print(f"Avg response time: {stats['avg_response_time']}s")
print(f"Active sessions: {stats['active_sessions']}")
Error Handling
async for event in engine.execute("Your task"):
if event.type == "error":
if "quota" in event.message.lower():
print("OpenAI quota exceeded!")
elif "timeout" in event.message.lower():
print("Task timed out")
else:
print(f"Error: {event.message}")
๐ฆ Package Structure
browsy-automation/
โโโ src/browsy/
โ โโโ __init__.py # Main exports
โ โโโ engine.py # BrowsyEngine core
โ โโโ config.py # Configuration management
โ โโโ types.py # Type definitions
โ โโโ session.py # Session management
โ โโโ api.py # FastAPI integration
โ โโโ cli.py # CLI tool
โโโ examples/ # Usage examples
โโโ tests/ # Unit tests
โโโ pyproject.toml # Package metadata
โโโ README.md # This file
๐ API Key Setup
Get your OpenAI API key from: https://platform.openai.com/api-keys
Important: Keep your API key secure! Use environment variables or config files, not hardcoded values.
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
๐ License
MIT License - see LICENSE file for details
๐ Acknowledgments
- Playwright - Browser automation
- MCP Agent - Model Context Protocol
- OpenAI - Language models
- FastAPI - Web framework
๐ Support
- GitHub Issues: https://github.com/yourusername/browsy-automation/issues
- Documentation: https://github.com/yourusername/browsy-automation#readme
Made with โค๏ธ by the Browsy Team
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file browsy_automation-0.3.2.tar.gz.
File metadata
- Download URL: browsy_automation-0.3.2.tar.gz
- Upload date:
- Size: 29.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d54cd9c38687236a48c114a012d28f25018692dc3ceccca7215ec938cd88261
|
|
| MD5 |
a905d8f6f6bf3c199c0fc515c382fcb1
|
|
| BLAKE2b-256 |
c5c109c7a361b923cb0cc55a79a35439eed52867512bde05f58de4b2b6c5c41d
|
File details
Details for the file browsy_automation-0.3.2-py3-none-any.whl.
File metadata
- Download URL: browsy_automation-0.3.2-py3-none-any.whl
- Upload date:
- Size: 33.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbefec4ec1e1160f4b4c6fae945feffb6cda6de52d5b2ed02d1f840af66dd1b1
|
|
| MD5 |
1a405d62ab6a7e41eab1fc78f0cc9e40
|
|
| BLAKE2b-256 |
eb30c3454b4698b18c96bc02b88cab4440df8fcdb917e99f410b496787acdb44
|