当前位置:   article > 正文

Python WEB框架之FastAPI_fastapi python-multipart

fastapi python-multipart

Python WEB框架之FastAPI

今天想记录一下最近项目上一直在用的Python框架——FastAPI。

个人认为,FastAPI是我目前接触到的Python最好用的WEB框架,没有之一。

之前也使用过像Django、Flask等框架,但是Django就用起来太重了,各种功能都糅杂在一起;Flask 框架虽说简单,但又只是单线程需要自己改造才支持多并发。

FastAPI貌似结合弥补了Flask 框架的缺陷,如果你想要快速搭建一个WEB服务,用FastAPI准没错。

OK,开始今天的笔记。

一、安装FastAPI

pip install fastapi uvicorn python-multipart

二、示例代码

from fastapi import FastAPI
import uvicorn

app = FastAPI()


@app.get("/")
def index():
    return "Hello World"


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

运行起来之后,您应该会看到下面的画面:
在这里插入图片描述
浏览器访问你的ip地址加端口号,应该就能看到“Hello World”。
在这里插入图片描述

三、接受请求参数

1、直接通过参数名接受,参数名即传参的名称。
@app.get("/info")
def handle_info(name, age):
    return f"Hello World, {name}, {age}"
  • 1
  • 2
  • 3

这种方式必须接受name和age参数,如果缺少参数则会看到以下错误:
在这里插入图片描述
适用于GET请求且参数固定的情况,并且可以省去自己验证必要参数的步骤。
正常传递后则不会发生错误:
在这里插入图片描述

2、使用Request对象传参

1)GET请求

from fastapi import FastAPI, Request

@app.get("/request")
def handle_info(params: Request):
    return params.query_params
  • 1
  • 2
  • 3
  • 4
  • 5

从fastapi库导入Request对象,使用Request对象作为接受参数,Request对象会把所有的参数都收集到query_params属性当中。
在这里插入图片描述
2)POST请求

@app.post("/request")
async def handle_info(params: Request):
    form = dict(await params.form())
    return form
  • 1
  • 2
  • 3
  • 4

需要注意的是这里需要将使用asyncawait关键字,然后强转为 dict类型,就可以愉快的使用啦。
在这里插入图片描述
3)文件上传

# 图片批量上传
@app.post('/upload')
async def upload_file(params: Request, files: List[UploadFile] = File(...)):
    form = dict(await params.form())
    save_files = []
    for file in files:
        temp_arr = file.filename.split(".")
        suffix = temp_arr[len(temp_arr) - 1]
        file_name = f"img_{datetime.now().strftime('%Y%m%d%H%M%S%f')}.{suffix}"
        with open(file_name, "wb") as f:
            content = await file.read()  # 读取上传文件的内容
            f.write(content)  # 将内容写入文件
            save_files.append(file_name)
    return {
        "code": 200,
        "data": {
            "params": form,
            "save_files": save_files
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

实例为图片批量上传示例,使用Request对象进行接收,同时上传的文件也会被映射到files参数中。
可通过file.read() 读取文件内容,file.filename可拿到上传的文件名。
单文件上传,个人觉得可以沿用。

前端上传文件示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <input type="file" name="" id="file" multiple onchange="upload()">
    <div id="output"></div>
</body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
    let upload = () => {
        let el_file = document.querySelector("#file")
        let output = document.querySelector("#output")
        const form = new FormData();
        for (let i = 0; i < el_file.files.length; i++) {
            form.append('files', el_file.files[i]);
        }
        form.append("name", "zhangsan");
        form.append("age", 20);
        this.uploadStage = true;
        axios.post('http://127.0.0.1:8000/upload', form, {
            headers: { 'Content-Type': 'multipart/form-data' }
        }).then(res => {
            output.innerHTML = JSON.stringify(res.data)
        }).catch(err => {
            output.innerHTML = JSON.stringify(err)
        });
    }
</script>
</html>
  • 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

示例结果:
在这里插入图片描述

四、跨域设定

from starlette.middleware.cors import CORSMiddleware
# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

*号部分可自由配置。

五、指定静态资源目录

from fastapi.staticfiles import StaticFiles
app.mount("/static", StaticFiles(directory="static"), name="static_resources")
  • 1
  • 2

static目录挂载为静态目录,当访问 /static时直接返回该文件内容。
把上述文件上传的示例文件index.html放到static文件夹下,则可直接通过 /static/index.html 访问。

※ fastapi已经做了循环挂载,所以static下的子文件夹也会被一起挂载成静态资源。

在这里插入图片描述

六、返回文件

from starlette.responses import FileResponse

@app.get("/index")
def home():
    return FileResponse("static/index.html")
  • 1
  • 2
  • 3
  • 4
  • 5

可通过FileResponse类返回指定文件的内容。用于做图片的预览、文件下载等功能。
现在也可以通过 /index 访问到 static/index.html 文件了。
在这里插入图片描述
以上,就是本次用到的fastapi 框架的相关内容。
相信以上知识已经足够解决日常的开发问题,希望看到的小伙伴不迷路。
欢迎大家留言探讨。

最后,奉上完整示例代码:

from datetime import datetime
from typing import List

from fastapi import FastAPI, Request, UploadFile, File
import uvicorn
from starlette.middleware.cors import CORSMiddleware
from starlette.responses import FileResponse
from starlette.staticfiles import StaticFiles

app = FastAPI()
# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

app.mount("/static", StaticFiles(directory="static"), name="static_resources")


@app.get("/")
def index():
    return "Hello World"


@app.get("/index")
def home():
    return FileResponse("static/index.html")


@app.get("/info")
def handle_info(name, age):
    return f"Hello World, {name}, {age}"


@app.post("/request")
def handle_info(params: Request):
    return params.query_params


@app.post("/request")
async def handle_info1(params: Request):
    form = dict(await params.form())
    return form


# 图片批量上传
@app.post('/upload')
async def upload_file(params: Request, files: List[UploadFile] = File(...)):
    form = dict(await params.form())
    save_files = []
    for file in files:
        temp_arr = file.filename.split(".")
        suffix = temp_arr[len(temp_arr) - 1]
        file_name = f"img_{datetime.now().strftime('%Y%m%d%H%M%S%f')}.{suffix}"
        with open(file_name, "wb") as f:
            content = await file.read()  # 读取上传文件的内容
            f.write(content)  # 将内容写入文件
            save_files.append(file_name)
    return {
        "code": 200,
        "data": {
            "params": form,
            "save_files": save_files
        }
    }


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
  • 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
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/892280
推荐阅读
相关标签
  

闽ICP备14008679号