Spaces:
Running
Running
File size: 2,809 Bytes
a3d4368 33184f5 a3d4368 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
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}.")
|