would be neat
Build and Push Docker Images / build-and-push (push) Failing after 20s

This commit is contained in:
2026-03-27 09:47:09 +01:00
parent d45b5ea521
commit 85dd29a457
5 changed files with 46 additions and 1 deletions
+4
View File
@@ -176,6 +176,7 @@ POSTGRES_PASSWORD= # PostgreSQL password (optional)
### Core Endpoints ### Core Endpoints
- `GET /` - Visit URL and get HTML content (with Cloudflare bypass) - `GET /` - Visit URL and get HTML content (with Cloudflare bypass)
- `GET /screenshot` - Capture a screenshot of a URL (PNG output)
- `GET /seo` - Extract SEO information (with Cloudflare bypass) - `GET /seo` - Extract SEO information (with Cloudflare bypass)
- `GET /meta` - Extract meta tags and Open Graph data (with Cloudflare bypass) - `GET /meta` - Extract meta tags and Open Graph data (with Cloudflare bypass)
- `GET /test-cloudflare` - Test Cloudflare bypass functionality on a specific URL - `GET /test-cloudflare` - Test Cloudflare bypass functionality on a specific URL
@@ -198,6 +199,9 @@ POSTGRES_PASSWORD= # PostgreSQL password (optional)
# Visit a URL # Visit a URL
curl -H "X-API-Key: your-api-key" "http://localhost:8000/?url=https://example.com" curl -H "X-API-Key: your-api-key" "http://localhost:8000/?url=https://example.com"
# Capture a full-page screenshot (PNG)
curl -H "X-API-Key: your-api-key" "http://localhost:8000/screenshot?url=https://example.com" --output screenshot.png
# Extract SEO data # Extract SEO data
curl -H "X-API-Key: your-api-key" "http://localhost:8000/seo?url=https://example.com" curl -H "X-API-Key: your-api-key" "http://localhost:8000/seo?url=https://example.com"
+26 -1
View File
@@ -1,10 +1,11 @@
from fastapi import APIRouter, HTTPException, Header from fastapi import APIRouter, HTTPException, Header, Response
from typing import Optional from typing import Optional
from urllib.parse import unquote from urllib.parse import unquote
from app.config import API_KEY from app.config import API_KEY
from app.database import get_cached_data, save_to_cache from app.database import get_cached_data, save_to_cache
from app.services.browser import ( from app.services.browser import (
visit_url_service, visit_url_service,
screenshot_url_service,
extract_seo_service, extract_seo_service,
extract_meta_tags_service, extract_meta_tags_service,
capture_outgoing_calls_service, capture_outgoing_calls_service,
@@ -41,6 +42,30 @@ async def visit_url(url: str, skipCache: bool = False, x_api_key: Optional[str]
print(f"Error visiting URL {decoded_url}: {e}") print(f"Error visiting URL {decoded_url}: {e}")
raise HTTPException(status_code=500, detail=str(e)) raise HTTPException(status_code=500, detail=str(e))
@router.get("/screenshot")
async def screenshot_url(url: str, fullPage: bool = True, x_api_key: Optional[str] = Header(None)):
"""Capture a screenshot of a website and return it as PNG"""
if not x_api_key or x_api_key != API_KEY:
raise HTTPException(status_code=401, detail="Invalid API key")
decoded_url = unquote(url)
try:
result = await screenshot_url_service(decoded_url, fullPage)
if isinstance(result, dict) and result.get("status") == "error":
raise HTTPException(status_code=500, detail=result.get("error", "Screenshot capture failed"))
if not isinstance(result, (bytes, bytearray)):
raise HTTPException(status_code=500, detail="Unexpected screenshot response")
return Response(content=result, media_type="image/png")
except HTTPException:
raise
except Exception as e:
print(f"Error taking screenshot for URL {decoded_url}: {e}")
raise HTTPException(status_code=500, detail=str(e))
@router.get("/seo") @router.get("/seo")
async def extract_seo(url: str, skipCache: bool = False, x_api_key: Optional[str] = Header(None)): async def extract_seo(url: str, skipCache: bool = False, x_api_key: Optional[str] = Header(None)):
"""Extract SEO information from a website""" """Extract SEO information from a website"""
@@ -55,6 +55,22 @@ async def visit_url_service(decoded_url):
# Perform the operation # Perform the operation
return await safe_browser_operation(decoded_url, visit_operation) return await safe_browser_operation(decoded_url, visit_operation)
async def screenshot_url_service(decoded_url, full_page=True):
"""Service function to visit a URL and return a screenshot as PNG bytes"""
print(f"Taking screenshot of: {decoded_url}")
async def screenshot_operation(page):
try:
await page.goto(decoded_url, wait_until='networkidle', timeout=30000)
await page.wait_for_timeout(1000)
screenshot_bytes = await page.screenshot(full_page=full_page, type='png')
return screenshot_bytes
except Exception as e:
print(f"Error during screenshot capture: {e}")
return {"status": "error", "url": decoded_url, "error": str(e)}
return await safe_browser_operation(decoded_url, screenshot_operation)
async def extract_seo_service(decoded_url): async def extract_seo_service(decoded_url):
"""Service function to extract SEO information from a website""" """Service function to extract SEO information from a website"""
print(f"Extracting SEO from: {decoded_url}") print(f"Extracting SEO from: {decoded_url}")