FastAPI:如何将任意属性字典映射到pydantic模型,让swagger显示细节



我有一个FastAPI项目,它的一个端点看起来像这样:

@app.post(
response=SomePydanticModel() # how to compose SomePydanticModel here???
)
def my_end_point():
response = {
"ZOOQ-700Z71": [
{"product_id": "prod_001", "product_name": "Product 001", "quantity": 10},
{"product_id": "prod_002", "product_name": "Product 002", "quantity": 20},
{"product_id": "prod_004", "product_name": "Product 004", "quantity": 30},
],
"0071-ZOGKNQ": [
{"product_id": "prod_001", "product_name": "Product 001", "quantity": 10},
{"product_id": "prod_003", "product_name": "Product 003", "quantity": 7},
{"product_id": "prod_008", "product_name": "Product 008", "quantity": 2},
],
"0071-Z0GKQ7": [
{"product_id": "prod_002", "product_name": "Product 002", "quantity": 12},
{"product_id": "prod_007", "product_name": "Product 007", "quantity": 6},
],
"ZZOQ-ZXOCT9": [
{"product_id": "prod_004", "product_name": "Product 004", "quantity": 100},
],
"2007-ZCKOZR": [
{"product_id": "prod_004", "product_name": "Product 004", "quantity": 30},
{"product_id": "prod_005", "product_name": "Product 005", "quantity": 20},
],
}

您可以看到,我的响应是任意属性字典,其属性格式为xxxx-xxxxxx采购订单ID. 我怎么用SomePydanticModel来表示我的反应?因此,我希望swagger显示我的响应的描述。

您可以使用Dict作为根类型的模型,键作为约束字符串constr与regex模式

例如:

from typing import Dict, List
from fastapi import FastAPI
from pydantic import BaseModel, constr
app = FastAPI()

class Product(BaseModel):
product_id: str
product_name: str
quantity: int

ConStrType = constr(regex=r'^[A-Z0-9]{4}-[A-Z0-9]{6}$')
ProductDict = Dict[ConStrType, List[Product]]

class ProductModel(BaseModel):
__root__: ProductDict

@app.post("/products", response_model=ProductModel)
def my_end_point():
return {
"ZOOQ-700Z71": [
{"product_id": "prod_001", "product_name": "Product 001", "quantity": 10},
{"product_id": "prod_002", "product_name": "Product 002", "quantity": 20},
{"product_id": "prod_004", "product_name": "Product 004", "quantity": 30},
],
"0071-ZOGKNQ": [
{"product_id": "prod_001", "product_name": "Product 001", "quantity": 10},
{"product_id": "prod_003", "product_name": "Product 003", "quantity": 7},
{"product_id": "prod_008", "product_name": "Product 008", "quantity": 2},
],
"0071-Z0GKQ7": [
{"product_id": "prod_002", "product_name": "Product 002", "quantity": 12},
{"product_id": "prod_007", "product_name": "Product 007", "quantity": 6},
],
"ZZOQ-ZXOCT9": [
{"product_id": "prod_004", "product_name": "Product 004", "quantity": 100},
],
"2007-ZCKOZR": [
{"product_id": "prod_004", "product_name": "Product 004", "quantity": 30},
{"product_id": "prod_005", "product_name": "Product 005", "quantity": 20},
],
}