1. 参数接收补充
在之前的文章Python框架篇(2):FastApi-参数接收和验证学习中,忘了以下几种参数的接收,这里补充下:
1.1 注解Annotated
typing.Annotated
是 Python
标准库中 typing
模块提供的一个工具,用于在类型提示中添加元数据(metadata
)。它可以帮助开发者更清晰地描述变量或函数的含义和用途,使用基本语法如下:
Annotated[type, metadata1, metadata2, ...]
|
其中,type
是变量或函数的类型,而 metadata1
, metadata2
, … 是元数据,可以是任何类型的对象,如字符串、字典等。
更多文档可查看: https://docs.python.org/zh-tw/3/library/typing.html#typing.Annotated
1.2 cookie参数
1.代码清单
文件: app/router/param_router.py
from typing import Annotated from fastapi import APIRouter, Request from fastapi import Cookie
router = APIRouter(prefix="/param", tags=["更多参数接收示例"])
@router.get("/cookie/key", summary="接收cookie中指定的key") async def cookieKey(user_name: Annotated[str | None, Cookie()] = None): """接收cookie中指定的key""" return {"user_name": user_name}
@router.get("/cookie/all", summary="所有cookie值") async def cookieParams(request: Request): """接收cookie值""" return {"cookies": request.cookies}
|
2.请求验证
$ curl -X 'GET' \ 'http://0.0.0.0:8088/param/cookie/all' \ -H 'accept: application/json' \ -H 'Cookie: user_name=liuqinghui;user_id=110;user_email=test@163.com'
{"cookies":{"user_name":"liuqinghui","user_id":"110","user_email":"test@163.com"}}
|
@注意: 发现框架生成的SwaggerUI演示cookie传参会报错,这里以命令行的形式展示~
默认情况下, Header
会把参数中的下划线 (_
) 转换为连字符 (-
) ,而且大小写不敏感,因此在代码种可以使用x_platform
接收Header
中的X-PlatForm
值。
1.代码清单
文件: app/router/param_router.py
from typing import Annotated from fastapi import APIRouter, Request from fastapi import Header
router = APIRouter(prefix="/param", tags=["更多参数接收示例"]) ...
@router.get("/header/key") async def headerKey(x_platform: Annotated[str | None, Header()] = None): """ 从header中获取指定key""" return {"x_platform": x_platform} @router.get("/header/keys") async def headerKey(x_ip: Annotated[list[str] | None, Header()] = None): """ 从header中获取重复key的值""" return {"x_ip": x_ip}
|
2.请求验证
$ curl -X 'GET' \ 'http://0.0.0.0:8088/param/header/key' \ -H 'accept: application/json' \ -H 'X-PlatForm: wechat'
{"x_platform":"wechat"}
$ curl -X 'GET' \ 'http://0.0.0.0:8088/param/header/keys' \ -H 'accept: application/json' \ -H 'X-IP: 127.0.0.1' \ -H 'X-IP: 172.30.10.21'
{"x_ip":["127.0.0.1","172.30.10.21"]}
|
1.4 表单参数
在使用表单参数前,需要先安装对应的包:pip install python-multipart
。
1.代码清单
文件: app/router/param_router.py
from fastapi import FastAPI, Form from app.types import response
router = APIRouter(prefix="/param", tags=["更多参数接收示例"])
... @router.post("/form/key") async def formKey(username: str = Form(), password: str = Form()) -> response.HttpResponse: """ 接收表单中的参数""" body = { "username": username, "password": password } return response.ResponseSuccess(body)
|
2.请求验证
2.上传文件
2.1 代码清单
import os from fastapi import APIRouter, Cookie, Request, Header, Form, UploadFile from app.types import response ...
@router.post("/upload/file") async def uploadFile(file: UploadFile | None = None, fileType: str = Form()) -> response.HttpResponse: """ 文件上传""" if not file: return response.ResponseFail("文件信息不能为空~")
try: save_path = os.path.join(os.getcwd(), "tmp", fileType) os.makedirs(save_path, exist_ok=True) file_path = os.path.join(save_path, file.filename) contents = await file.read() with open(file_path, "wb") as f: f.write(contents) body = { "fileName": file.filename, "fileType": fileType, "size": file.size, } return response.ResponseSuccess(body) except Exception as e: return response.ResponseFail("文件上传失败:" + str(e))
|
2.2 请求验证
$ curl -X 'POST' \ 'http://0.0.0.0:8088/param/upload/file' \ -H 'accept: application/json' \ -H 'Content-Type: multipart/form-data' \ -F 'file=@/Users/hui/Downloads/computer.png' \ -F 'fileType=img'
|
2.3 保存结果
3.访问文件
在某些场景下,我们需要提供一个地址,可以让前端工程师或者第三方来访问静态资源,比如返回一张图片或者一个文件。在FastAPI
中,静态资源的访问实现,叫:挂载
。
3.1 静态目录
... ├── app ├── main.py ... ├── static │ ├── img │ │ └── test.jpg │ └── root.txt ...
|
3.2 挂载
在服务启动入口,加上下面server.mount(...)
这行代码,即可进行静态资源进行访问。
...
server = FastAPI(redoc_url=None, docs_url="/apidoc", title="FastAPI学习")
server.mount("/static", StaticFiles(directory="static"), name="static") ...
|
3.3 访问
比如下面访问静态资源图片: static/img/test.jpg
4.下载文件
在工作中下载文件的场景,大部分都是异步导出文件,如发个异步任务,查出数据并把结果上传到oss
,然后在下载列表中查看状态并下载结果。但是也有些特殊场景,需要直接在浏览器中,实现下载文件,下面是实现效果:
4.1 代码清单
文件: app/router/param_router.py
from fastapi.responses import FileResponse ...
@router.get("/file/download") async def downloadFile() -> FileResponse: """下载文件""" fileName = "test.pdf" file_path = os.path.join(os.getcwd(), "tmp", fileName) return FileResponse(file_path, filename=fileName)
|
4.2 请求验证