FastAPI使用教程【更新中】

文章目录

  • 一、安装命令
  • 二、模板
  • 三、启动命令
  • 四、访问测试
    • 1.访问服务
    • 2.访问API文档
  • 五、参数方法详解
    • 1.路径参数
    • 2.指定数据类型的路径参数
    • 3.枚举路径参数
    • 4.匹配所有路径
    • 5.普通传参
    • 6.必备参数
    • 7.可选参数
    • 8.布尔参数
    • 9.使用数据模型
    • 10.待补充
  • 六、静态文件存储
  • 七、文件上传
    • 1.上传方式一
    • 2.上传方式二
  • 八、接口路由
  • 九、跨域请求配置
  • 十、websocket应用
  • 十一、【中间件】返回接口响应时长


一、安装命令

pip install fastapi uvicorn

二、模板

创建 main.py 文件,内容如下

from pydantic import BaseModel
from fastapi import FastAPI

# 创建服务对象
app = FastAPI()

# get --------------------------------
@app.get("/")
async def hello():
    return {"message": "Hello World"}
# ------------------------------------

# post ------------------------------------------------------
class Publication(BaseModel):
    title: str
    abstract: str
@app.post("/findPublication")
async def findPublication(pc: Publication):
    return {"message": "{}-{}".format(pc.title, pc.abstract)}
# -----------------------------------------------------------

if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app="main:app", host="127.0.0.1", port=8000, reload=True)


三、启动命令

直接右键启动就行,或者使用如下命令启动

uvicorn main:app --host 0.0.0.0 --port 80 --reload

ps:

  1. uvicorn:是一个基于asyncio开发的一个轻量级高效的web服务器框架
  2. main:启动服务的py文件名
  3. app:服务对象名
  4. –host:ip地址
  5. –port:端口
  6. –reload:代码修改的时候自动重启服务,仅在开发时使用,上线后不要带这个参数,会降低性能

四、访问测试

1.访问服务

127.0.0.1:8000
FastAPI使用教程【更新中】_第1张图片

2.访问API文档

  1. 127.0.0.1:8000/docs【Swagger UI 提供的api文档】
    FastAPI使用教程【更新中】_第2张图片

  2. 127.0.0.1:8000/redoc【ReDoc 提供的api文档】
    FastAPI使用教程【更新中】_第3张图片


五、参数方法详解

1.路径参数

<1>代码

@app.get("/items/{item_id}")
async def read_item(item_id):
    return {"item_id": item_id}

<2>调用方法

ip:port/items/3

2.指定数据类型的路径参数

<1>代码

@app.get("/items/{item_id}")
async def read_item(item_id: int): # 以整数类型接收
    return {"item_id": item_id}
@app.get("/users/{user_id}")
async def read_user(user_id: str): # 以字符串类型接收
    return {"user_id": user_id}

<2>调用方法

ip:port/items/3
ip:port/users/2

3.枚举路径参数

<1>代码

class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"
    
@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
    if model_name == ModelName.alexnet:
        return {"model_name": model_name, "message": "Deep Learning FTW!"}

    if model_name.value == "lenet":
        return {"model_name": model_name, "message": "LeCNN all the images"}

    return {"model_name": model_name, "message": "Have some residuals"}

<2>调用方法

ip:port/models/alexnet
ip:port/models/resnet
ip:port/models/lenet

4.匹配所有路径

<1>代码

@app.get("/files/{file_path:path}")  # :path 代表任意路径
async def read_file(file_path: str):
    return {"file_path": file_path}

<2>调用方法

ip:port/files/abc/234/r
ip:port/files/fasdf/a
ip:port/files/nn

5.普通传参

<1>代码

@app.get("/items")
async def read_item(skip: int = 0, limit: int = 10):
    return {"skip": skip, "limit": limit}

<2>调用方法

ip:port/items?skip=0&limit=3
ip:port/items   				# 使用默认值 skip=0,limit=10
ip:port/items?skip=&limit=		# 报错

6.必备参数

<1>代码

@app.get("/items")
async def read_item(skip: int):
    return {"skip": skip}

<2>调用方法

ip:port/items?skip=0
ip:port/items   # 报错

7.可选参数

<1>代码

from typing import Union

@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None):
    if q:
        return {"item_id": item_id, "q": q}
    return {"item_id": item_id}

<2>调用方法

ip:port/items/3?q=haoye
ip:port/items/3   # q默认为None

8.布尔参数

<1>代码

@app.get("/items/{item_id}")
async def read_item(item_id: str, short: bool = False):
    item = {"item_id": item_id}
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item

<2>调用方法

