bdb.BdbQuit 在 uwsgi 服务器上的 Flask 应用 运行 中使用 pdb 时引发

bdb.BdbQuit raises when using pdb in Flask app running on uwsgi server

我正在使用 Flask-SocketIO library in my project. Because websockets need to "run in parallel" with main Flask app I'm required to use gevent-websocket 库。当我尝试在 create_app 方法中为调试器设置断点时出现问题:

我的 app.py 文件:

# monkey patching standard library before importing 
# other modules
from gevent import monkey
monkey.patch_all()

import os
import logging.config

from flask import Flask
from dynaconf import FlaskDynaconf
...
# other imports


def configure_app(app):
    '''
    Configure app settings.
    '''
    FlaskDynaconf(app)
    import pdb; pdb.set_trace()
    logging.config.fileConfig(app.config.LOGGING_SETTINGS)

...

def create_app(run_from_celery=False):
    ''' 
    Create new Flask app instance.
    '''
    app = Flask('automoticz')
    configure_app(app)
    # ...
    return app

当我启动服务器时(我正在使用 uwsgi ),我收到以下错误:

$ uwsgi --http 0.0.0.0:5000 \
      --gevent 1000 \
      --http-websockets \
      --master \
      --wsgi-file automoticz/wsgi.py \
      --callable app
Traceback (most recent call last):
  File "automoticz/wsgi.py", line 3, in <module>
    app = create_app()
  File "./automoticz/app.py", line 138, in create_app
    configure_app(app)
  File "./automoticz/app.py", line 28, in configure_app
    logging.config.fileConfig(app.config.LOGGING_SETTINGS)
  File "./automoticz/app.py", line 28, in configure_app
    logging.config.fileConfig(app.config.LOGGING_SETTINGS)
  File "/usr/lib/python3.5/bdb.py", line 48, in trace_dispatch
    return self.dispatch_line(frame)
  File "/usr/lib/python3.5/bdb.py", line 67, in dispatch_line
    if self.quitting: raise BdbQuit
bdb.BdbQuit
unable to load app 0 (mountpoint='') (callable not found or import error)
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 22694)
spawned uWSGI worker 1 (pid: 22702, cores: 1000)
spawned uWSGI http 1 (pid: 22703)
*** running gevent loop engine [addr:0x494fa0] ***

我尝试使用 gevent-tools 的补丁 pdb,但 import gtools.pdb; gtools.pdb.set_trace()

的结果相同
 104         @app.before_request                                                                                          
 105         def log_request_info():                                                                                      
 106             import gtools.pdb                                                                                        
 107             gtools.pdb.set_trace()                                                                                   
 108  ->         log_request(request)                                                                                     
(Pdb++) 
2019-07-14 19:52:30 - flask.app - ERROR - Exception on /api/system/ws_devices [GET]
Traceback (most recent call last):
  File "./automoticz/app.py", line 108, in log_request_info
    log_request(request)
  File "./automoticz/app.py", line 108, in log_request_info
    log_request(request)
  File "/usr/lib/python3.5/bdb.py", line 48, in trace_dispatch
    return self.dispatch_line(frame)
  File "/usr/lib/python3.5/bdb.py", line 67, in dispatch_line
    if self.quitting: raise BdbQuit
bdb.BdbQuit

有什么方法可以让 pdbgevent 下 运行 时正常工作吗?

深入研究后我意识到你不应该使用

from gevent.pywsgi import WSGIServer
application = WSGIServer((application.config.SERVER_HOST, application.config.SERVER_PORT), application)

因为它不起作用。所以你可以使用旧的 wsgi.py 版本。现在问题出现了,因为当你是 uwsgi 时没有 stdin 而它指向 /dev/null。由于没有标准输入,调试器无法启动。请参阅下面的线程

How to debug python application under uWSGI?

所以你想要的是添加 --hounor-stdin--gevent 而 运行 uwsgi

uwsgi --http 0.0.0.0:5000 \
 --gevent 10 \
 --http-websockets \
 --master \
 --wsgi-file automoticz/wsgi.py \
 --honour-stdin

现在可以调试了