Search code examples
python-3.xflaskuwsgigevent

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


I'm using Flask-SocketIO library in my project. Because websockets need to "run in parallel" with main Flask app I'm required to use gevent-websocket library. The problem occurs when I'm trying to set breakpoint for debugger in create_app method:

My app.py file:

# 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

When I start server (I'm using uwsgi ), I recieve following error:

$ 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] ***

I've tried using patched pdb from gevent-tools but result was the same for 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

Is there any way to make pdb work correctly when running under gevent?


Solution

  • After digging a bit I realised you shouldn't use

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

    As it doesn't work. So you can use your older wsgi.py version. Now the issue arises because when you are uwsgi there is no stdin and it is pointed to /dev/null. Since there is no stdin, the debugger cannot launch. See below thread

    How to debug python application under uWSGI?

    So what you want is to add the --hounor-stdin and --gevent while running uwsgi

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

    And now the debugging works

    Debugging working