AWS AppRunner部署Python 3.11应用时出现ModuleNotFoundError: No module named 'fastapi'错误
问题描述
我刚接触AWS AppRunner,想部署一个简单的FastAPI端点来做测试,我的main.py代码如下:
from fastapi import FastAPI import uvicorn from pydantic import BaseModel import numpy as np app = FastAPI() class InputNumber(BaseModel): value: float @app.post("/sqrt") async def compute_sqrt(input_data: InputNumber): result = np.sqrt(input_data.value) return {"result": float(result)} if __name__ == '__main__': uvicorn.run(app, port=8080, host='0.0.0.0')
对应的requirements.txt:
fastapi uvicorn[standard] numpy pydantic
一开始我用Python 3部署,用以下命令:
- 构建命令:
pip install -r requirements.txt - 启动命令:
python main.py
一切都正常。后来我尝试用Python 3.11部署,命令改成: - 构建命令:
pip3 install -r requirements.txt - 启动命令:
python3 main.py
构建过程没问题,但部署启动时出现了意外错误:
ModuleNotFoundError: No module named 'fastapi'
构建是成功的(日志里能看到所有依赖都下载安装了),就算给requirements.txt里的库加上版本号,还是出现同样的错误。我没有用Docker,求帮忙!
解决方案
这个问题我之前碰到过好几次,核心原因基本是**pip3和python3没有关联到同一个Python 3.11环境**,导致依赖装到了python3找不到的目录里。给你几个靠谱的解决办法,按推荐顺序尝试:
1. 用python3 -m pip替代pip3安装依赖
把构建命令修改为:
python3 -m pip install -r requirements.txt
原理:直接用pip3可能会指向系统中其他版本的Python(比如AppRunner环境里可能预装了多个Python版本),而python3 -m pip会强制调用当前python3命令对应的解释器的pip工具,这样依赖肯定会被安装到python3能识别的site-packages目录中,启动时就不会出现找不到模块的问题了。
2. 改用uvicorn模块启动(官方推荐方式)
把启动命令换成FastAPI官方推荐的uvicorn模块启动方式,替代直接运行main.py:
python3 -m uvicorn main:app --host 0.0.0.0 --port 8080
这种方式不仅能规避Python环境路径的问题,还能获得更稳定的启动效果,比直接运行脚本文件更可靠。
3. 排查依赖安装情况(用于定位深层问题)
如果上面两个方案没解决问题,你可以先修改启动命令,先打印已安装的依赖列表,确认fastapi是否真的被安装:
pip3 list && python3 main.py
然后去AppRunner的部署日志里查看pip3 list的输出:
- 如果日志里没有
fastapi,说明构建阶段的安装确实失败了(虽然日志显示成功,但可能有隐藏问题); - 如果有
fastapi,那就是PYTHONPATH的问题,这时候可以在启动命令前手动添加依赖目录到PYTHONPATH:
这个命令会自动获取当前Python版本的用户export PYTHONPATH=$(python3 -c "import site; print(site.getusersitepackages())"):$PYTHONPATH && python3 main.pysite-packages目录,并添加到环境变量中,确保启动时能找到依赖。
4. 尝试统一用python替代python3
在AppRunner的Python 3.11运行时环境中,python命令可能已经默认指向Python 3.11了,你可以把构建和启动命令里的pip3、python3全部换成pip、python试试:
- 构建命令:
pip install -r requirements.txt - 启动命令:
python main.py
有时候这种统一的命令反而能避免版本混淆的问题。
备注:内容来源于stack exchange,提问作者ibra

