Spaces:
Build error
Build error
| 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") | |
| async def read_root(request: Request): | |
| return templates.TemplateResponse("index.html", {"request": request}) | |
| 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 | |
| async def health_check(): | |
| return {"status": "ok"} |