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
Metadata
Release files for browsy-automation 0.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| browsy_automation-0.3.2.tar.gz | 29.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| browsy_automation-0.3.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.9 kB
Release files / browsy_automation-0.3.2.tar.gz
| Download URL | browsy_automation-0.3.2.tar.gz |
|---|---|
| Size | 29.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3d54cd9c38687236a48c114a012d28f25018692dc3ceccca7215ec938cd88261
|
|
BLAKE2b-256 checksum How to use checksums |
c5c109c7a361b923cb0cc55a79a35439eed52867512bde05f58de4b2b6c5c41d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / browsy_automation-0.3.2-py3-none-any.whl
| Download URL | browsy_automation-0.3.2-py3-none-any.whl |
|---|---|
| Size | 33.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dbefec4ec1e1160f4b4c6fae945feffb6cda6de52d5b2ed02d1f840af66dd1b1
|
|
BLAKE2b-256 checksum How to use checksums |
eb30c3454b4698b18c96bc02b88cab4440df8fcdb917e99f410b496787acdb44
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|