simoncck's picture
Update app.py
8ed40a8 verified
from flask import Flask, request, jsonify, send_from_directory
from flask_cors import CORS
import asyncio
import os
import sys
from threading import Thread
import json
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Import browser-use components and LLM libraries
try:
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from langchain_google_genai import ChatGoogleGenerativeAI
from browser_use import Agent
except ImportError as e:
print(f"Import error: {e}")
print("Make sure to install browser-use, langchain-openai, langchain-anthropic, and langchain-google-genai")
app = Flask(__name__, static_folder="static")
CORS(app) # Enable CORS for all routes
# Global variables for managing async operations
loop = None
thread = None
def start_background_loop(loop):
"""Start the asyncio event loop in a background thread"""
asyncio.set_event_loop(loop)
loop.run_forever()
def get_or_create_eventloop():
"""Get or create the asyncio event loop"""
global loop, thread
if loop is None:
loop = asyncio.new_event_loop()
thread = Thread(target=start_background_loop, args=(loop,))
thread.daemon = True
thread.start()
return loop
async def run_browser_task(task, model="gpt-4o-mini"):
"""Run a browser automation task using browser-use"""
try:
# Initialize the LLM based on the model name
if model.startswith("gpt"):
llm = ChatOpenAI(model=model, temperature=0.1)
elif model.startswith("claude"):
llm = ChatAnthropic(model=model, temperature=0.1)
elif model.startswith("gemini"):
llm = ChatGoogleGenerativeAI(model=model, temperature=0.1)
else:
raise ValueError(f"Unsupported model: {model}")
# Create the agent
agent = Agent(task=task, llm=llm)
# Run the task
result = await agent.run()
return {
"success": True,
"result": str(result),
"task": task
}
except Exception as e:
return {
"success": False,
"error": str(e),
"task": task
}
@app.route("/")
def home():
"""Serve the HTML interface"""
return send_from_directory("static", "index.html")
@app.route("/api")
def api_docs():
"""API documentation endpoint"""
return jsonify({
"message": "Browser-Use Server API",
"endpoints": {
"/": "Web interface",
"/api": "This API documentation",
"/health": "Health check",
"/run-task": "POST - Run a browser automation task",
"/status": "Get server status"
},
"usage": {
"run_task": {
"method": "POST",
"url": "/run-task",
"body": {
"task": "Description of the task to perform",
"model": "gpt-4o-mini (optional, default)"
},
"example": {
"task": "Go to google.com and search for 'Python programming'",
"model": "gpt-4o-mini"
}
}
}
})
@app.route("/health")
def health():
"""Health check endpoint"""
return jsonify({
"status": "healthy",
"service": "browser-use-server",
"version": "1.0.0"
})
@app.route("/status")
def status():
"""Get server status and configuration"""
return jsonify({
"status": "running",
"environment": {
"python_version": sys.version,
"has_openai_key": bool(os.getenv("OPENAI_API_KEY")),
"has_anthropic_key": bool(os.getenv("ANTHROPIC_API_KEY")),
"has_google_api_key": bool(os.getenv("GOOGLE_API_KEY"))
},
"supported_models": [
"gpt-4o",
"gpt-4o-mini",
"gpt-4-turbo",
"claude-3-sonnet-20240229",
"claude-3-haiku-20240307",
"gemini-2.0-flash",
"gemini-2.5-flash",
"gemini-2.0-flash-exp",
"gemini-2.0-flash-lite"
]
})
@app.route("/run-task", methods=["POST"])
def run_task():
"""Run a browser automation task"""
try:
# Get request data
data = request.get_json()
if not data or "task" not in data:
return jsonify({
"success": False,
"error": "Missing 'task' in request body"
}), 400
task = data["task"]
model = data.get("model", "gpt-4o-mini")
# Validate API keys
if not os.getenv("OPENAI_API_KEY") and not os.getenv("ANTHROPIC_API_KEY") and not os.getenv("GOOGLE_API_KEY"):
return jsonify({
"success": False,
"error": "No API keys configured. Please set OPENAI_API_KEY, ANTHROPIC_API_KEY, or GOOGLE_API_KEY environment variable."
}), 500
# Get the event loop
loop = get_or_create_eventloop()
# Run the task asynchronously
future = asyncio.run_coroutine_threadsafe(
run_browser_task(task, model),
loop
)
# Wait for the result (with timeout)
try:
result = future.result(timeout=300) # 5 minute timeout
return jsonify(result)
except asyncio.TimeoutError:
return jsonify({
"success": False,
"error": "Task timed out after 5 minutes"
}), 408
except Exception as e:
return jsonify({
"success": False,
"error": f"Server error: {str(e)}"
}), 500
if __name__ == "__main__":
print("Starting Browser-Use Server...")
print("Make sure you have set your API keys:")
print("- OPENAI_API_KEY for OpenAI models")
print("- ANTHROPIC_API_KEY for Anthropic models")
print("- GOOGLE_API_KEY for Google Gemini models")
# Run the Flask app
app.run(host="0.0.0.0", port=7860, debug=False)