remake
This commit is contained in:
1 parent
bcdc0568e0
commit
2c647bb6e5
3 files changed
+138
-17
No files matched your search
+14
-12
@@ -30,18 +30,20 @@ RUN apt-get update && apt-get install -y \
|
|||||||
RUN pip install --no-cache-dir playwright && \
|
RUN pip install --no-cache-dir playwright && \
|
||||||
playwright install --with-deps chromium
|
playwright install --with-deps chromium
|
||||||
|
|
||||||
# Установка uv
|
# Установка Python зависимостей
|
||||||
RUN pip install --no-cache-dir uv
|
RUN pip install --no-cache-dir \
|
||||||
|
fastapi \
|
||||||
# Установка mcp-server-browser-use
|
uvicorn \
|
||||||
RUN uv pip install --system mcp-server-browser-use
|
pydantic \
|
||||||
|
browser-use \
|
||||||
# Создание директорий
|
langchain-openai \
|
||||||
RUN mkdir -p /root/.config/mcp-server-browser-use
|
langchain \
|
||||||
RUN mkdir -p /root/.config/browser-skills
|
python-dotenv
|
||||||
|
|
||||||
EXPOSE 8383
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
CMD ["mcp-server-browser-use", "start", "--host", "0.0.0.0", "--port", "8383"]
|
COPY app.py .
|
||||||
|
|
||||||
|
EXPOSE 8383
|
||||||
|
|
||||||
|
CMD ["python", "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)
|
||||||
+1
-5
@@ -10,15 +10,11 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "8383:8383"
|
- "8383:8383"
|
||||||
environment:
|
environment:
|
||||||
- LLM__PROVIDER=openrouter
|
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
|
||||||
- LLM__MODEL_NAME=${LLM_MODEL_NAME}
|
|
||||||
- LLM__API_KEY=${OPENROUTER_API_KEY}
|
|
||||||
volumes:
|
volumes:
|
||||||
- browser-data:/root/.config/mcp-server-browser-use
|
- browser-data:/root/.config/mcp-server-browser-use
|
||||||
- browser-skills:/root/.config/browser-skills
|
|
||||||
shm_size: '2gb'
|
shm_size: '2gb'
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
browser-data:
|
browser-data:
|
||||||
browser-skills:
|
|
||||||
Reference in new issue
Block a user