使用pyinstaller打包fastapi项目的问题记录
文章目录
- PyInstaller 相关介绍
- 作用
- 使用方式
- Spec 文件介绍
- FastAPI 相关介绍
- 什么是 FastAPI?
- 使用方式
- 使用 PyInstaller 打包 FastAPI 项目
- 常见问题与解决方案
PyInstaller 相关介绍
作用
PyInstaller 是一个将 Python 程序打包成独立可执行文件的工具,支持 Windows、Linux 和 macOS。它的核心功能包括:
- 跨平台兼容:生成的可执行文件无需用户安装 Python 环境。
- 依赖自动收集:自动分析代码并捆绑所需的第三方库和资源文件。
- 支持单文件/多文件模式:可选择生成单个可执行文件或包含依赖的目录结构。
使用方式
-
安装:
pip install pyinstaller
-
基本命令:
- 单文件模式(适合简单脚本):
pyinstaller --onefile your_script.py
- 多文件模式(默认,适合复杂项目):
pyinstaller your_script.py
- 常用参数:
--name
: 指定生成的可执行文件名称。--add-data
: 添加非代码文件(如配置文件、模板)。--hidden-import
: 显式声明隐式导入的模块(如动态导入的库)。
- 单文件模式(适合简单脚本):
Spec 文件介绍
运行 PyInstaller 后会自动生成 .spec
文件,控制打包流程。主要参数:
# -*- mode: python ; coding: utf-8 -*-a = Analysis(['D:\\xujiaomiao\\fastapi_project\\app\\main.py'],pathex=[],binaries=[],datas=[('app/templates/index.html', 'templates'), ('app/static/style.css', 'static')],hiddenimports=[],hookspath=[],hooksconfig={},runtime_hooks=[],excludes=[],noarchive=False,optimize=0,
)
pyz = PYZ(a.pure)exe = EXE(pyz,a.scripts,a.binaries,a.datas,[],name='main',debug=False,bootloader_ignore_signals=False,strip=False,upx=True,upx_exclude=[],runtime_tmpdir=None,console=True,disable_windowed_traceback=False,argv_emulation=False,target_arch=None,codesign_identity=None,entitlements_file=None,uac_admin=True,
)
FastAPI 相关介绍
什么是 FastAPI?
FastAPI 是一个现代、高性能的 Python Web 框架,特点包括:
- 基于类型提示:自动请求参数验证和序列化。
- 异步支持:原生支持
async/await
,适合高并发场景。 - 自动生成 API 文档:集成 Swagger UI 和 Redoc。
使用方式
-
安装:
pip install fastapi uvicorn
-
基础示例:
from fastapi import FastAPIapp = FastAPI()@app.get("/") def read_root():return {"Hello": "World"}if __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=8000)
-
运行:
uvicorn main:app --reload
使用 PyInstaller 打包 FastAPI 项目
常见问题与解决方案
-
运行方式的问题:
-
打包程序时,程序里面是使用uvicorn.run(“main:app”, host=“127.0.0.1”, port=8080) 启动fastapi项目:
- 遇到问题:Error loading ASGI app. Could not import module “main”.
-
打包程序时,程序里面是使用uvicorn.run(“main:app”, host=“127.0.0.1”, port=8080) 启动fastapi项目:
- 遇到问题:
- Uvicorn running on 1mhttp://127.0.0.1:8000 (Press CTRL+C to quit)
- Started reloader process 36m1m12764 using 36mmStatReload0m
- Will watch for changes in these directories: 工作目录
- 遇到问题:
-
打包程序时,程序里面是使用uvicorn.run(app, host=“127.0.0.1”, port=8000)或者启动fastapi项目:
- uvicorn.run(app, host=“127.0.0.1”, port=8000)
- uvicorn.run(“__main__:app”, host=“127.0.0.1”, port=8000)
- 成功启动
-
这是为什么呢?
-
"main:app"
是一个字符串,表示模块名和应用对象的路径。main
是模块名(通常是 Python 文件名,例如main.py
)。app
是模块中定义的 ASGI 应用对象的名称。- 这种方式是通过字符串路径导入应用,Uvicorn 会自动导入模块并找到对应的
app
对象。
-
这里的
app
是一个直接传递的 Python 对象,而不是字符串路径。- 这意味着在调用
uvicorn.run()
之前,app
必须已经在当前 Python 环境中被定义或导入。 - 这种方式通常用于动态传递应用对象,或者在更复杂的部署场景中,例如在测试代码中动态生成应用对象。
- 这种方式不支持
reload=True
,因为reload
依赖于通过字符串路径导入模块,以便监控文件变化。
- 这意味着在调用
-
总结
- 使用场景:
- 如果你直接运行一个固定的 ASGI 应用(如 FastAPI 应用),推荐使用第一种方式(
uvicorn.run("main:app", ...)
),因为它更简洁,且支持reload
功能。 - 如果你需要动态传递应用对象,或者在测试环境中使用,第二种方式(
uvicorn.run(app, ...)
)可能更合适。
- 如果你直接运行一个固定的 ASGI 应用(如 FastAPI 应用),推荐使用第一种方式(
- 功能差异:
- 第一种方式支持
reload=True
,适合开发环境。 - 第二种方式不支持
reload=True
,但更灵活。
- 第一种方式支持
- 使用场景:
-
-