Changing response Status Codes

  • Lets set up the code required for a NULL return

from fastapi import FastAPI
from typing import Optional
from pydantic import BaseModel
from random import randrange

app = FastAPI()

class Post(BaseModel):
    title: str
    content: str
    published: bool = True
    rating: Optional[int] = None


# Global variable to save the post in memory
my_posts = [

    {
    "title": "title of post 1",
    "content": "content of post 1",
    "id": 1
    },

    {
    "title": "favorite foods",
    "content": "Pizza",
    "id": 2
    }
]

@app.get("/posts/{id}")
def get_post(id: int):
    post = find_post(id)

    return {"post_details": post}
  • If we use the ID = 5 via Postman we will get a NULL Response since there is no ID = 5 stored

  • There are multiple HTTP Codes that are being used but since there is no ID in the database for our request, we require in this case a HTTP 404 Message

  • First we need to import Response from FastAPI

from fastapi import FastAPI, Response
  • Now we can modify our code to accept responses

@app.get("/posts/{id}")
def get_post(id: int, response: Response):
    post = find_post(id)
    
    if not post:
        response.status_code = 404

    return {"post_details": post}
  • We have set it up so that if no post is found, it will return 404, so the return of the HTTP request still might be NULL but the response code is 404

There is a better way of doing things

  • Same concept but just a better overall implementation method

  • We need to import status from FastAPI

from fastapi import FastAPI, Response, status
  • Now we can simply say status. and this will return all HTTP Statuses

from fastapi import FastAPI, Response, status

@app.get("/posts/{id}")
def get_post(id: int, response: Response):
    post = find_post(id)
    
    if not post:
        response.status_code = status.HTTP_404_NOT_FOUND

    return {"post_details": post}
  • Additionally returning a NULL response looks ugly so we're going to add a code line to return a 404 message

  • This will return only if the post is not found

@app.get("/posts/{id}")
def get_post(id: int, response: Response):
    post = find_post(id)
    
    if not post:
        response.status_code = status.HTTP_404_NOT_FOUND
        
        return {"message": f"post with id {id} was not found"}

    return {"post_details": post}
  • This returns HTTP code 404 with message:

{
    "message": "post with id 5 was not found"
}

The above method is fine but a little sloppy, there is a even better way of raising this sort of exceptions so that you don't have to hardcode values

  • We will import HTTPException from FastAPI

from fastapi import FastAPI, Response, status, HTTPException
  • Then we will use the HTTPException to pass both HTTP code and the return message

@app.get("/posts/{id}")
def get_post(id: int): # We don't have to code in the response varialbe
    post = find_post(id)
    
    if not post:

        # This code is not needed anymore
        # response.status_code = status.HTTP_404_NOT_FOUND
        # return {"message": f"post with id {id} was not found"}

        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"post with id {id} was not found")

    return {"post_details": post}
  • The code cleaned up:

@app.get("/posts/{id}")
def get_post(id: int):
    post = find_post(id)
    
    if not post:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"post with id {id} was not found")

    return {"post_details": post}
  • This way you have both on a single line of code

Returning a HTTP code inside the decorator

  • Based on the HTTP Documentation, we should return a HTTP 201 every time there is a new post created

  • To do this we need to provide the decorator with an additional variable for this

# Creates new post and returns said post
@app.post("/posts", status_code=status.HTTP_201_CREATED)
def create_posts(post: Post):

    post_dict = post.dict()
    post_dict['id'] = randrange(0, 10000000)

    my_posts.append(post.dict())

    return {"data": post_dict}
  • Now that we have passed the status_code variable in the decorator the HTTP Request returns 201

Last updated