diff --git a/Dockers/puppeteer-api/Dockerfile b/Dockers/puppeteer-api/Dockerfile new file mode 100644 index 0000000..74f6b22 --- /dev/null +++ b/Dockers/puppeteer-api/Dockerfile @@ -0,0 +1,46 @@ +FROM python:3.9-slim + +# Install required system dependencies +RUN apt-get update && apt-get install -y \ + wget \ + gnupg2 \ + && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/google-chrome-keyring.gpg \ + && echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome-keyring.gpg] http://dl.google.com/linux/chrome/deb/ stable main" | tee /etc/apt/sources.list.d/google-chrome.list \ + && apt-get update \ + && apt-get install -y \ + google-chrome-stable \ + fonts-ipafont-gothic \ + fonts-wqy-zenhei \ + fonts-thai-tlwg \ + fonts-kacst \ + fonts-freefont-ttf \ + libxss1 \ + xvfb \ + --no-install-recommends \ + && rm -rf /var/lib/apt/lists/* \ + # Verify Chrome installation + && google-chrome --version + +# Set working directory +WORKDIR /app + +# Copy requirements first to leverage Docker cache +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Copy the rest of the application +COPY . . + +# Set environment variables +ENV PYTHONUNBUFFERED=1 +ENV API_KEY="" + +# Create a non-root user and switch to it +RUN useradd -m puppeteer && chown -R puppeteer:puppeteer /app +USER puppeteer + +# Expose port +EXPOSE 8000 + +# Run the application +CMD ["python", "main.py"] diff --git a/Dockers/puppeteer-api/main.py b/Dockers/puppeteer-api/main.py new file mode 100644 index 0000000..6c40470 --- /dev/null +++ b/Dockers/puppeteer-api/main.py @@ -0,0 +1,56 @@ +from fastapi import FastAPI, HTTPException, Header +from pyppeteer import launch +import os +import asyncio +from typing import Optional +from urllib.parse import unquote + +app = FastAPI() + +# Get API key from environment variable +API_KEY = os.getenv('API_KEY') +if not API_KEY: + raise ValueError("API_KEY environment variable must be set") + +async def wait_for_network_idle(page): + """Wait until no network requests are in flight""" + await page.waitForNetworkIdle(idleTime=500, timeout=30000) + +@app.get("/") +async def visit_url(url: str, x_api_key: Optional[str] = Header(None)): + # Validate API key + if not x_api_key or x_api_key != API_KEY: + raise HTTPException(status_code=401, detail="Invalid API key") + + try: + # Decode URL if it's encoded + decoded_url = unquote(url) + print(decoded_url) + + # Launch browser using installed Chrome + browser = await launch( + headless=True, + executablePath='/usr/bin/google-chrome', + args=['--no-sandbox', '--disable-setuid-sandbox'] + ) + + # Create new page + page = await browser.newPage() + + # Navigate to URL and wait for network idle + await page.goto(decoded_url, waitUntil='networkidle2') + + # Get page content + content = await page.content() + + # Close browser + await browser.close() + + return {"status": "success", "content": content} + + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + +if __name__ == "__main__": + import uvicorn + uvicorn.run(app, host="0.0.0.0", port=8000) diff --git a/Dockers/puppeteer-api/requirements.txt b/Dockers/puppeteer-api/requirements.txt new file mode 100644 index 0000000..1d5de17 --- /dev/null +++ b/Dockers/puppeteer-api/requirements.txt @@ -0,0 +1,3 @@ +fastapi==0.68.1 +uvicorn==0.15.0 +pyppeteer==1.0.2 \ No newline at end of file