ip:port/items/3?short=true
ip:port/items/3?short=false
ip:port/items/3?short=True
ip:port/items/3?short=False
ip:port/items/3?short=1
ip:port/items/3?short=0
ip:port/items/3?short=haoye  # 报错
ip:port/items/3?short=2		 # 报错

9.使用数据模型

<1>代码

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

class Item(BaseModel):
    name: str
    description: Union[str, None] = None
    price: float
    tax: Union[float, None] = None

app = FastAPI()

@app.get("/items/")
async def create_item(item: Item):
    return item

<2>调用方法

ip:port/items/?name=Foo&description=onedescription&price=45.2&tax=3.5

10.待补充

已经在写了(旺柴)


六、静态文件存储


from fastapi import FastAPI

# 导包
from fastapi.staticfiles import StaticFiles


app = FastAPI()

# 配置静态文件路径 ----------------------------------------------------
app.mount("/static", StaticFiles(directory="static"), name="static")
# -------------------------------------------------------------------


if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app="main:app", host="0.0.0.0", port=8000, reload=True)


ps:

  1. “/static”:url访问的路径,例如 192.168.0.233:5000/static/abc.jpg
  2. StaticFiles(directory=“static”):静态文件的根目录文件夹名称
  3. name=“static”:FastAPI的内部使用名称

七、文件上传

main.py

from fastapi import FastAPI, UploadFile
from fastapi.staticfiles import StaticFiles
import os

app = FastAPI()

# 配置静态文件路径 ----------------------------------------------------
app.mount("/static", StaticFiles(directory="static"), name="static")
# ------------------------------------------------------------------


@app.post("/file_upload")
async def file_upload(file: UploadFile):

    # 接收文件
    res = await file.read()

    # 写到本地
    predict_img_path = os.path.join('static', file.filename)
    with open(predict_img_path, "wb") as f:
        f.write(res)

    return {"code": 1, "msg": "上传成功:{}".format(file.filename)}


if __name__ == '__main__':

    import uvicorn
    uvicorn.run(app="main:app", host="0.0.0.0", port=2333)


1.上传方式一

import requests
import json


if __name__ == '__main__':

    # 上传一张图
    file_path = r'E:\工具测试数据\封面上传测试\img\1825513ec0b.png'
    url = "http://127.0.0.1:2333/file_upload"

    data = {"file": open(file_path, 'rb')}
    res = requests.post(url=url, files=data, verify=False)
    print(json.loads(res.content))
    # {'code': 1, 'msg': '上传成功:7f63f6711f5f57d9.jpg'}

2.上传方式二

import requests
import json
import os
from urllib3 import encode_multipart_formdata


if __name__ == '__main__':

    # 上传一张图
    file_path = r'E:\工具测试数据\封面上传测试\img\1825513ec0b.png'
    url = "http://127.0.0.1:2333/file_upload"

    with open(file_path, 'rb') as f:
        file_name = os.path.split(file_path)[-1]
        file = {"file": (file_name, f.read())}
        encode_data = encode_multipart_formdata(file)
        data = encode_data[0]
        content_type = encode_data[1]
        headers = {
            'Content-Type': content_type
        }
        res = requests.post(url, headers=headers, data=data)
        print(json.loads(res.content))
        # {'code': 1, 'msg': '上传成功:1825513ec0b.png'}


八、接口路由

可以参考这篇文章
https://blog.csdn.net/weixin_43721000/article/details/128051445


九、跨域请求配置

from fastapi.middleware.cors import CORSMiddleware


# 跨域中间件
app.add_middleware(
	CORSMiddleware,
	# 允许跨域的源列表,例如 ["http://www.example.org"] 等等,["*"] 表示允许任何源
	allow_origins=["*"],
	# 跨域请求是否支持 cookie,默认是 False,如果为 True,allow_origins 必须为具体的源,不可以是 ["*"]
	allow_credentials=False,
	# 允许跨域请求的 HTTP 方法列表,默认是 ["GET"]
	allow_methods=["*"],
	# 允许跨域请求的 HTTP 请求头列表,默认是 [],可以使用 ["*"] 表示允许所有的请求头
	# 当然 Accept、Accept-Language、Content-Language 以及 Content-Type 总之被允许的
	allow_headers=["*"],
	# 可以被浏览器访问的响应头, 默认是 [],一般很少指定
	# expose_headers=["*"]
	# 设定浏览器缓存 CORS 响应的最长时间,单位是秒。默认为 600,一般也很少指定
	# max_age=1000
)

十、websocket应用

可以参考这篇文章
https://blog.csdn.net/weixin_43721000/article/details/128163408


十一、【中间件】返回接口响应时长

加入这个中间价后,每个接口返回时会在返回头的 X-Process-Time 字段中插入接口耗时

import time

from fastapi import FastAPI, Request

app = FastAPI()


@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

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