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