Using py DBGP to debug cherrypy – Work in progress

I will freely admit I am heavily addicted to the DBG protocol these days. For the uninformed, DBGp when combined with a proper client, allows for symbolic debugging of live and or remote applications in PHP and Python. I’ve used xdebug, the PHP implementation of DBGp for several years now and it has been a tremendous time saver debugging weird issues in staging and testing environments.

I’ve also used DBGp for simple Python applications, but have never been able to get the same functionality with more advanced products like cherrypy…. until now. I’ts kind of hokey, but all I needed to do was insert a python dbgp call liked

    from dbgp.client import brk
    
    def someCode(*args)
          ....
          brk(host="192.168.56.1", port = "9000" )

And voila I got a session started inside one of my controller methods while it was walking through handling an OpenId response.

Very happy about this I must say as it will make it ever so much easier to figure out where the hell I’ve gone wrong.

A new source code repo

http://github.com/devdave/DevDave-s-miscellanious-bucket

Includes: The complete mako Auto-render logic class + decorator for cherrypy and a proof of concept idea I am still working on to implement the command pattern in Python.

The power of convenient information

I’ve been using PHP off and on as a language since sometime in the late 90’s when it was just PHP ( and not even PHP3 ). To be fair, the language has come a long way and beaten out some well financed rivals ( ASP & Coldfusion for example ) but it has also suffered along the way in the quality of it’s source code.

For the last 5 years, I’ve occasionally stared at PHP’s C macro-soup and soon after promptly stopped. My first real programming language was C when I was eleven years old, I know C like an old friend, but PHP’s source code is not C. It’s the dark side of C, a meta-language built on top of C via a fairly deep interdependent network of macro’s, defines, typedef’s, linked structs, and shit I didn’t know you could do with C.

Oh yeah and most of that crap is extremely terse, not documented, and inconsistently arranged. If I had a client who asked me to maintain PHP, I’d probably smile and every so carefully walked backwards out of the room. Really I must say I am impressed with PHP’s dedicated staff and volunteer engineering team. I don’t know how the hell they do it.

That said, I’ve been trying out various c/c++ IDE’s for linux and continually dissappointed. Code Lite seemed nice but its unworkable workspace idealogy pissed me off, Kdevelop is good but lacking in features, and etc etc. Recently I’ve had to do some Java code ( I’ve got a borderline irrational hatred towards the language since the 90’s ) and after trying IntelliJ for a day or two, I went back to the IDE I first used to learn Java… NetBeans. I’ve got to say, Netbeans has gotten a lot better since I last used it 12 years ago. And one of the things it has gotten really good at, is being a c/c++ IDE.

The IDE’s macro resolution and code intelligence features probably helped me jump years of effort into the future for understanding PHP by providing a macro resolution feature that visually converts the PHP meta language source code back into C. Whole sections of the languages design, construction, and its philosophy all became self-evident to me in the space of three hours.

Which leads to the end of this post, information maybe power… but only if it can be recognized as information and not noise… or in the case of PHP, a code base written by an infinite number of PCP snorting monkeys.

Simple helper script while debugging cherryPy apps

Usage: $~/looper runSomePythonScript.py

#!/usr/bin/python
import subprocess
import time, sys

PYTHON = '/usr/bin/python'

def main():
    commands = [PYTHON]
    commands.extend(sys.argv[1:])
    
    print "Looping %s" % commands
    while True:
       subprocess.call(commands)
       print "4 seconds to restart"
       time.sleep(2)
       
       
if __name__ == "__main__":
    main()

Ghetto dev. updating script

When writing maps/reduce functions for couch, its tedious to make a change, jump to the server console, push the code, then call the map/reduce via a web browser or curl. So I figured, cut at least 1 step out of the whole process and just page back and forth from the IDE to the browser while a tail of the couchdb error log spins by on a 2nd monitor.

import os
from os import path
import time
from stat import ST_MTIME
manifest = dict()
import subprocess

