Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debugging GAE in Python Tools for Visual Studio

I'm able to run my Google App Engine webapp2 app using Python Tools for Visual Studio 2012 without issues after following this tutorial, and even step through the server initialization code, but I can't get it to break at get or post methods when the website is loaded, similar to what is shown in this video with the main() method. When I pause the debugger, it always ends up in the following infinite loop in wsgi_server.py:

def _loop_forever(self):
  while True:
  self._select()

def _select(self):
  with self._lock:
    fds = self._file_descriptors
    fd_to_callback = self._file_descriptor_to_callback
if fds:
  if _HAS_POLL:
    # With 100 file descriptors, it is approximately 5x slower to
    # recreate and reinitialize the Poll object on every call to _select
    # rather reuse one. But the absolute cost of contruction,
    # initialization and calling poll(0) is ~25us so code simplicity
    # wins.
    poll = select.poll()
    for fd in fds:
      poll.register(fd, select.POLLIN)
    ready_file_descriptors = [fd for fd, _ in poll.poll(1)]
  else:
    ready_file_descriptors, _, _ = select.select(fds, [], [], 1)
  for fd in ready_file_descriptors:
    fd_to_callback[fd]()
else:
  # select([], [], [], 1) is not supported on Windows.
  time.sleep(1)

Is it possible to set breakpoints in a Google App Engine webapp2 app in PTVS, which are triggered when the page is loaded from localhost?

Edit: using cprcrack's settings, I was able to successfully run GAE, but when loading the main page I get the error

Traceback (most recent call last):
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 3003, in _HandleRequest
    self._Dispatch(dispatcher, self.rfile, outfile, env_dict)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 2862, in _Dispatch
    base_env_dict=env_dict)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 719, in Dispatch
    base_env_dict=base_env_dict)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1797, in Dispatch
    self._module_dict)
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\dev_appserver.py", line 1648, in ExecuteCGI
    app_log_handler = app_logging.AppLogsHandler()
  File "C:\Python\lib\logging\__init__.py", line 660, in __init__
    _addHandlerRef(self)
  File "C:\Python\lib\logging\__init__.py", line 639, in _addHandlerRef
    _releaseLock()
  File "C:\Python\lib\logging\__init__.py", line 224, in _releaseLock
    _lock.release()
  File "C:\Python\lib\threading.py", line 138, in release
    self.__count = count = self.__count - 1
  File "C:\Python\lib\threading.py", line 138, in release
    self.__count = count = self.__count - 1
  File "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\Extensions\Microsoft\Python Tools for Visual Studio\2.0\visualstudio_py_debugger.py", line 557, in trace_func
    return self._events[event](frame, arg)
  File "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\Extensions\Microsoft\Python Tools for Visual Studio\2.0\visualstudio_py_debugger.py", line 650, in handle_line
    if filename == frame.f_code.co_filename or (not bound and filename_is_same(filename, frame.f_code.co_filename)):
  File "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\Extensions\Microsoft\Python Tools for Visual Studio\2.0\visualstudio_py_debugger.py", line 341, in filename_is_same
    import ntpath
  File "C:\Python\lib\ntpath.py", line 8, in <module>
    import os
  File "C:\Python\lib\os.py", line 120, in <module>
    from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
ImportError: cannot import name curdir

Is this error occurring because I need to roll back to Python 2.5 to use the old dev_appserver?

like image 375
1'' Avatar asked Jul 13 '13 18:07

1''


4 Answers

UPDATE#2

gcloud preview deprecated

it's back to original method

UPDATE#1

