Pyinstaller 编译的 Uvicorn 服务器无法正常启动
Pyinstaller-compiled Uvicorn server does not start correctly
当我启动 server.exe
并尝试执行 uvicorn.run()
时,抛出异常:
Traceback (most recent call last):
File "logging\config.py", line 390, in resolve
ModuleNotFoundError: No module named 'uvicorn.logging'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "logging\config.py", line 542, in configure
File "logging\config.py", line 654, in configure_formatter
File "logging\config.py", line 469, in configure_custom
File "logging\config.py", line 397, in resolve
File "logging\config.py", line 390, in resolve
ValueError: Cannot resolve 'uvicorn.logging.DefaultFormatter': No module named 'uvicorn.logging'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "server.py", line 82, in <module>
File "server.py", line 21, in run
File "uvicorn\main.py", line 343, in run
File "uvicorn\config.py", line 180, in __init__
File "uvicorn\config.py", line 223, in configure_logging
File "logging\config.py", line 808, in dictConfig
File "logging\config.py", line 545, in configure
ValueError: Unable to configure formatter 'default'
[7932] Failed to execute script server
请注意 uvicorn.logging
模块确实存在,当我在 Python 中执行服务器代码时,它运行正常。
我遇到了同样的问题。而且发现是hiddenimports
的工作,修改xxx.spec
中的以下几行很有用:
a = Analysis(['xxx.py'],
hiddenimports=['uvicorn.logging'],
<everything else>)
但是,还是会出现其他类似的问题。所以,我尝试添加 uvicorn
的所有文件,它适用于:
hiddenimports=['uvicorn.lifespan.off','uvicorn.lifespan.on','uvicorn.lifespan',
'uvicorn.protocols.websockets.auto','uvicorn.protocols.websockets.wsproto_impl',
'uvicorn.protocols.websockets_impl','uvicorn.protocols.http.auto',
'uvicorn.protocols.http.h11_impl','uvicorn.protocols.http.httptools_impl',
'uvicorn.protocols.websockets','uvicorn.protocols.http','uvicorn.protocols',
'uvicorn.loops.auto','uvicorn.loops.asyncio','uvicorn.loops.uvloop','uvicorn.loops',
'uvicorn.logging'],
然后,运行:
pyinstaller xxx.spec
更通用的方法是太指定钩子:
# extra-hooks/hooks-uvicorn.py
from PyInstaller.utils.hooks import collect_submodules
hiddenimports = collect_submodules('uvicorn')
和 运行 pyinstaller 与 --additional-hooks-dir extra-hooks
。例如:
pyinstaller -y --clean --additional-hooks-dir extra-hooks main.py
但是!
如果你像我一样使用 websockets
库。您将面临错误:
File "uvicorn\protocols\websockets\websockets_impl.py", line 24, in <module>
AttributeError: module 'websockets' has no attribute 'WebSocketServerProtocol'
[1844] Failed to execute script main
为此我找到了另一个解决方案。添加整个 uvicorn 的目录本身:
# extra-hooks/hooks-uvicorn.py
from PyInstaller.utils.hooks import get_package_paths
datas = [(get_package_paths('uvicorn')[1], 'uvicorn')]
并用上面的命令构建exe。
当我启动 server.exe
并尝试执行 uvicorn.run()
时,抛出异常:
Traceback (most recent call last):
File "logging\config.py", line 390, in resolve
ModuleNotFoundError: No module named 'uvicorn.logging'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "logging\config.py", line 542, in configure
File "logging\config.py", line 654, in configure_formatter
File "logging\config.py", line 469, in configure_custom
File "logging\config.py", line 397, in resolve
File "logging\config.py", line 390, in resolve
ValueError: Cannot resolve 'uvicorn.logging.DefaultFormatter': No module named 'uvicorn.logging'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "server.py", line 82, in <module>
File "server.py", line 21, in run
File "uvicorn\main.py", line 343, in run
File "uvicorn\config.py", line 180, in __init__
File "uvicorn\config.py", line 223, in configure_logging
File "logging\config.py", line 808, in dictConfig
File "logging\config.py", line 545, in configure
ValueError: Unable to configure formatter 'default'
[7932] Failed to execute script server
请注意 uvicorn.logging
模块确实存在,当我在 Python 中执行服务器代码时,它运行正常。
我遇到了同样的问题。而且发现是hiddenimports
的工作,修改xxx.spec
中的以下几行很有用:
a = Analysis(['xxx.py'],
hiddenimports=['uvicorn.logging'],
<everything else>)
但是,还是会出现其他类似的问题。所以,我尝试添加 uvicorn
的所有文件,它适用于:
hiddenimports=['uvicorn.lifespan.off','uvicorn.lifespan.on','uvicorn.lifespan',
'uvicorn.protocols.websockets.auto','uvicorn.protocols.websockets.wsproto_impl',
'uvicorn.protocols.websockets_impl','uvicorn.protocols.http.auto',
'uvicorn.protocols.http.h11_impl','uvicorn.protocols.http.httptools_impl',
'uvicorn.protocols.websockets','uvicorn.protocols.http','uvicorn.protocols',
'uvicorn.loops.auto','uvicorn.loops.asyncio','uvicorn.loops.uvloop','uvicorn.loops',
'uvicorn.logging'],
然后,运行:
pyinstaller xxx.spec
更通用的方法是太指定钩子:
# extra-hooks/hooks-uvicorn.py
from PyInstaller.utils.hooks import collect_submodules
hiddenimports = collect_submodules('uvicorn')
和 运行 pyinstaller 与 --additional-hooks-dir extra-hooks
。例如:
pyinstaller -y --clean --additional-hooks-dir extra-hooks main.py
但是!
如果你像我一样使用 websockets
库。您将面临错误:
File "uvicorn\protocols\websockets\websockets_impl.py", line 24, in <module>
AttributeError: module 'websockets' has no attribute 'WebSocketServerProtocol'
[1844] Failed to execute script main
为此我找到了另一个解决方案。添加整个 uvicorn 的目录本身:
# extra-hooks/hooks-uvicorn.py
from PyInstaller.utils.hooks import get_package_paths
datas = [(get_package_paths('uvicorn')[1], 'uvicorn')]
并用上面的命令构建exe。