tfrere's picture
update
0ef192c
import os
import asyncio
from fastapi import FastAPI, Request, Form
from fastapi.responses import HTMLResponse, JSONResponse, FileResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from playwright.async_api import async_playwright
import uuid
import logging
import pathlib
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Create FastAPI app
app = FastAPI()
# Determine base directory
BASE_DIR = pathlib.Path(__file__).parent.parent
# Set up templates and static files
templates_path = BASE_DIR / "templates"
static_path = BASE_DIR / "static"
screenshots_path = BASE_DIR / "screenshots"
templates = Jinja2Templates(directory=str(templates_path))
app.mount("/static", StaticFiles(directory=str(static_path)), name="static")
# Create screenshots directory if it doesn't exist
os.makedirs(str(screenshots_path), exist_ok=True)
# Mount the screenshots directory
app.mount("/screenshots", StaticFiles(directory=str(screenshots_path)), name="screenshots")
@app.get("/", response_class=HTMLResponse)
async def read_root(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
@app.post("/take-screenshot")
async def take_screenshot(url: str = Form(...)):
logger.info(f"Taking screenshot of URL: {url}")
try:
# Generate a unique filename
filename = f"{uuid.uuid4()}.png"
filepath = str(screenshots_path / filename)
# Log browser executable paths
logger.info(f"HOME env: {os.environ.get('HOME')}")
logger.info(f"Current working directory: {os.getcwd()}")
# Take the screenshot with Playwright
async with async_playwright() as p:
# Configuration adapted for Docker environment
browser = await p.chromium.launch(
headless=True,
args=[
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--no-first-run',
'--no-zygote',
'--single-process',
'--disable-gpu'
],
executable_path=None # Use default path
)
logger.info("Browser launched successfully")
page = await browser.new_page(viewport={"width": 1280, "height": 720})
try:
logger.info(f"Navigating to URL: {url}")
await page.goto(url, wait_until="networkidle", timeout=60000)
logger.info("Navigation complete, taking screenshot")
await page.screenshot(path=filepath)
logger.info(f"Screenshot saved to {filepath}")
except Exception as e:
logger.error(f"Error during page navigation or screenshot: {str(e)}")
raise
finally:
await browser.close()
logger.info("Browser closed")
return JSONResponse({
"success": True,
"screenshot_url": f"/screenshots/{filename}"
})
except Exception as e:
logger.error(f"Error taking screenshot: {str(e)}")
return JSONResponse({
"success": False,
"error": str(e)
}, status_code=500)
# Add a health check endpoint
@app.get("/health")
async def health_check():
return {"status": "ok"}