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 = 20 | |
| # ) | |
| global http_client | |
| http_client = aiohttp.ClientSession() | |
| # 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() | |
| print(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) |