To install the TraceKnack module, first download the package using the link in the sidebar, unpack it, then run the usual Python setup:
python setup.py install
How you integrate it with your application, depends on the framework you are using. TraceKnack includes interfaces for a small number of common frameworks, and we hope to add more over time. Look for a module named after the framework you’re using, and peek inside it – it ought to be obvious what you need to do.
If you’re using a framework you built yourself, or some other unsupported one, you’ll need to work with TraceKnack directly. The interface is fairly straightforward – create an instance of the TraceKnack class, and call it’s handle() method, passing in sys.exc_info() when an exception occurs:
import sys
from traceknack import TraceKnack, TraceKnackError
traceknack_handler = TraceKnack("http://localhost/debugger/")
python Inside your request handler:
try:
# handling the request
except TraceKnackError, e:
# an error occurred actually inside TraceKnack.
# we'll pass this up to the normal event handling to avoid a
# potential infinite loop. that said, I have successfully used
# TK to debug itself... :)
raise e.internal_error
except:
web_page_body = traceknack_handler.handle(sys.exc_info())
# it's up to you to get web_page_body output to the browser in
# your particular framework.
This creates and renders the HTML/JavaScript-based debugging interface and sends it to the user. Now, you need to install a handler so that the interactive controls work. You need to arrange to handle two URLs, under the base URL you provided when creating the TraceKnack instance. So, using the example above, you need to handle http://localhost/debugger/Viewer and http://localhost/debugger/Var
Both take GET parameters and you need to pass these directly into the matching render_viewer() and get_variables() members of the handler. Here’s how the TurboGears interface does it:
@turbogears.expose()
def Viewer(self, except_id, depth=-1, callables=False, hidden=False):
depth = int(depth)-1
if depth<0: depth=None
return self.knack.render_viewer(int(except_id), depth, bool(callables), bool(hidden))
@turbogears.expose()
def Var(self, except_id, depth, path, callables=False, hidden=False):
depth = int(depth)-1
if depth<0: depth=None
return self.knack.get_variables(int(except_id), depth, bool(callables), bool(hidden), path)
Note the diddling of the depth parameter. Internally, TraceKnack treats depth parameters like list indices: Negative indices are counted back from the end of the list, and a value of None indicates that the global variables should be inspected instead of anything in the stack. The HTML form simply has an indexed list, so we need to convert the indices.