A-A+
FastAPI 上传文件 保存文件方法 UploadFile示例详解

【注意:此文章为博主原创文章!转载需注意,请带原文链接,至少也要是txt格式!】
最近准备利用FastAPI写个系统,在研究upload上传文件,但是发现很多很多案例上传的点讲的并不详细,下面经过我自己的总结,把上传点详细分享给打家。直接看代码吧,非常直接。
主文件程序,名命为mian.py,代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | # -*- coding: utf-8 -*-
from typing import List
from starlette.requests import Request
from fastapi import FastAPI, Form, File, UploadFile
from starlette.templating import Jinja2Templates
import utils
app = FastAPI()
templates = Jinja2Templates(directory="templates")
upload_tmp_full = 'E:\\fastapi_xuexi\\'
@app.post("/files/")
async def files(
request: Request,
files_list: List[bytes] = File(...), # List多个文件
files_name: List[UploadFile] = File(...),
):
return templates.TemplateResponse("index.html",
{
"request": request,
"files_sizes": [len(file) for file in files_list], # 注意files_list是多个文件
"filenames": [file.filename for file in files_name]
}
)
@app.post("/create_file/")
async def create_file(
request: Request, # 单个文件
fileb: UploadFile = File(...),
notes: str = Form(...),
):
logs = []
content = await fileb.read()
file_name = fileb.filename
if len(content) > 0:
file_name = utils.standardization_filename(fileb.filename)
addr = upload_tmp_full + file_name
with open(addr, 'wb') as f:
f.write(content)
logs.append({'origin': fileb.filename, 'type': fileb.content_type, 'save_name': file_name})
else:
logs.append({'status': 'isn`t file'})
return templates.TemplateResponse("index.html",
{
"request": request,
"fileb_size": len(content),
"fileb_content_type": fileb.content_type,
"fileb_name": file_name,
"notes": notes,
"上传结果": logs
})
@app.get("/")
async def main(request: Request):
return templates.TemplateResponse('main.html', {"request": request, })
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host='0.0.0.0', port=80) |
次要python文件,名命为utils.py,代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | # -*- coding: utf-8 -*-
# __author__ = xieyunlong
# __Blog__ = https://woj.app
# __Date__ = 2021/7/7
from datetime import datetime, timezone, timedelta
import uuid
def get_standard_time() -> str:
return (datetime.now(timezone.utc) + timedelta(hours=8)).strftime('%Y-%m-%dT%H:%M:%S%z')
def get_string_time() -> str:
return (datetime.now(timezone.utc) + timedelta(hours=8)).strftime('%Y%m%d%H%M%S+z%f')
def generate_doc_id() -> str:
# 生成唯一编号,所有doc都将使用其作为doc_id
return str(uuid.uuid1())
def standardization_filename(origin_name) -> str:
splitted = origin_name.split('.')
if len(splitted) >= 2:
return splitted[0] + '_' + get_string_time() + '.' + splitted[-1]
return splitted[0] + '_' + get_string_time() + '.unknown'
def standardization_filename2taskname(name) -> str:
splitted = name.split('_')
# 保留原名称中的_,去除正规化后附加的时间及原后缀
return "_".join(splitted[0:-1])
def standardization_filename(origin_name) -> str:
splitted = origin_name.split('.')
if len(splitted) >= 2:
return splitted[0] + '_' + get_string_time() + '.' + splitted[-1]
return splitted[0] + '_' + get_string_time() + '.unknown' |
要在当前主文件下面建立一个目录,名字为“templates”,在目录里放入如下两个Html文件。
名命为:main.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传页</title>
</head>
<body>
<form action="/files/" enctype="multipart/form-data" method="post">
<input name="files_list" type="file" multiple><br><br>
<input name="files_name" type="file" multiple><br><br>
<input type="submit" value="点击这里显示文件名字与大小">
</form>
<br><br><br>
<form action="/create_file/" enctype="multipart/form-data" method="post">
<input name="fileb" type="file" multiple><br><br>
<input name="notes" type="text" multiple><br><br>
<input type="submit" value="点击这里显示文件属性">
</form>
</body>
</html> |
命名为:index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传之后的页面</title>
</head>
<body>
<div class="container">
<h1>NO.1</h1>
<h2>File Name:{{ filenames }}</h2>
<h2>File Size:{{ file_sizes }}</h2>
<h1>NO.2</h1>
<h2>File Size:{{ fileb_size }}</h2>
<h2>File Type:{{ fileb_content_type }}</h2>
<h2>File Name:{{ fileb_name }}</h2>
<h2>File Notes:{{ notes }}</h2>
<h2>上传结果:{{ 上传结果 }}</h2>
</div> <!-- /container -->
</body>
</html> |
部分代码参考:https://github.com/kaikai03/inpainting_backen
布施恩德可便相知重
微信扫一扫打赏
支付宝扫一扫打赏