Last active
March 24, 2025 08:54
-
-
Save thevickypedia/02e1242bd8aa4f06cd19cfab5a030eef to your computer and use it in GitHub Desktop.
Basic proxy service using FastAPI (asynchronous)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import logging | |
from http import HTTPStatus | |
import httpx | |
import uvicorn.logging | |
from fastapi import FastAPI, HTTPException, Request, Response | |
from fastapi.routing import APIRoute | |
TARGET_URL = "http://127.0.0.1:8080" # Change this to the URL you want to proxy requests to | |
async def proxy(request: Request) -> Response: | |
"""Proxy handler function to forward incoming requests to a target URL. | |
Args: | |
request: The incoming request object. | |
Returns: | |
Response: The response object with the forwarded content and headers. | |
""" | |
try: | |
async with httpx.AsyncClient() as client: | |
body = await request.body() | |
# noinspection PyTypeChecker | |
response = await client.request( | |
method=request.method, | |
url=TARGET_URL + request.url.path, | |
headers=dict(request.headers), | |
cookies=request.cookies, | |
params=dict(request.query_params), | |
data=body.decode(), | |
) | |
# If the response content-type is text/html, we need to rewrite links in it | |
content_type = response.headers.get("content-type", "") | |
if "text/html" in content_type: | |
content = response.text | |
# Modify content if necessary (e.g., rewriting links) | |
# content = modify_html_links(content) | |
else: | |
content = response.content | |
response.headers.pop("content-encoding", None) | |
return Response(content, response.status_code, response.headers, content_type) | |
except httpx.RequestError as exc: | |
logging.getLogger("uvicorn.error").error(exc) | |
raise HTTPException(status_code=HTTPStatus.BAD_GATEWAY.value, detail=HTTPStatus.BAD_GATEWAY.phrase) | |
if __name__ == '__main__': | |
uvicorn.run( | |
app=FastAPI( | |
routes=[ | |
APIRoute("/{_:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"], endpoint=proxy) | |
] | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment