返回顶部

Fastapi 迁移模型、token 认证、中间件、CORS、后台任务、测试用例

alembic 迁移模型

pip install alembic=1.13.1

 初始化Alembic 项目

alembic init alembic

会生成alebic.ini文件 修改里面的数据库连接

[alembic]
script_location = alembic
sqlalchemy.url = mysql+pymysql://david:123456@localhost/summary

[loggers]
keys = root

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARN
handlers = console
qualname =

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
alembic.ini

alembic/env.py,修改meatadata中的信息,是target_matadata指向项目中真实的路径

from models import Base
target_metadata = Base.metadata

创建一个表,生成迁移文件

alembic revision --autogenerate -m "create_user_table"

执行迁移

alembic upgrade head 

后续添加字段只需重复执行下面的两条命令即可

alembic revision --autogenerate -m "add phone field to user"

alembic upgrade head 

用户认证

from fastapi import FastAPI, Security, HTTPException
from fastapi.security import APIKeyHeader
 
app = FastAPI()
 
api_key = APIKeyHeader(name="api_key")
 
 
@app.get("/protected")
async def protected_route(api_key: str = Security(api_key)):
    if api_key != "your_api_key":
        raise HTTPException(status_code=401, detail="Invalid API key")
    return current_user

常用中间件

from fastapi.middleware.cors import CORSMiddleware

@app.middleware('http')
async def add_process_time_header(request: Request, call_next):  # call_next将接收request请求做为参数
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers['X-Process-Time'] = str(process_time)  # 添加自定义的以“X-”开头的请求头
    return response


app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "*"
    ],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

实现类似celery 的后台任务

BackgroundTasks 开启后台任务

from typing import Optional

from fastapi import APIRouter, BackgroundTasks, Depends

app08 = APIRouter()


def bg_task(framework: str):
    with open("README.md", mode="a") as f:
        f.write(f"test")


@app08.post("/background_tasks")
async def run_bg_task(framework: str, background_tasks: BackgroundTasks):
    """
    :param framework: 被调用的后台任务函数的参数
    :param background_tasks: FastAPI.BackgroundTasks
    :return:
    """
    background_tasks.add_task(bg_task, framework)
    return {"message": "任务已在后台运行"}

引入其他的BackgroundTasks 

#!/usr/bin/python3
# -*- coding:utf-8 -*-
# __author__ = '__Jack__'

from typing import Optional

from fastapi import APIRouter, BackgroundTasks, Depends

app08 = APIRouter()


"""Background Tasks 后台任务"""


def bg_task(framework: str):
    with open("README.md", mode="a") as f:
        f.write(f"test")


def continue_write_readme(background_tasks: BackgroundTasks, q: Optional[str] = None):
    if q:
        background_tasks.add_task(bg_task, "\n> 整体的介绍 FastAPI,快速上手开发,结合 API 交互文档逐个讲解核心模块的使用\n")
    return q


@app08.post("/dependency/background_tasks")
async def dependency_run_bg_task(q: str = Depends(continue_write_readme)):
    if q:
        return {"message": "README.md更新成功"}
需要注意的点,不要在后台任务中使用depends
def bg_task(url: HttpUrl, db: Session):
    """这里注意一个坑,不要在后台任务的参数中db: Session = Depends(get_db)这样导入依赖"""

编写单元测试用例

#!/usr/bin/python3
# -*- coding:utf-8 -*-
# __author__ = '__Jack__'

from fastapi.testclient import TestClient

from run import app

"""Testing 测试用例"""

client = TestClient(app)  # 先pip install pytest


def test_run_bg_task():  # 函数名用“test_”开头是 pytest 的规范。注意不是async def
    response = client.post(url="/chapter08/background_tasks?framework=FastAPI")
    assert response.status_code == 200
    assert response.json() == {"message": "任务已在后台运行"}


def test_dependency_run_bg_task():
    response = client.post(url="/chapter08/dependency/background_tasks")
    assert response.status_code == 200
    assert response.json() is None


def test_dependency_run_bg_task_q():
    response = client.post(url="/chapter08/dependency/background_tasks?q=1")
    assert response.status_code == 200
    assert response.json() == {"message": "README.md更新成功"}

 

posted @ 2024-06-12 16:00  Crazymagic  阅读(3)  评论(0编辑  收藏  举报