FastAPI中API-key校验异步函数的原因及单元测试方法咨询
FastAPI API-Key校验函数的疑问解答
1. 无await的async函数:目的、机制与def的区别
- 为什么定义为async?
核心是预留扩展性。当前的校验逻辑是纯同步的,但如果后续需要加入异步操作——比如从Redis异步查询合法密钥、调用第三方异步验证接口——直接在函数里加await即可,不用修改函数定义和所有端点的依赖引用,避免后续重构的麻烦。 - 工作机制
哪怕函数内部没有await,FastAPI也会把这个异步协程提交到ASGI事件循环中执行;而用def定义的同步函数,FastAPI会将其放到线程池里运行,多了一层线程切换的开销。 - 和def定义的差异
- 同步依赖(
def):适合纯同步逻辑,但后续要扩展异步逻辑时,必须把def改成async,虽然端点引用无需修改,但统一异步风格更省心。 - 异步依赖(
async):直接在事件循环执行,性能略优,且天然支持后续扩展异步逻辑,这也是很多开发者宁愿现在用async的原因。
- 同步依赖(
2. 异步函数的单元测试方法
不用通过API端点,直接测试这个异步函数可以借助pytest-asyncio实现,步骤如下:
1. 安装测试依赖
pip install pytest pytest-asyncio
2. 编写测试用例
假设校验函数在main.py中,新建test_main.py编写测试代码:
import pytest from fastapi import HTTPException from main import get_api_key, config_env # 测试合法API密钥场景 @pytest.mark.asyncio async def test_valid_api_key(): result = await get_api_key(api_key_header=config_env["API_KEY"]) assert result == config_env["API_KEY"] # 测试非法API密钥场景 @pytest.mark.asyncio async def test_invalid_api_key(): with pytest.raises(HTTPException) as exc_info: await get_api_key(api_key_header="wrong_key") assert exc_info.value.status_code == 403 assert exc_info.value.detail == "Could not validate API KEY"
3. 运行测试
pytest test_main.py -v
核心逻辑是用@pytest.mark.asyncio标记异步测试函数,然后用await直接调用异步依赖函数——测试时无需走真实请求流程,手动传参即可模拟请求头的输入。
内容的提问来源于stack exchange,提问作者SHAO CHUN CHENG
相关产品推荐
相关产品推荐

