A-A+

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

2021年07月07日 00:43 学习笔记 暂无评论 共2799字 (阅读2,609 views次)

【注意:此文章为博主原创文章!转载需注意,请带原文链接,至少也要是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

布施恩德可便相知重

微信扫一扫打赏

支付宝扫一扫打赏

×

给我留言