veeiiinnnnn's picture
Add backend-python and Dockerfile
4ef118d
import asyncio
import os
import subprocess
from fastapi import APIRouter, HTTPException
from fastapi.responses import JSONResponse
from loguru import logger
router = APIRouter(prefix="/env", tags=["Environment"])
@router.get("/status")
async def get_env_status():
"""
Check if the scraper engine (Playwright Chromium) is installed by finding its path.
"""
try:
from playwright.async_api import async_playwright
chromium_found = False
try:
async with async_playwright() as p:
exec_path = p.chromium.executable_path
if exec_path and os.path.exists(exec_path):
chromium_found = True
logger.info(f"[Env] Chromium found at: {exec_path}")
else:
logger.warning(f"[Env] Chromium executable not found at: {exec_path}")
except Exception as inner_e:
logger.warning(f"[Env] Chromium check failed: {inner_e}")
return {
"status": "ok" if chromium_found else "error",
"chromium_installed": chromium_found,
"message": None if chromium_found else "Chromium browser not installed. Please run /api/env/install-browsers"
}
except ImportError:
return {"status": "error", "chromium_installed": False,
"message": "Playwright module not installed"}
except Exception as e:
return {"status": "error", "message": str(e), "chromium_installed": False}
@router.post("/install-browsers")
async def install_browsers():
"""
Triggers 'playwright install chromium' asynchronously.
"""
try:
logger.info("[Env] Triggering playwright install chromium...")
# We use uv run if available, otherwise direct playwright
cmd = ["playwright", "install", "chromium"]
# Check if we are in uv environment
if os.path.exists(".venv") or os.environ.get("VIRTUAL_ENV"):
# Try to find which command works best
pass
# Use asyncio to keep it non-blocking
process = await asyncio.create_subprocess_exec(
"python", "-m", "playwright", "install", "chromium",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
# Wait for completion (Real-time progress could be added via SSE later)
stdout, stderr = await process.communicate()
if process.returncode == 0:
logger.info("[Env] Scraper engine installed successfully.")
return {"status": "success", "message": "Scraper engine installed successfully."}
else:
err_msg = stderr.decode()
logger.error("[Env] Scraper engine installation failed: %s", err_msg)
raise HTTPException(status_code=500, detail=f"Installation failed: {err_msg}")
except Exception as e:
logger.error("[Env] Error during browser installation: %s", e)
raise HTTPException(status_code=500, detail=str(e))