可随意转载Update2023.03.28

前言

fastapi是一个python的RESTFul工具。

一、安装

pip install fastapi[all]

上面命令同时安装了web容器uvicorn。

二、启动

编写程序:

from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
    return {"message": "Hello World"}

保存为文件test1.py

使用命令启动程序:uvicorn test1:app –reload

打开链接:http://127.0.0.1:8000/docs 查看swagger格式的RESTFul API界面。

打开链接:http://127.0.0.1:8000/redoc 查看文档。

三、功能测试

编写test2.py

from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id}

使用命令启动程序:uvicorn test2:app –reload

打开链接: http://127.0.0.1:8000/items/3 查看结果:

{"item_id":3}

注意:item_id的类型为int,如果输入字符串会返回错误类型的提示信息。这项能力来源于Pydantic库。

编写test3.py

from fastapi import FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
    return fake_items_db[skip : skip + limit]

使用命令启动程序:uvicorn test3:app –reload

打开链接: http://127.0.0.1:8000/items?skip=0&limit=10 查看结果:

[{"item_name":"Foo"},{"item_name":"Bar"},{"item_name":"Baz"}]

编写test4.py

from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    description: Union[str, None] = None
    price: float
    tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
    return item

使用命令启动程序:uvicorn test4:app –reload

将数据

{
    "name": "Foo",
    "price": 45.2
}

POST 到地址 http://127.0.0.1:8000/docs 并查看结果

四、文件/图片上传

4.1 安装依赖

pip install python-multipart

4.2 单张图片上传

编写后台程序test5.py

from typing import List
import uvicorn
from fastapi import FastAPI, File, UploadFile
from starlette.responses import HTMLResponse
app = FastAPI()
@app.post('/uploadFile')
async def uploadFile(file: UploadFile = File(...)):
    """缺少验证是否上传文件"""
    content = await file.read()
    with open('./test.jpg', 'wb') as f:
        f.write(content)
 
    return {"filename": file.filename}

编写前端页面test5.html

<html>
    <title>
        test file upload
    </title>
    <body>
        <form action="http://127.0.0.1:8000/uploadFile/" enctype="multipart/form-data" method="post">
        <input name="file" type="file">
        <input type="submit" value="uploadFile上传">
        </form>
        </body>
</html>

4.3 多张图片上传

from typing import List
import uvicorn
 
from fastapi import FastAPI, File, UploadFile
from starlette.responses import HTMLResponse
 
app = FastAPI()
 
@app.post("/uploadfiles/")
async def create_upload_files(
    files: List[UploadFile] = File(...)
):

    # todo: 实现多张图片保存
    return {"filenames": [file.filename for file in files]}


@app.get("/")
async def main():
    content = """
<body>
<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit" value="uploadfiles上传">
</form>
</body>
 """
    return HTMLResponse(content=content)
 
if __name__ == '__main__':
    uvicorn.run(app)

附录

FastAPI (官网)

Q1:FastAPI库并行与并发问题?

A1:FastAPI会对路径操作函数(path operation function)和依赖(dependencies)进行特殊处理。这个特殊处理是:如果你把函数定义为def而不是async def,那么FastAPI会把它放到单独的线程池中,异步执行,这就是FastAPI精彩的地方。就像官方所说,如果你不清楚你函数里面的调用是不是异步(能不能用await),那么就把它定义为普通函数,FastAPI会采用多线程的方式处理。乱用async,在async里面有同步调用,则会变成串行,Fast秒变Slow。

分类: python