Reputation: 2707
I'm using FastAPI to create a simple REST API for my frontends. This REST API backend that I'm developing is in fact a wrapper around another REST API which is pretty complex. The wrapper will also perform additional logic. There is no database involved here.
The code in my backend is defining a route 'projects'. Upon receiving a call, the code is performing a REST call to the vendor's product. Right now, it just passed the response from the vendor's REST API and passes it unaltered on to the frontend.
@app.get("/projects")
async def get_projects():
projects = RequestsApi(base_url, headers=headers) //RequestsApi is a class responsible for calling a REST API. That REST Api will return a json response
response = projects.get("/api/projects")
return response.json()
The response looks as follows (very much simplified):
{
"data": [
{
"access": "public",
"customer_id": 1,
"customer_name": "test1",
"description": "test1",
"email": null,
"id": 11814,
"name": "test1",
},
"access": "private",
"customer_id": 3,
"customer_name": "test2",
"description": "test2",
"email": null,
"id": 11815,
"name": "test2",
],
"warnings": []
}
I would want to filter the response to only include the name and description.
So I would like to return to my frontend the following:
{
"data": [
{
"description": "test1",
"name": "test1",
},
"description": "test2",
"name": "test2",
]
}
Therefore I created a pydantic model as follows:
class Project(BaseModel):
name: str
description: str
And I modified the route by adding the response_model:
@app.get("/projects", response_model=Project)
async def get_projects():
projects = RequestsApi(base_url, headers=headers)
response = projects.get("/api/projects")
return response.json()
Somehow I need to tell that the response maps to the Project model so I can return a project json object just containing the name and description.
How can this be done?
Note: I found a way through constructing it myself but this is surely not the right way to do this:
@app.get("/projects")
async def get_projects():
projects = RequestsApi(base_url, headers=headers)
response = projects.get("/api/projects")
projects = []
for key in response.json()["data"]:
myDict = {}
myDict["name"] = key["name"]
myDict["description"] = key["description"]
projects.append(myDict)
return projects
Upvotes: 1
Views: 3649
Reputation: 7300
You need to specify a list
of Pydantic models, like List[Project]
:
test.py:
import uvicorn
from typing import List
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
DATA = {
"data": [
{
"access": "public",
"customer_id": 1,
"customer_name": "test1",
"description": "test1",
"email": None,
"id": 11814,
"name": "test1",
},
{
"access": "private",
"customer_id": 3,
"customer_name": "test2",
"description": "test2",
"email": None,
"id": 11815,
"name": "test2",
},
],
"warnings": [],
}
class Project(BaseModel):
name: str
description: str
@app.get("/projects", response_model=List[Project])
async def get_projects():
# projects = RequestsApi(base_url, headers=headers)
# response = projects.get("/api/projects")
response = DATA
return response["data"]
if __name__ == "__main__":
uvicorn.run("main:app", host="localhost", port=8000, reload=True)
Test:
$ curl -s localhost:8000/projects | python -m json.tool --indent 2
[
{
"name": "test1",
"description": "test1"
},
{
"name": "test2",
"description": "test2"
}
]
Upvotes: 1