FastAPI -- 第二弹(响应模型、状态码)

响应模型

添加响应模型

from typing import Any

from fastapi import FastAPI
from pydantic import BaseModel, EmailStr

app = FastAPI()


class UserIn(BaseModel):
    username: str
    password: str
    email: EmailStr
    full_name: str | None = None


class UserOut(BaseModel):
    username: str
    email: EmailStr
    full_name: str | None = None

# 通过 response_model 设置返回模型
@app.post("/user/", response_model=UserOut)
async def create_user(user: UserIn) -> Any:
    return user

模型的其他操作

继承 & 解包

from fastapi import FastAPI
from pydantic import BaseModel, EmailStr

app = FastAPI()

# 定义一个 Base
# 包含公共属性,比如 id create_time update_time 等
class UserBase(BaseModel):
    username: str
    email: EmailStr
    full_name: str | None = None

# 继承 Base
class UserIn(UserBase):
    password: str


# 继承 Base
class UserOut(UserBase):
    pass


# 继承 Base
class UserInDB(UserBase):
    hashed_password: str
    

def fake_password_hasher(raw_password: str):
    return "supersecret" + raw_password


def fake_save_user(user_in: UserIn):
    hashed_password = fake_password_hasher(user_in.password)

	# 解包
	# user_in = UserIn(username="john", password="secret", email="john.doe@example.com")
	# **user_in.dict() ==> 
	#		username = user_dict["username"],
	#	    password = user_dict["password"],
	#	    email = user_dict["email"],
	#	    full_name = user_dict["full_name"], 
	user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)
    print("User saved! ..not really")
    return user_in_db


@app.post("/user/", response_model=UserOut)
async def create_user(user_in: UserIn):
    user_saved = fake_save_user(user_in)
    return user_saved

组合模型 (Union & dict)

union

union:组合多个模型,但返回值只能是一个模型的实例

from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class BaseItem(BaseModel):
    description: str
    type: str


class CarItem(BaseItem):
    type: str = "car"


class PlaneItem(BaseItem):
    type: str = "plane"
    size: int


items = {
    "item1": {"description": "All my friends drive a low rider", "type": "car"},
    "item2": {
        "description": "Music is my aeroplane, it's my aeroplane",
        "type": "plane",
        "size": 5,
    },
    "item3": [
	    {
	        "description": "item3_1 Music is my aeroplane, it's my aeroplane",
	        "type": "plane",
	        "size": 5,
	    },
	    {
	        "description": "item3_2 Music is my aeroplane, it's my aeroplane",
	        "type": "plane",
	        "size": 5,
	    },
    ]
}

# Union[PlaneItem, CarItem, list[PlaneItem]],。。。。]
# 允许返回 Union 的多种类型中的 一种
@app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem,list[PlaneItem]])
async def read_item(item_id: str):
    return items[item_id]
dict

response_model=dict ,
response_model=dict[str, list] ,
response_model=list …

dict 有点类似于 any, 但又比 any 更具体一些
比如 any 可以是 list 也可以是 dict, 但 dict 只能是 dict 不能是 list
比如 dict 可以是 dict[str, list], dict[int, list] 等,但 dict[str, list] 只能是 dict[str, list]

from fastapi import FastAPI

app = FastAPI()


# 测试 Any
@app.get("/test_any/")
async def read_keyword_weights():
    # return {"foo": 2.3, "bar": 3.4}
    return [1, 2, 3]


# 测试 dict
@app.get("/test_dict/", response_model=dict)
async def read_keyword_weights():
    return {"foo": 2.3, "bar": [1, 2, 3]}


# 测试 dict[str, float]
@app.get("/test_dict_str_float/", response_model=dict[str, float])
async def read_keyword_weights():
    return {"foo": 2.3, "bar": 3.4}
    # return {"foo": 2.3, "bar": [1, 2, 3]}

响应状态码

from enum import IntEnum
from http import HTTPStatus

from fastapi import FastAPI, status

app = FastAPI()


# 通过 http模块的 HTTPStatus 类,
# 我们可以很方便的使用一些常见的状态码,如下
@app.get("/items/http_status", status_code=HTTPStatus.OK)
def test_status_code():
    return "hallow world HTTPStatus"


# 通过 fastapi 的 status 模块,
# 我们可以很方便的使用一些常见的状态码,如下
@app.get("/items/status", status_code=status.HTTP_201_CREATED)
def test_status_code():
    return "hallow world status"


# 也可以直接使用数字
@app.get("/items/num", status_code=201)
def test_status_code():
    return "hallow world num"



