From 2c647bb6e5baf50309c2522a887ea751e9f708db Mon Sep 17 00:00:00 2001 From: nafer Date: Thu, 5 Mar 2026 19:36:24 +0300 Subject: [PATCH] remake --- Dockerfile | 26 +++++----- app.py | 123 +++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 6 +-- 3 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 app.py diff --git a/Dockerfile b/Dockerfile index e6b6da4..ebeddf4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,18 +30,20 @@ RUN apt-get update && apt-get install -y \ RUN pip install --no-cache-dir playwright && \ playwright install --with-deps chromium -# Установка uv -RUN pip install --no-cache-dir uv - -# Установка mcp-server-browser-use -RUN uv pip install --system mcp-server-browser-use - -# Создание директорий -RUN mkdir -p /root/.config/mcp-server-browser-use -RUN mkdir -p /root/.config/browser-skills - -EXPOSE 8383 +# Установка Python зависимостей +RUN pip install --no-cache-dir \ + fastapi \ + uvicorn \ + pydantic \ + browser-use \ + langchain-openai \ + langchain \ + python-dotenv WORKDIR /app -CMD ["mcp-server-browser-use", "start", "--host", "0.0.0.0", "--port", "8383"] +COPY app.py . + +EXPOSE 8383 + +CMD ["python", "app.py"] diff --git a/app.py b/app.py new file mode 100644 index 0000000..59a5c7d --- /dev/null +++ b/app.py @@ -0,0 +1,123 @@ +""" +Browser Use REST API Server +Простой HTTP API для управления браузером из n8n +""" +import os +import asyncio +from typing import Optional +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel +from browser_use import Agent, Browser, Controller +from browser_use.agent.views import AgentHistoryList +from langchain_openai import ChatOpenAI +import uvicorn + +# Обход проверки API ключа browser-use +os.environ["OPENAI_API_KEY"] = os.environ.get("OPENAI_API_KEY", "dummy") + +app = FastAPI(title="Browser Use API", version="1.0.0") + +# Модели запросов +class TaskRequest(BaseModel): + task: str + max_steps: Optional[int] = 20 + model: Optional[str] = "openai/gpt-4o-mini" + +class TaskResponse(BaseModel): + task_id: str + status: str + result: Optional[str] = None + error: Optional[str] = None + +# Хранилище задач +tasks = {} + +@app.post("/api/tasks", response_model=TaskResponse) +async def create_task(request: TaskRequest): + """Создать новую задачу браузера""" + import uuid + task_id = str(uuid.uuid4())[:8] + + tasks[task_id] = { + "status": "pending", + "task": request.task, + "result": None + } + + # Запускаем задачу в фоне + asyncio.create_task(run_browser_task(task_id, request.task, request.max_steps, request.model)) + + return TaskResponse( + task_id=task_id, + status="pending" + ) + +async def run_browser_task(task_id: str, task: str, max_steps: int, model: str): + """Выполнение задачи браузера""" + try: + tasks[task_id]["status"] = "running" + + # Настройка LLM через OpenRouter + api_key = os.getenv("OPENROUTER_API_KEY", "") + if not api_key: + raise ValueError("OPENROUTER_API_KEY not set") + + llm = ChatOpenAI( + model=model, + openai_api_base="https://openrouter.ai/api/v1", + openai_api_key=api_key, + ) + + # Инициализация браузера + browser = Browser() + controller = Controller() + + # Создание агента + agent = Agent( + task=task, + llm=llm, + browser=browser, + controller=controller, + ) + + # Выполнение задачи + history: AgentHistoryList = await agent.run(max_steps=max_steps) + + # Получение результата + result = history.final_result() + + tasks[task_id]["status"] = "completed" + tasks[task_id]["result"] = result + + # Очистка + await browser.close() + + except Exception as e: + tasks[task_id]["status"] = "failed" + tasks[task_id]["error"] = str(e) + +@app.get("/api/tasks/{task_id}", response_model=TaskResponse) +async def get_task(task_id: str): + """Получить статус/результат задачи""" + if task_id not in tasks: + raise HTTPException(status_code=404, detail="Task not found") + + task = tasks[task_id] + return TaskResponse( + task_id=task_id, + status=task["status"], + result=task.get("result"), + error=task.get("error") + ) + +@app.get("/api/health") +async def health_check(): + """Проверка здоровья сервера""" + return { + "status": "healthy", + "service": "browser-use-api", + "version": "1.0.0" + } + +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=8383) diff --git a/docker-compose.yml b/docker-compose.yml index d8e3518..7c5945b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,15 +10,11 @@ services: ports: - "8383:8383" environment: - - LLM__PROVIDER=openrouter - - LLM__MODEL_NAME=${LLM_MODEL_NAME} - - LLM__API_KEY=${OPENROUTER_API_KEY} + - OPENROUTER_API_KEY=${OPENROUTER_API_KEY} volumes: - browser-data:/root/.config/mcp-server-browser-use - - browser-skills:/root/.config/browser-skills shm_size: '2gb' restart: unless-stopped volumes: browser-data: - browser-skills: