Python WEB框架之FastAPI

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)

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

三、接受请求参数

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

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

2、使用Request对象传参

1)GET请求

from fastapi import FastAPI, Request

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

从fastapi库导入Request对象,使用Request对象作为接受参数,Request对象会把所有的参数都收集到query_params属性当中。
Python WEB框架之FastAPI_第2张图片
2)POST请求

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

需要注意的是这里需要将使用asyncawait关键字,然后强转为 dict类型,就可以愉快的使用啦。
Python WEB框架之FastAPI_第3张图片
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
        }
    }

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

前端上传文件示例代码:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
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>

示例结果:
Python WEB框架之FastAPI_第4张图片

四、跨域设定

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

*号部分可自由配置。

五、指定静态资源目录

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

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")

可通过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)

你可能感兴趣的:(python,前端,fastapi)