import os from fastapi import FastAPI, Request, HTTPException, Depends, Query from fastapi.responses import HTMLResponse, PlainTextResponse import httpx import uvicorn # --- Security Dependency --- ACCESS_KEY = os.environ.get("AK") async def verify_access_key(ak: str = Query(..., alias="AK")): """ Dependency to secure endpoints by verifying the 'AK' query parameter against the secret key stored in the environment. """ if not ACCESS_KEY: # Server-side configuration error if the secret is not set raise HTTPException( status_code=500, detail="Access key is not configured on the server." ) if ak != ACCESS_KEY: # Client-side error for an invalid access key raise HTTPException( status_code=401, detail="Unauthorized: Invalid access key provided." ) # --- FastAPI Application --- app = FastAPI( title="URL Fetcher API", description="A simple API to fetch URL content, with a protected endpoint." ) # --- MODIFIED: Root Endpoint --- @app.get("/", response_class=PlainTextResponse) async def root(): """ Root endpoint for health checks. Returns a simple 'OK' response. """ return "OK" @app.get("/ping", response_class=PlainTextResponse) async def ping(): """ An unprotected endpoint to check if the service is running. Returns a simple 'pong' response. """ return "pong" @app.get("/fetch_url", response_class=HTMLResponse, dependencies=[Depends(verify_access_key)]) async def fetch_url_content(request: Request): """ Fetches the HTML content of a URL from the 'url' query parameter. This endpoint is protected and requires a valid 'AK' (access key). """ target_url = request.query_params.get('url') if not target_url: raise HTTPException( status_code=400, detail="The 'url' query parameter is required." ) async with httpx.AsyncClient(follow_redirects=True) as client: try: headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'} response = await client.get(target_url, headers=headers) response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx) return HTMLResponse(content=response.text, status_code=response.status_code) except httpx.RequestError as exc: raise HTTPException(status_code=400, detail=f"An error occurred while requesting {exc.request.url!r}: {exc}") except httpx.HTTPStatusError as exc: raise HTTPException(status_code=exc.response.status_code, detail=f"Error response {exc.response.status_code} while requesting {exc.request.url!r}.")