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-pro", "gemini-1.5-pro-latest" ] }) @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)