【问题标题】:Pyinstaller-compiled Uvicorn server does not start correctlyPyinstaller 编译的 Uvicorn 服务器无法正确启动
【发布时间】:2020-10-09 13:23:51
【问题描述】:

当我启动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 中执行服务器的代码时,它运行正常。

【问题讨论】:

标签: python pyinstaller uvicorn


【解决方案1】:

我遇到了同样的问题。而且我发现这是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

【讨论】:

    【解决方案2】:

    更通用的方法是指定钩子:

    # extra-hooks/hooks-uvicorn.py
    from PyInstaller.utils.hooks import collect_submodules
    
    hiddenimports = collect_submodules('uvicorn')
    

    然后使用--additional-hooks-dir extra-hooks 运行 pyinstaller。例如:

    pyinstaller -y --clean --additional-hooks-dir extra-hooks main.py
    

    但是!

    如果您像我一样使用websockets lib。您将面临错误:

    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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 2022-06-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2019-03-01
      • 1970-01-01
      相关资源
      最近更新 更多