顺便记一下,可以仿照 HTTPStatus 的写法,自定义状态码。
注意:自定义状态码是放到 响应体 里的,放到 status_code 后面有可能会报错哦


# 自定义的状态码
class MyHTTPStatus(IntEnum):    
    
    def __new__(cls, value, phrase, description=''):
        obj = int.__new__(cls, value)
        obj._value_ = value

        obj.phrase = phrase
        obj.description = description
        return obj
    
    Code200000 = 200000, 'OK', 'Request fulfilled, document follows'
    # client error
    Code400000 = (400000, 'Bad Request',
        'Bad request syntax or unsupported method')


# 响应体示例
# {
#     "code": 200000,
#     "message": "OK",
#     "data": {
#         "name": "张三"
#     }
# }

From表单

from fastapi import FastAPI, Form

app = FastAPI()

# 和 Boday Query 类似,Form 也是从 fastapi 导入
# username: str = Form()
@app.post("/login/")
async def login(username: str = Form(), password: str = Form()):
    return {"username": username}

上传文件 (File, UploadFile)

from fastapi import FastAPI, File, UploadFile

app = FastAPI()


@app.post("/files/")
async def create_file(file: bytes = File()):
    return {"file_size": len(file)}


# 和前面的可选参数类似,如果 file 是可选的可以使用如下的方式声明
# file: UploadFile | None = None
# 多文件上传
# files: list[UploadFile]
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
    return {"filename": file.filename}

UploadFile 与 bytes 相比有更多优势:

  • 使用 spooled 文件
    • 存储在内存的文件超出最大上限时,FastAPI 会把文件存入磁盘
  • 这种方式更适于处理图像、视频、二进制文件等大型文件,好处是不会占用所有内存
  • 可获取上传文件的元数据
  • 自带 file-like async 接口
  • 暴露的 Python SpooledTemporaryFile 对象,可直接传递给其他预期「file-like」对象的库。

UploadFile

UploadFile 的属性
  • filename:上传文件名字符串(str),例如, myimage.jpg;
  • content_type:内容类型(MIME 类型 / 媒体类型)字符串(str),例如,image/jpeg;
  • file: SpooledTemporaryFile( file-like 对象)。其实就是 Python文件,可直接传递给其他预期 file-like 对象的函数或支持库。
UploadFile 支持以下 async 方法
  • write(data):把 data (str 或 bytes)写入文件;
  • read(size):按指定数量的字节或字符(size (int))读取文件内容;
  • seek(offset):移动至文件 offset (int)字节处的位置
    • 例如,await myfile.seek(0) 移动到文件开头, 执行 await myfile.read() 后,需再次读取已读取内容时,这种方法特别好用;
  • close():关闭文件

依赖项

声明依赖项

  • 提高代码的复用性
from typing import Union

from fastapi import Depends, FastAPI

app = FastAPI()


# 为查询接口设置一些公共参数
async def common_parameters(
    q: Union[str, None] = None, skip: int = 0, limit: int = 100
):
    return {"q": q, "skip": skip, "limit": limit}


# 通过 Depends 声明依赖项
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
    return commons


@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
    return commons

到此结  DragonFangQy 2024.07.13

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
fastapi-mysql-generator 是一个用于快速生成FastAPI和MySQL的框架的工具。FastAPI是一个现代、快速(高性能)的web框架,而MySQL是一个流行的关系型数据库。 使用 fastapi-mysql-generator,可以从一个简单的命令行界面中生成 FastAPI 应用程序,并与 MySQL 数据库集成。这个工具可以自动创建数据库表和模型(Model),并提供一组 API 端点,用于执行常见的 CRUD(创建、读取、更新和删除)操作。 fastapi-mysql-generator 的主要优势之一是它的简单易用性。无论是初学者还是有经验的开发人员,都可以快速上手并生成一个完整的基于FastAPI和MySQL的应用程序。只需要几个简单的步骤,就可以生成项目的基本结构和代码。同时,fastapi-mysql-generator 还提供了一些配置选项,可以根据需求进行自定义设置,以满足特定的应用程序需求。 这个工具还提供了一些有用的特性,以增强开发的效率和便利性。例如,它可以自动生成 API 文档,包括请求和响应模型的文档说明。此外,fastapi-mysql-generator 还支持身份验证和授权功能,以确保 API 路由的安全性。 总而言之,fastapi-mysql-generator 是一个快速生成 FastAPI 和 MySQL 应用程序的方便工具。它简化了应用程序的开发过程,并提供了一些有用的特性,以提高开发效率和便利性。无论是初学者还是有经验的开发人员,都可以受益于这个工具的使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值