gcloud preview (it's newer and simpler),

replace this:

General->Startup File:

C:\Program Files\Google\Cloud SDK\google-cloud-sdk\lib\googlecloudsdk\gcloud\gcloud.py

Debug->Script Arguments:

preview app run app.yaml --python-startup-script "pydevd_startup.py" --max-module-instances="default:1"

all rest is the same as the original answer below:


ORIGINAL ANSWER:

A.) Create A File to Inject remote debugger

  1. make a new python file "pydevd_startup.py"

  2. insert this:

    import json 
    import sys 
    if ':' not in config.version_id:  
    # The default server version_id does not contain ':'  
        sys.path.append("lib")  
        import ptvsd  #ptvsd.settrace() equivalent  
        ptvsd.enable_attach(secret = 'joshua')  
        ptvsd.wait_for_attach()
    
  3. Save it in your working directory of your app

  4. for more info look at the pytool remote debuging docu I mentioned above

B.) Edit Project Settings in VS 2013

Now open your Project Settings in VS and enter this:

General->Startup File: C:\Cloud SDK\google-cloud-sdk\bin\dev_appserver.py
General->Working Directory: .
Debug->Search Paths: C:\Cloud SDK\google-cloud-sdk\lib
Debug->Script Arguments: --python_startup_script=".\pydevd_startup.py" --automatic_restart=no --max_module_instances="default:1" ".\app.yaml"

You could probably also use . instead of <path-to-your-app> but I wanted to be safe.

C.) Run Debugger

With Ctrl+F5 you run the debugger, without debugging. This sound weird, but we are actually not debugging right now, just running the dev server which than starts our script to inject the debugger code and wait for our remote debugger to connect, which will happen in the next step

D.) Start Remote Debugger

DEBUG->Attach to Process <Ctrl+Alt+P>
Qualifier: tcp://joshua@localhost:5678 <ENTER>

joshua is your secret key. If you want to change it (and you should), you also have to change it in the pydevd_startup.py. See pytool reference for more info.

F.) Be really happy!

You now can remote debug your application locally (erm, weird). To test this you probably should use a breakpoint at the start of your own script.

If you have any question, please ask. In the end it seems really simple, but to get this going was rough. Especially because pytools said, they don't support it...

G.) Start Debugging for real!

Open http://localhost:8080 in a browser (or any other address you configure your app to use). Now it should invoke the breaking point. If you are done and reload the site, it starts all over again. If you really want to end debugging or change some code, you have to restart the server and attach again. Don't forget to close the terminal window with the server open (use <Crtl+C> )

like image 137
JoeSchr Avatar answered Sep 22 '22 00:09

JoeSchr


This is a known issue with Google App Engine for Python: currently, debugging does not work on any debugger. See here, here and here.

like image 33
1'' Avatar answered Sep 21 '22 00:09

1''


There's a workaround, but I don't know about getting this working for python tools for vs. In theory it should be possible.

https://groups.google.com/forum/#!topicsearchin/google-appengine/Boa/google-appengine/-m00Qz4Vc7U

You'd probably need this guide to get it working:

https://docs.google.com/document/d/1CCSaRiIWCLgbD3OwmuKsRoHHDfBffbROWyVWWL0ZXN4/edit#heading=h.fj44xnkhr0gr

like image 25
dragonx Avatar answered Sep 22 '22 00:09

dragonx


I'm using the old dev_appserver for debugging and it's working for me in an scenario similar to yours. I also got a bunch of exceptions but I was able to just skip all of them following the instructions on this link (I also had to add "exceptions" for some ValueError exceptions).

These are my project properties:

General tab:

Startup File: C:\Program Files (x86)\Google\google_appengine\old_dev_appserver.py

Working Directory: ./

Windows Application: (unchecked)

Interpreter: Python 2.7

Debug tab:

Search Paths: C:\Program Files (x86)\Google\google_appengine

Script Arguments: --use_sqlite ./

Interpreter Arguments: (blank)

Interpreter Path: C:\Python27\python.exe

When there is no need for breakpoints I run the project with DEBUG > Execute Project in Python Interactive. This way you don't get the unneeded console window.

like image 34
cprcrack Avatar answered Sep 20 '22 00:09

cprcrack