FastAPI 文件上传
# coding: utf8
from fastapi import FastAPI, File, UploadFile
from typing import List
app = FastAPI()
# 上传文单个件方法一, File 是直接继承自 Form 的类。
@app.post('/file')
async def create(file: bytes = File(...)):
return {"file_size": len(file)}
# 上传文单个件方法二
@app.post('/uploadfile')
async def upload_file(file: UploadFile = File(...)):
# contents = await file.read()
# print(contents)
return {'filename': file.filename}
# 上传多个文件方法一
@app.post("/files")
async def create(fileS: List[bytes] = File(...)):
return {"file_sizes": [len(file) for file in fileS]}
# 上传多个文件方法二
@app.post("/uploadfiles")
async def upload_file(fileS: List[UploadFile] = File(...)):
return {"filenames": [file.filename for file in fileS]}
# # 启动: uvicorn main:app --reload
pip install python-multipart
上传和form表单组合使用
- 上传单个多个文件
```python
from fastapi import FastAPI, File, Form, UploadFile
app = FastAPI()
@app.post("/files/")
async def create_file(
file: bytes = File(...), one: UploadFile = File(...),
token: str = Form(...)
):
return {
"filesize": len(file),
"token": token,
"one_content_type": one.content_type,
}
上传多个文件
from fastapi import FastAPI, File, Form, UploadFile
from typing import List
app = FastAPI()
@app.post("/files/")
async def create_file(
file: bytes = File(...), one: List[UploadFile] = File(...),
token: str = Form(...)
):
return {
"filesize": len(file),
"token": token,
"one_content_type": [file.content_type for file in one],
}
## UploadFile 的属性如下:
- filename:上传文件名字符串(str),例如, myimage.jpg;
- content_type:内容类型(MIME 类型 / 媒体类型)字符串(str),例如,image/jpeg;
- file: SpooledTemporaryFile( file-like 对象)。其实就是 Python文件,可直接传递给其他预期 file-like 对象的函数或支持库。
- UploadFile 支持以下 async 方法,(使用内部 SpooledTemporaryFile)可调用相应的文件方法。
- write(data):把 data (str 或 bytes)写入文件;
- read(size):按指定数量的字节或字符(size (int))读取文件内容;
- seek(offset):移动至文件 offset (int)字节处的位置;
例如,await myfile.seek(0) 移动到文件开头;
执行 await myfile.read() 后,需再次读取已读取内容时,这种方法特别好用;
close():关闭文件。
因为上述方法都是 async 方法,要搭配「await」使用。
例如,在 async 路径操作函数 内,要用以下方式读取文件内容
`contents = await myfile.read()`
文件上传保存
pip install python-multipart
import os
import shutil
from pathlib import Path
from typing import Union, Any
from tempfile import NamedTemporaryFile
from fastapi import APIRouter, Depends, File, UploadFile
from api.common.logger import logger
f
from api.utils import response_code
router = APIRouter()
@router.post("/upload/file/", summary="上传图片")
async def upload_image(
file: UploadFile = File(...)
):
logger.info(f"用户{token_data.sub}->上传文件:{file.filename}")
# 本地存储临时方案,一般生产都是使用第三方云存储OSS(如七牛云, 阿里云)
save_dir = f"{settings.BASE_DIR}/assets"
if not os.path.exists(save_dir):
os.mkdir(save_dir)
try:
suffix = Path(file.filename).suffix
with NamedTemporaryFile(delete=False, suffix=suffix, dir=save_dir) as tmp:
shutil.copyfileobj(file.file, tmp)
tmp_file_name = Path(tmp.name).name
finally:
file.file.close()
return response_code.resp_200(data={"image": f"http://127.0.0.1:8010/assets/{tmp_file_name}"})
Last updated