Retrieve one individual entry

  • We need to define a PATH PARAMETER in the decorator

# Note that this is sigunlar to retrieve one single post
@app.get("/posts/{id}") # Has {id} because the user needs to specify the id of the post
def get_post(id):
    print(id)

    return {"data": f"this is the post {id}"}
  • We can then pass the path parameter to the function directly

def get_post(id): # Note the ID
  • This will allow us send the HTTP Request and retrieve some info

Note: We have a hardcoded post with ID 2

  • A better way of doing this (but not best practice) would be to create a function which retrieves the posts

# Function that retrieves the post based on id
def find_post(id):
    for p in my_posts:
        if p["id"] == id:
            return p
  • Then use the PATH PARAMETER as the ID for our function

@app.get("/posts/{id}") # Has {id} because the user needs to specify the id of the post
def get_post(id):
    post = find_post(id)

    return {"post_details": post}

Full code:

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
    }
]

# Function that retrieves the post based on id
def find_post(id):
    for p in my_posts:
        if p["id"] == id:
            return p
            
            
@app.get("/posts/{id}") # Has {id} because the user needs to specify the id of the post
def get_post(id):

# Note that we need the integer ID here
    post = find_post(int(id))

    return {"post_details": post}
  • Send the HTTP request to test the results

There is a problem with this approach. If you provide a string that cannot be converted to an integer, it will throw an INTERNAL SERVER ERROR response

  • We need to perform some kind of validation to ensure that whatever data is being passed to this parameter can be converted properly into an integer

  • This can be done directly via FastAPI

# Old validation code from above:
@app.get("/posts/{id}")
    post = find_post(int(id))

    return {"post_details": post}
    
# Validating directly with FastAPI
@app.get("/posts/{id}")
def get_post(id: int):   # Here is where we validate
    post = find_post(id) # We no longer need to convert

    return {"post_details": post}
  • Now we can send the HTTP Request

  • And get proper feedback of what went wrong

{
    "detail": [
        {
            "loc": [
                "path",
                "id"
            ],
            "msg": "value is not a valid integer",
            "type": "type_error.integer"
        }
    ]
}

Last updated