Spaces:
Sleeping
Sleeping
from fastapi import FastAPI, Request, HTTPException | |
from fastapi.responses import Response | |
import aiohttp | |
from urllib.parse import urlparse | |
from aiohttp_client_cache import CachedSession,CacheBackend | |
app = FastAPI() | |
# Initialize the aiohttp ClientSession | |
#http_client = aiohttp.CachedSession() | |
async def startup_event(): | |
cache = CacheBackend( | |
allowed_methods=('GET', 'POST'), | |
allowed_codes=(200,503,502), | |
include_headers=True, | |
expire_after = 50 | |
) | |
global http_client | |
http_client = CachedSession(cache=cache) | |
async def shutdown_event(): | |
await http_client.close() | |
async def proxy(request: Request, url: str): | |
# The base_url includes scheme (http/https), so ensure it is provided | |
target_url = request.query_params.get("url") | |
if not target_url: | |
raise HTTPException(status_code=400, detail="Missing 'url' query parameter.") | |
# Optional: Validate the URL schema | |
parsed_url = urlparse(target_url) | |
if parsed_url.scheme not in ['http', 'https']: | |
raise HTTPException(status_code=400, detail="Invalid URL scheme. Only HTTP and HTTPS are supported.") | |
# Prepare headers from the original request | |
headers = dict(request.headers) | |
headers.pop('host', None) | |
# Prepare the body for methods that allow a body | |
body = None | |
if request.method in ["POST", "PUT", "PATCH"]: | |
body = await request.body() | |
try: | |
async with http_client.request( | |
method=request.method, | |
url=target_url, | |
headers=headers, | |
data=body, | |
allow_redirects=False, | |
ssl = False | |
) as upstream_response: | |
# Prepare the response headers, excluding some that might cause issues | |
response_headers = {k: v for k, v in upstream_response.headers.items() | |
if k.lower() not in ['transfer-encoding', 'content-encoding']} | |
# Stream the response back to the client | |
content = await upstream_response.read() | |
return Response(content=content, status_code=upstream_response.status, | |
headers=response_headers) | |
except aiohttp.ClientError as e: | |
raise HTTPException(status_code=500, detail=str(e)) | |
# Run the application | |
# Note: If running this file directly, uncomment the following lines: | |
# if __name__ == "__main__": | |
# import uvicorn | |
# uvicorn.run(app, host="0.0.0.0", port=8000) |