赞
踩
在之前的文章Python框架篇(2):FastApi-参数接收和验证学习中,忘了以下几种参数的接收,这里补充下:
typing.Annotated
是 Python
标准库中 typing
模块提供的一个工具,用于在类型提示中添加元数据(metadata
)。它可以帮助开发者更清晰地描述变量或函数的含义和用途,使用基本语法如下:
Annotated[type, metadata1, metadata2, ...]
其中,type
是变量或函数的类型,而 metadata1
, metadata2
, ... 是元数据,可以是任何类型的对象,如字符串、字典等。
更多文档可查看: https://docs.python.org/zh-tw/3/library/typing.html#typing.Annotated
文件: app/router/param_router.py
from typing import Annotated
from fastapi import APIRouter, Request
from fastapi import Cookie # 导入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}
# 命令行请求
$ 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
值。
文件: app/router/param_router.py
from typing import Annotated
from fastapi import APIRouter, Request
from fastapi import Header # 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}
# 请求验证
$ curl -X 'GET' \
'http://0.0.0.0:8088/param/header/key' \
-H 'accept: application/json' \
-H 'X-PlatForm: wechat'
# 返回值
{"x_platform":"wechat"}
# ----- headers中有重复key时 -----
$ 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"]}
在使用表单参数前,需要先安装对应的包:
pip install python-multipart
。
文件: 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)
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))
$ 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'
在某些场景下,我们需要提供一个地址,可以让前端工程师或者第三方来访问静态资源,比如返回一张图片或者一个文件。在FastAPI
中,静态资源的访问实现,叫:挂载
。
...
├── app
├── main.py
...
├── static
│ ├── img
│ │ └── test.jpg
│ └── root.txt
...
在服务启动入口,加上下面server.mount(...)
这行代码,即可进行静态资源进行访问。
...
# 实例化
server = FastAPI(redoc_url=None, docs_url="/apidoc", title="FastAPI学习")
# 挂载静态资源目录
server.mount("/static", StaticFiles(directory="static"), name="static")
...
比如下面访问静态资源图片: static/img/test.jpg
在工作中下载文件的场景,大部分都是异步导出文件,如发个异步任务,查出数据并把结果上传到oss
,然后在下载列表中查看状态并下载结果。但是也有些特殊场景,需要直接在浏览器中,实现下载文件,下面是实现效果:
文件: 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)
本文由 mdnice 多平台发布
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。