python:Fastapi - 请求表单与文件
简单絮叨下,如有问题请私信
上篇文章主要唠了接口响应的一些东西,今天主要是唠Form表单和文件处理。表单可以理解为数据采集,而文件处理就是在获得客户端的文件进行数据返回或者直接上传服务器。
fastapi框架中提供了操作表单的Form和处理文件的File,其参数的方式与 Body 和 Query一样。
表单数据
From它接收的不是json,而是表单字段,使用表单需要安装pip install python-multipart(Python 的流式多部分解析器)
from fastapi import Form
from fastapi import FastAPI
app = FastAPI()
@app.post("/login/")
async def login(username: str = Form(...), password: str = Form(...)):
if password == "123456":
return {"username": username}
else:
return "密码或账号不正确..."
注释信息:
usernam和password是定义了Form表单- 如果
password不等于字符串类型的123456,就抛出提示信息,相反就是返回用户名 - 可在一个路径操作中声明多个
Form参数 - 表单数据的「媒体类型」编码一般为
application/x-www-form-urlencoded
启动服务:
PS E:\git_code\python-code\fastapiProject> uvicorn form_main:app --reload
请求接口:
POST http://127.0.0.1:8000/login/
请求参数:
- 所以在
postman中的body-选择form-data或x-www-form-urlencoded进行传参
| KEY | VALUE |
|---|---|
| username | zhangsan |
| password | 123456 |
请求结果:
{
"username": "zhangsan"
}
请求文件
文件上传也是以表单的形式发送的,它默认的媒体类型编码一般为 application/form-data
因为是以表单的形式发送数据,固要安装pip install python-multipart(Python 的流式多部分解析器)
文件上传分为两种形式,首先是直接File,其次是UploadFile,它俩的区别就是UploadFile是处理大数据,相反的就是适用于小型文件
from fastapi import File
from fastapi import FastAPI
from fastapi import UploadFile
app = FastAPI()
@app.post("/file/")
async def create_file(file: bytes= File(...)):
"""
直接定义`File`参数
:param file:
:return:
"""
return {"file": file}
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...)):
"""
含 UploadFile 的 File 参数
:param file:
:return:
"""
return {"filename": file.filename}
注释信息:
file: bytes= File(…)把路径操作函数参数的类型声明为bytes,FastAPI将以bytes形式读取和接收文件内容,这里是把文件都存储在内存里,所以适用小型文件file: UploadFile = File(…)是存储在内存的文件超出最大上限时,FastAPI会把文件存入磁盘,适于处理图像、视频、二进制文件等大型文件,好处是不会占用所有内存file.filename是UploadFile下的属性,获取文件名称
启动服务:
PS E:\git_code\python-code\fastapiProject> uvicorn form_main:app --reload
请求接口:
POST http://127.0.0.1:8000/file/
POST http://127.0.0.1:8000/uploadfile/
请求参数:
- 所以在
postman中的body-选择form-data进行传参。[注意:KEY栏输入参数并下拉选择为File]
直接File传参
| KEY | VALUE |
|---|---|
| file | 选择文件 |
含UploadFile的File传参
| KEY | VALUE |
|---|---|
| file | 选择文件 |
请求结果:
直接File请求结果
{
"file": "22222"
}
含UploadFile的File请求结果
{
"filename": "testing.txt"
}
多文件上传
FastAPI 支持同时上传多个文件。
可用同一个「表单字段」发送含多个文件的「表单数据」。
上传多个文件时,要声明含 bytes 或 UploadFile 的列表(List):
from typing import List
from fastapi import File
from fastapi import FastAPI
from fastapi import UploadFile
app = FastAPI()
@app.post("/files/")
async def files(files: List[bytes] = File(...)):
"""
直接定义`File`参数
:param files:
:return:
"""
return {
"file_sizes": [len(file) for file in files]
}
@app.post("/uploadfiles/")
async def upload_files(files: List[UploadFile] = File(...)):
"""
含 UploadFile 的 File 参数
:param files:
:return:
"""
return {
"filenames": [file.filename for file in files],
"content_type": [file.content_type for file in files],
"file": [file for file in files]
}
注释信息:
file: List[bytes] = File(…)定义了一个列表,列表中的值必须是字节类型[len(file) for file in file]是列表推导获取文件的长度files: List[UploadFile] = File(…)定义了一个列表,列表中的值必须是UploadFile[file.filename for file in files]列表推导获取文件名称[file.content_type for file in files]列表推导获取文件类型[file for file in files]列表推导获取文件
启动服务:
PS E:\git_code\python-code\fastapiProject> uvicorn form_main:app --reload
请求接口:
POST http://127.0.0.1:8000/files/
POST http://127.0.0.1:8000/uploadfiles/
请求参数:
- 所以在
postman中的body-选择form-data进行传参。[注意:KEY栏输入参数并下拉选择为File]
直接File传参
| KEY | VALUE |
|---|---|
| files | 选择文件 |
| files | 选择文件 |
含UploadFile的File传参
| KEY | VALUE |
|---|---|
| files | 选择文件 |
| files | 选择文件 |
请求结果:
直接File请求结果
{
"file_sizes": [
5,
13488
]
}
含UploadFile的File请求结果
{
"filenames": [
"testing.txt",
"fastapi.png"
],
"content_type": [
"text/plain",
"image/png"
],
"file": [
{
"filename": "testing.txt",
"content_type": "text/plain",
"file": {
"_file": {},
"_max_size": 1048576,
"_rolled": false,
"_TemporaryFileArgs": {
"mode": "w+b",
"buffering": -1,
"suffix": null,
"prefix": null,
"encoding": null,
"newline": null,
"dir": null,
"errors": null
}
}
},
{
"filename": "fastapi.png",
"content_type": "image/png",
"file": {
"_file": {},
"_max_size": 1048576,
"_rolled": false,
"_TemporaryFileArgs": {
"mode": "w+b",
"buffering": -1,
"suffix": null,
"prefix": null,
"encoding": null,
"newline": null,
"dir": null,
"errors": null
}
}
}
]
}
请求表单与文件
FastAPI 支持同时使用 File 和 Form 定义文件和表单字段。
from fastapi import Form
from fastapi import File
from fastapi import FastAPI
from fastapi import UploadFile
app = FastAPI()
@app.post("/filesForm/")
async def form_upload_file(
file: bytes = File(...), files: UploadFile = File(...), token: str = Form(...)
):
return {
"token": token,
"file_size": len(file),
"filename": files.filename,
"content_type": files.content_type,
}
启动服务:
PS E:\git_code\python-code\fastapiProject> uvicorn form_main:app --reload
请求接口:
POST http://127.0.0.1:8000/filesForm/
请求参数:
- 所以在
postman中的body-选择form-data进行传参。[注意:KEY栏输入参数并下拉选择为File]
| KEY | VALUE |
|---|---|
| file | 选择文件 |
| files | 选择文件 |
| token | 1234567 |
请求结果:
{
"token": "1234567",
"file_size": 5,
"filename": "弱网测试.docx",
"content_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}
注意点:
- 可在一个路径操作中声明多个
File与Form参数,但不能同时声明要接收JSON的Body字段。因为此时请求体的编码为multipart/form-data,不是application/json。这不是FastAPI的问题,而是HTTP协议的规定。
UploadFile的属性及方法
上述段落描述了UploadFile的使用,这个段落描述UploadFile提供的属性和方法。
属性
file:获取文件对象filename:获取上传文件的名称content_type:获取上传文件的内容类型
{
"file": {
"filename": "弱网测试.docx",
"content_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"file": {
"_file": {},
"_max_size": 1048576,
"_rolled": false,
"_TemporaryFileArgs": {
"mode": "w+b",
"buffering": -1,
"suffix": null,
"prefix": null,
"encoding": null,
"newline": null,
"dir": null,
"errors": null
}
}
},
"filename": "弱网测试.docx",
"content_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}
方法
write(data):把data(str或bytes)写入文件。踩坑:在写入str时就会抛错误,bytes类型就不会报错,暂时还没找到解决方法。read(size):按自定数量的字节或字符读取文件内容。踩坑:读取数据时,针对.txt的文件可以读出数据,针对word类型的文件,就会抛出错误,暂时还没找到解决方法。seek(offset):移动至问价字节处的位置close():关闭文件
read跟seek结合使用,可多次读取已读内容:
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...)):
"""
含 UploadFile 的 File 参数
:param file:
:return:
"""
await file.write(b"ggggggg")
await file.seek(0)
data = await file.read()
await file.close()
return data
注意点:
如果你是异步请求,必须要搭配await使用:
data = await file.read()
return data
如果你是普通请求,就不需要搭配await使用:
data = file.read()
return data
今天先聊到这里吧,以上总结或许能帮助到你,或许帮助不到你,但还是希望能帮助到你,如有疑问、歧义,直接私信留言会及时修正发布;非常期待你的一键 3 连【 点赞、收藏、分享 】哟,谢谢!
未完成,待续……
一直在努力,希望你也是!
微信搜索公众号:就用python

浙公网安备 33010602011771号