Deleting entries

  • First we need to set up a function that enumerates through all the posts

def find_index_post(id):
    for i, p in enumerate(my_posts):
        if p['id'] == id:
            return i
  • The above function:

    • Iterates through all posts in the "database" by using enumerate

    • This retrieves the index position (i) as well as the post (p)

    • If the post id is the same as the id provided to the function, it returns the index position number (i)

  • Now we can create a DELETE Path Operation

@app.delete("/posts/{id}")
def delete_post(id: int):
    # Deleting posts
    # find the index in the array that requires the ID
    # my_posts.pop()

    index = find_index_post(id)

    my_posts.pop(index)
    return {"message": f"post with id {id} was successfully deleted"}
  • This calls the find_index_post function we have defined above and provides it with an id of integer type (from decorator)

  • The index number will be "popped" out of the posts

  • Message with the successful deletion will be returned

Full Code:

from fastapi import FastAPI, Response, status, HTTPException
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
    }
]
    
    
def find_index_post(id):
    for i, p in enumerate(my_posts):
        if p['id'] == id:
            return i

@app.delete("/posts/{id}")
def delete_post(id: int):

    index = find_index_post(id)

    my_posts.pop(index)
    return {"message": f"post with id {id} was successfully deleted"}
  • If we send now a DELETE HTTP request via Postman we should be prompted for a message successfully deleted

  • If we retrieve all posts from the "database" it should return only the post with ID 2

  • When deleting entries we should be using HTTP Code 204

  • So the way FastAPI works is that we should not be sending any data back with a 204

  • So the new code and HTTP 204 implementation should be:

@app.delete("/posts/{id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_post(id: int):
    index = find_index_post(id)
    my_posts.pop(index)
    
    return Response(status_code=status.HTTP_204_NO_CONTENT)
  • If we try to return the info, it will work but will throw an error on the backend side:

raise RuntimeError("Response content longer than Content-Length")
  • So what we need to do is grab the response and return no content back

  • After this there shouldn't be any error anymore

To get a detailed explanation for this click here!

  • We are still running into an issue where if you don't provide a ID that exists it will return a HTTP 500 message

  • To get around this we need to implement an exception that raises a HTTP 404 message with post does not exist

@app.delete("/posts/{id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_post(id: int):

    index = find_index_post(id)

# Handles non-existent IDs
    if index == None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"post with {id} does not exist")

    my_posts.pop(index)
    return Response(status_code=status.HTTP_204_NO_CONTENT)

Last updated