2

I want to render the index.html file. Otherwise, return a 404 error page not found.

from fastapi import FastAPI, Request, HTTPException 
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse

app = FastAPI() 

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


@app.get("/", response_class=HTMLResponse)
async def Index(request: Request):
    if status_code=404:
        return templates.TemplateResponse("404.html", {"request": request})
    return templates.TemplateResponse("index.html", {"request": request}) 

if __name__ == '__main__':
    uvicorn.run(app)
Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
Emma Donery
  • 85
  • 1
  • 1
  • 5
  • Does this answer your question? [How to return a custom 404 Not Found page using FastAPI?](https://stackoverflow.com/questions/71800133/how-to-return-a-custom-404-not-found-page-using-fastapi) – Chris Mar 17 '23 at 05:40

1 Answers1

2

Your index endpoint is only called when the client accesses the / route. So, you can't handle 404 errors in that same endpoint because a 404 means the client accessed some other undefined route.

A 404 is an HTTPException and FastAPI has a built-in handler for HTTPExceptions. But you can override it to provide your own handler. See the Handling Errors > Override the HTTPException error handler section of the FastAPI docs.

Basically, you define a method that handles all the HTTPExceptions:

from starlette.exceptions import HTTPException as StarletteHTTPException

@app.exception_handler(StarletteHTTPException)
async def my_custom_exception_handler(request: Request, exc: StarletteHTTPException):
    # Handle HTTPExceptions here

The function receives as its 2nd argument an HTTPException, which has a status_code and a detail attribute. So you can check the status_code, and render appropriate HTML templates. You can even use the passed-in Request and HTTPException objects for your templates:

from starlette.exceptions import HTTPException as StarletteHTTPException

@app.exception_handler(StarletteHTTPException)
async def my_custom_exception_handler(request: Request, exc: StarletteHTTPException):
    # print(exc.status_code, exc.detail)
    if exc.status_code == 404:
        return templates.TemplateResponse('404.html', {'request': request})
    elif exc.status_code == 500:
        return templates.TemplateResponse('500.html', {
            'request': request,
            'detail': exc.detail
        })
    else:
        # Generic error page
        return templates.TemplateResponse('error.html', {
            'request': request,
            'detail': exc.detail
        })

Take note again that the function handles all HTTPException types, not just your 404. If you just care about overriding the 404 error, you can pass the other errors to FastAPI's built-in handler:

from starlette.exceptions import HTTPException as StarletteHTTPException
from fastapi.exception_handlers import http_exception_handler

@app.exception_handler(StarletteHTTPException)
async def my_custom_exception_handler(request: Request, exc: StarletteHTTPException):
    if exc.status_code == 404:
        return templates.TemplateResponse('404.html', {'request': request})
    else:
        # Just use FastAPI's built-in handler for other errors
        return await http_exception_handler(request, exc)
Gino Mempin
  • 25,369
  • 29
  • 96
  • 135