使用uvicorn库的get_factory方法时出现"TypeError: 'NoneType' object is not callable"错误如何解决?

问题现象与背景

在Python异步Web开发中,uvicorn作为高性能ASGI服务器被广泛使用。get_factory()方法负责将用户提供的应用工厂转换为可调用对象,但开发者常会遇到以下报错:

Traceback (most recent call last):  
  File "main.py", line 15, in module  
    server = uvicorn.Server(config)  
  File "/uvicorn/server.py", line 60, in __init__  
    self.app_factory = get_factory(app)  
TypeError: 'NoneType' object is not callable

根本原因分析

该错误表明ASGI应用工厂未被正确初始化,具体可能由以下情况导致:

  • 工厂函数未返回可调用对象:应用工厂返回了None而非ASGI应用实例
  • 路径引用错误:使用字符串模块路径时导入失败(如"module:app_factory"格式错误)
  • 依赖注入缺失:工厂函数需要未提供的参数(数据库连接、配置对象等)
  • 生命周期事件冲突:在lifespan事件处理中意外返回None

解决方案

方案1:验证工厂函数返回值

确保工厂函数返回有效的ASGI可调用对象

# 正确的工厂模式示例  
def create_app():  
    from fastapi import FastAPI  
    app = FastAPI()  
    return app  # 必须返回ASGI兼容对象

方案2:检查模块导入语法

使用字符串路径时需确认:

  1. 模块文件存在且可导入
  2. 目标函数/类与路径声明一致(如"module:create_app"
  3. PYTHONPATH包含模块所在目录

方案3:实现参数化工厂

对于需要参数的工厂,使用闭包functools.partial

from functools import partial  

def app_factory(config):  
    app = FastAPI()  
    app.state.config = config  
    return app  

# 在uvicorn配置中  
config.app = partial(app_factory, config=settings)

深度优化建议

场景 检查点 工具推荐
复杂依赖 依赖项是否在工厂外初始化 pytest-dependency
异步环境 工厂是否包含未await的协程 aiocontextvars

预防措施

通过单元测试提前发现问题:

# 工厂函数测试用例示例  
def test_app_factory():  
    app = create_app()  
    assert callable(app), "工厂必须返回可调用ASGI应用"  
    # 模拟ASGI接口调用  
    scope = {"type": "http"}  
    async def receive(): return {}  
    async def send(*args): pass  
    import asyncio  
    asyncio.run(app(scope, receive, send))