FastApi 通过响应模型修改响应

FastApi modify response through a response model

我正在使用 FastAPI 为我的前端创建一个简单的 REST API。我正在开发的这个 REST API 后端实际上是另一个 REST API 的包装器,它非常复杂。包装器还将执行其他逻辑。这里不涉及数据库。

我后端的代码正在定义一条路线 'projects'。接到电话后,代码将对供应商的产品执行 REST 调用。现在,它只是传递来自供应商的 REST API 的响应,并将其原封不动地传递到前端。

@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()

响应如下(非常简化):

{
  "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": []
}

我想过滤响应以仅包含名称和描述。

所以我想return到我的前端:

{
  "data": [
    {
      "description": "test1",
      "name": "test1", 
    },
      "description": "test2",
      "name": "test2",   
  ]
}

因此我创建了一个 pydantic 模型如下:

class Project(BaseModel):
    name: str
    description: str

并且我通过添加 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()

我需要以某种方式告知响应映射到项目模型,这样我就可以 return 一个只包含名称和描述的项目 json 对象。

如何做到这一点?

注意:我找到了自己构建的方法,但这肯定不是正确的方法:

@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

您需要指定 list 个 Pydantic 模型,例如 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)

测试:

$ curl -s localhost:8000/projects | python -m json.tool --indent 2
[
  {
    "name": "test1",
    "description": "test1"
  },
  {
    "name": "test2",
    "description": "test2"
  }
]