while 1:
    time.sleep(3)
    print "Scanning"
    for root , dirs, files in os.walk("./_design/"):
        for file in files:
            filepath = path.join(root,file)
            mtime = os.stat(filepath)[ST_MTIME]
            if not filepath in manifest:
                manifest[filepath] = mtime
            else:
                if mtime > manifest[filepath]:
                    print filepath, "is stale, updating."
                    subprocess.call(["/usr/bin/python", "push.py"] )
                    manifest[filepath] = mtime

CouchDBKit: couchdbkit.designer

As mentioned previously, CouchDBKit stores map/reduce functions on the local filesystem. An undocumented feature in the couchdbkit.designer module is the presence & functionality of the .couchappignore… thankfully the programmer left some comments.

# A .couchappignore file is a json file containing a 
# list of regexps for things to skip 

I assume this functions similar to .gitignore or SVN:ignore

Timestamp property adapter for couchdbkit


import time, datetime
from couchdbkit.schema.properties import Property
class TimestampProperty(Property):
    
    """
        
    """
    
    @staticmethod
    def now(self):
        return datetime.datetime.now()
    
    def to_python(self, value):
        if isinstance(value, basestring ):
            try:
                value = float(value)
                value = datetime.datetime.fromtimestamp(value)
            except ValueError, e:
                raise e
        elif isinstance( value, float):
            try:                
                value = datetime.datetime.fromtimestamp(value)
            except ValueError, e:
                raise e
        else:
            #if it's not basestring or float... what the hell is it?
            #@TODO remove on acceptance
            raise Exception(value, [(k,getattr(value,k)) for k in dir(value)])
        
        return value
    
    def to_json(self, value):
        if value is None:
            return value
        return time.mktime(value.timetuple())

A recommend book

I’ve been recommending “The Python Cookbook” to my peers and anyone who will listen. Its not an earth shattering, change your life book, and it doesn’t have a recipe for curing cancer. What it does have is some extremely well written solutions to common and uncommon problems so the recommendation to read the cookbook is made for those just getting into Python and who need a good source of examples for doing things in a more pythonic way.

Available @ Amazon via this link or directly from Oreilly here

Python & CouchDB

In my so far unnanounced pet-project to make a delicious clone, I’ve been experimenting with CouchDB. Initially I started with python-couchdb and it worked well for importing data from my delicious data export, but then things started
getting difficult. The major issue was how to install & use views, authenticating, and so on.

Being unhappy with python-couchdb, I decided to try out couchdbkit and the initial trials have been mostly positive on interfacing with the couchdb server. One of the more outstanding features is the ability to push a directory stucture of maps/views from the local filesystem to couchdb.

Given a path structure like:

  • _design/
    • databaseName/
      • views/
        • viewName/
          • map.js

CouchDBkit will push viewName to databaseName ( note I may not have this exactly right just yet ).

Will see how couchdbkit does for performance and more involved tests.

Cherrypy @AutoRender magic

from functools import wraps

def AutoRender(f):
    
    name =  f.__name__
    f.exposed = True
    #raise Exception([ name, [(k, getattr(f,k),"\n",) for k in dir(f)]])
    
    @wraps(f)
    def wrapper(self, *args, **kwargs):
        cls = self.__class__.__name__.lower()
        result = f(self, *args, **kwargs)
        pathname = "%s/%s" % (cls, name, )
        
        return Render(pathname , result ).gen()
        
    
    wrapper.exposed = True
    return wrapper

I often find it tedious in pretty much any language to have the following pattern:

   Class MyController:
        
         def action(self):
             result = do_stuff()
             return Render("MyController/action", { result : result } )
         action.exposed = True

So with @AutoRender it assumes the above pattern to make things a little cleaner @ the application layer

class MyController:
      
      @AutoRender
      def action(self):
          result = do_stuff()
          return { result: result }

As much as Ruby annoys me with its syrupy breakfast cereal syntactic sugar, I do praise it for laying down an assortment of helpers and shortcuts for common tasks.