FastAPI双端口运行异常:主API被辅助API覆盖问题求助
我有一个分散在三个代码仓库的项目,其中两个仓库包含API:主API和被主API调用的辅助API。两者均基于FastAPI(fastapi==0.89.0)实现,使用Python 3.9.12与VSCode开发,仓库结构类似:
两个API仓库的结构
|__ app |__ main.py |__ routers.py |__ # 部分子文件夹
每个仓库都有独立的虚拟环境,非API仓库的源码以可编辑模式(pip install -e)安装到两个API的虚拟环境中。主API运行在8000端口,辅助API运行在8005端口:
主API(仓库1)的main.py
import uvicorn from fastapi import FastAPI from gunicorn.http import message from app.routers import router app = FastAPI(description="main API") app.include_router(router) if __name__ == "__main__": uvicorn.run(app, host="127.0.0.1", port=8000)
辅助API(仓库2)的main.py
from fastapi import FastAPI import uvicorn from gunicorn.http import message from app.routers import router # fastapi app app = FastAPI( title="helper API") app.include_router(router) if __name__ == "__main__": uvicorn.run(app, host="127.0.0.1", port=8005)
两个仓库的routers.py脚本基本一致,仅include_router传入的tags不同:
from fastapi import APIRouter from app.pipeline import view router = APIRouter() router.include_router(view.router, tags=["different tag here"])
在不同终端运行两个main.py脚本后,终端输出日志符合预期:
辅助API终端日志
INFO: Started server process [4650] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8005 (Press CTRL+C to quit)
主API终端日志
INFO: Started server process [4681] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
但访问http://127.0.0.1:8000/docs时,显示的却是辅助API的端点而非主API的。辅助API的端点可在8000和8005两个端口访问,而主API的端点无处可访问。起初怀疑是VSCode设置问题,但搜索后未找到解决办法,求问如何修复?
1. 排查虚拟环境的包依赖冲突
两个API仓库的顶级包名均为app,如果主API的虚拟环境中意外安装了辅助API的可编辑包(比如误执行pip install -e ../辅助API仓库路径),会导致Python导入时优先加载site-packages中的辅助APIapp模块,而非当前仓库本地的app模块。
- 激活主API的虚拟环境,执行
pip list查看已安装包,确认没有包含辅助API仓库的代码; - 如果存在错误安装的包,执行
pip uninstall 包名移除,确保仅安装了非API仓库的可编辑包。
2. 修改包名避免命名冲突
将两个API仓库的顶级包名改为不同名称(比如主API改为main_api,辅助API改为helper_api),彻底解决同名包的导入冲突:
- 重命名仓库根目录下的
app文件夹为新名称; - 修改
main.py、routers.py中的导入路径(比如from main_api.routers import router); - 确保非API仓库的包名与两个API的包名均不重复。
3. 验证运行环境与工作目录
- 运行主API前,确认已激活对应虚拟环境,且工作目录处于主API仓库的根目录(即包含重命名后的包文件夹的目录);
- 在
main.py开头添加以下代码,打印Python的导入路径,确认本地包目录优先级高于site-packages:
如果本地仓库目录不在import sys print("Python导入路径:", sys.path)sys.path的前列,可以手动添加:import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent.parent))
4. 清除浏览器缓存
浏览器可能缓存了旧的OpenAPI文档页面,尝试用隐私模式访问http://127.0.0.1:8000/docs,或手动清除浏览器缓存后重试。
内容的提问来源于stack exchange,提问作者mr_faulty

