'FastAPI handling and redirecting 404

How can i redirect a request with FastAPI if there is a HTTPException?

In Flask we can achieve that like this:

@app.errorhandler(404)
def handle_404(e):
    if request.path.startswith('/api'):
        return render_template('my_api_404.html'), 404
    else:
        return redirect(url_for('index'))

Or in Django we can use django.shortcuts:

from django.shortcuts import redirect

def view_404(request, exception=None):
    return redirect('/')

How we can achieve that with FastAPI?



Solution 1:[1]

I know it's too late but this is the shortest approach to handle 404 exceptions in your personal way.

Redirect

from fastapi.responses import RedirectResponse


@app.exception_handler(404)
async def custom_404_handler(_, __):
    return RedirectResponse("/")

Custom Jinja Template

from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles

templates = Jinja2Templates(directory="templates")
app.mount("/static", StaticFiles(directory="static"), name="static")

@app.exception_handler(404)
async def custom_404_handler(request, __):
    return templates.TemplateResponse("404.html", {"request": request})

Serve HTML from file

@app.exception_handler(404)
async def custom_404_handler(_, __):
    return FileResponse('./path/to/404.html')

Serve HTML directly

from fastapi.responses import HTMLResponse

response_404 = """
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Not Found</title>
</head>
<body>
    <p>The file you requested was not found.</p>
</body>
</html>
"""
    
@app.exception_handler(404)
async def custom_404_handler(_, __):
    return HTMLResponse(response_404)

Note: exception_handler decorator passes the current request and exception as arguments to the function. I've used _ and __ where the variables are unnecessary.

Solution 2:[2]

I uses this method,

from fastapi.responses import RedirectResponse
from starlette.exceptions import HTTPException as StarletteHTTPException

app.mount("/static", StaticFiles(directory="static"), name="static")

templates = Jinja2Templates(directory="templates")

@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request, exc):
    return templates.TemplateResponse("404.html", {"request": request})
  • Make sure you have static folder, for your static files and templates folder your html files.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dharman
Solution 2 Dharman