1
Vote

Attach to Process using Flask

description

I am writing an application using Flask, and I am having trouble attaching to a Python process for debugging. I am trying to attach to the process which my Flask development server is running on (127.0.0.1:5000).

I have followed the instructions within the "Cross-platform remote Python debugging" section in the documentation, and have had mixed success (but I have never fully gotten it to work).

I insert the following code just before I run my server:

import ptvsd
ptvsd.attach_server.enable_attach(secret = None, address = ('127.0.0.1', 5000))

Then I go to "Tools --> Attach to Process", choose "Python remote debugging (unsecured)", and type in the appropriate qualifier to find my running process ('127.0.0.1:5000'). After doing that, I am actually able to see the process, and I can 'attach' to it (I put 'attach' in quotes since at this point my process doesn't seem to work properly).

The problem is that as soon as my code runs the 'ptvsd.attach_server.enable_attach()' command, it seems to disable my server. Everything runs fine as long as I comment out that line so that that command does not run (although I am obviously not able to debug). If I uncomment that line, if I then run the server and go to 127.0.0.1:5000 in my browser I get an error page that "This webpage is not available".

Does anyone have any ideas on why this isn't working?

I am running Visual Studio 2012 Professional and have version 2.0 of PTVS installed.

comments

pminaev wrote Jul 22, 2013 at 8:09 PM

The port number that you specify in enable_attach should not match the port number that your web server runs on - these are two different things. As it is, with the code above, you are basically overriding your web server with the debug server.

You should pick some port number that is different. For example, 5678, which also happens to be the default one (and so you can then just type 127.0.0.1 in Attach to Process dialog).

akirkby wrote Jul 23, 2013 at 12:51 AM

Ok, so that fixed part of the problem but not all of it. I didn't realize that what this was doing was launching a debug server which you could then attach to, so it makes sense that I was overwriting my own web server.

What I would like to do is to attach to my Flask web server for debugging (my development server runs on 127.0.0.1:5000). Is it possible to attach to my web server for debugging? After reading the documentation more thoroughly and playing around with it for a bit it seems that maybe I can't do that. When I update my code to say "ptvsd.attach_server.enable_attach(secret = None, address = ('127.0.0.1', 5678))" and then I go to the Attach to Process dialog to attach to '127.0.0.1', it no longer overwrites my web server and so my site works as expected. The problem is that I can't break into my code with my breakpoints, and it seems that the reason is that I'm attached to the PTVS debugging server and not to my development web server.

So, am I still missing something, or is it just not possible to attach to my development web server for debugging? (I'm using Flask v0.9)

pminaev wrote Aug 18, 2013 at 3:43 AM

Sorry for the late reply; I've accidentally disabled notifications for new comments in this bug :/

The "PTVS debugging server" is a separate thread that runs in an existing Python process, and lets you debug the rest of the code in that process. So if you're launching it and attaching to it, then you're attaching to the process in which it is spawned.

Now, in case of web servers, it can get complicated if the web server in question itself consists of multiple processes. For example, it may be spawning a new process to service requests; or it may be a daemon that forks itself as a background process when it is launched from the console. In these cases, it might be that you simply have the debugging server running in the wrong process. Here's a forum discussion where a similar case was analyzed: https://pytools.codeplex.com/discussions/450477

By "Flask web server", do you mean the development one that you get when you launch your Flask app main script directly? I'll have a look at what it actually does to see what, if anything, can be done to attach to the request servicing code.

pminaev wrote Jan 16 at 11:32 PM

Can you share the code for your Flask app (maybe simplify it down to just starting the app, and one simple "Hello, world" style route). I tried to reproduce it on my own simple Flask project which looks like so:
import ptvsd
ptvsd.enable_attach(None)

from flask import Flask
app = Flask(__name__)

# Make the WSGI interface available at the top level so wfastcgi can get it.
wsgi_app = app.wsgi_app


@app.route('/')
def hello():
    return "Hello World!"

if __name__ == '__main__':
    import os
    host = os.environ.get('SERVER_HOST', 'localhost')
    try:
        port = int(os.environ.get('SERVER_PORT', '5555'))
    except ValueError:
        port = 5555
    app.run(host, port)
However, when I launch it and then attach to it (all on the same machine, so connecting to localhost), I can hit the breakpoint that I've set inside hello(), and it keeps getting hit if I refresh the page in the web browser. So clearly I'm doing something differently here...