Tech Ravings

An Opinion is a Terrible Thing To Waste
Subscribe

Archive for the ‘Programming’

CherryPy Using Routes Library

June 23, 2008 By: ScottK Category: Python No Comments →

I’m still plucking away at this project as time allows using CherryPy. This weekend I just started to use it and finally got a working environmental configuration system and then next step was to figure out if RESTful controllers could be used. As it turns out you can not only use RESTful controllers but have the additional benefit of format types as well (html, xml, json, etc).

This is due to the CherryPy RoutesDispatcher using the routes library. I’ve successfully setup dispatcher with RESTful routes and have tests to show that they work as planned.

I’ll do a follow up post with working examples this weekend.

Setting Up Environments in CherryPy

June 20, 2008 By: ScottK Category: Python 2 Comments →

Here’s my dilemma, I’m a developer working on code on my machine. Once I’m done I send the code to QA who then says yay or nay. Once I get a yay then the code goes into production on a live server. CherryPy has a site config for all apps as well as an app specific config, which pertains to the code I writing. Under the CherryPy documentation I would have to modify 3 different files in order to add 1 new model! That’s insane.

Additionally, I’m working on my computer (localhost) so I need the SQLObject connections to point to my machine. When I send my work to QA the db connections are completely different. Production environment, again different. Traces, ip address, etc, all different from the various environments. CherryPy 3 does have a “global” config for all apps as well as a “site” config pertaining to your app, but no where does it suggest setting up these environments. Outside of the “environment = whatever” in the config.

Do I really have to write my code on my machine, send it to QA, log into shell and make the modifications, get a yay and send to production, log into shell there and make modifications? Do this across twenty developers as well?

No…

I hope you see the catastrophe that could ensue because an out of the box framework doesn’t allow environments to be set up within an app. Likewise I do judge a framework by the lack of code duplication (DRY). Searching the documentation for CherryPy as well as many other sites I found no information concerning my requirements. So it was time to start “playing”

CherryPy does allow you to remain DRY and set up environments!
Takes a little work around though, but with a deploy script it’s easy.

First let’s create the scripts:

# Site Config (site_config.py)

[global]
server.protocol_version = "HTTP/1.1"
tools.proxy.on = True
tools.proxy.local = "X-Forwarded-Host"
tools.proxy.remote =  "X-Forwarded-For"
log.error_file = "logs/error.log"
log.access_file = "logs/access.log"

#Development (development.py)

[global]
server.socket_host = "127.0.0.1"
server.socket_port = 8082
log.screen = True
tools.log_tracebacks.on = True

#QA (qa.py)

[global]
server.socket_host = "127.0.0.1"
server.socket_port = 8083
log.screen = True
tools.log_tracebacks.on = False

#routes.py (routes.py)

[/]

#whatever

#deploy script (deploy.py)

import sys
import cherrypy

import models
from models.base import Base
#add your additional models as well from models folder

if __name__ == '__main__':
    cherrypy.config.update(sys.argv[1] + ".py")
    cherrypy.config.update(sys.argv[2] + ".py")
    cherrypy.tree.mount(Base(), script_name="/", config="routes.py")
    cherrypy.engine.start()

So in the command line when you call:
>>python deploy.py site_config.py development
what happens is:

1. Loads the models as classes.
2. cherrypy loads the site wide config variables (site_config.py). These pertain to all the environments.
3. chrrypy loads, adds or overwrites, all the environment settings. Specific to development (locally), qa (hope it works), production (umm better work) :)
4. Mounts each model to the correct path as found in the routes.py file which contains settings for each route.

Of course it’s not completely DRY. As each new model is made you do have to update the deploy script as well as the routes.py, but it’s a lot better than doing all your environment files.

I do feel CherryPy would be much more powerful if out of the box we could set up situations like this as well as a plain routes file (Dispatcher) so hacks like this aren’t needed. However this hack at least kept me considering using CherryPy.

Restful Pylons with Extension Types

June 13, 2008 By: ScottK Category: Python No Comments →

The time has come for me to finally use a python web framework, Pylons is the choice around here. I’ve set up a few toy apps using it but nothing so involved that took real software planning. Since I was making a real application that required real business planning I found the Pylons documentation to be really screwed up. The instructions in the tutorials conflicted with each other in how to set up the websetup.py, development.py, etc. Months ago I had a toy program setup in half an hour using one tutorial; today it took me over two hours because the Pylons docs had changed. But not across the boards.

While displeased with this, I’m used to it. It also means that serious research is needed in order to work with the software. Being fully involved with Pylons, albeit new. I didn’t expect it to be RESTful; nor did I expect it to allow different extension type within an action. I am actually impressed with the Ruby on Rails RESTful implementation and was very surprised to find that Pylons itself has RESTful implementations itself.

However, my project requires me to call one action in the extension with “.js” for JSON and another extension of “.rss” for that version. The Pylons RESTful documentation lacks for this. I couldn’t find any other reference for this on the web either. While I don’t know for sure when Pylons added RESTful resources the documentation lacks any examples that I found for using different formats, so here it goes.

The Pylons wiki for RESTful controllers is found here: How map.resource enables controllers as services. It explains everything you want to know about how to use REST within Pylons. It does not explain my predicament on how to make the index action display JSON format or RSS format.

After a little testing and discovery I found out that you can, within an action, produce different views specific to the format of the action.  Given my requirements here is how I was able to use one RESTful action for many formats, i.e (.js, .gif, .rss, .rtf, etc).

1. Create your RESTful controller using the command: paster restcontroller <singular name> <plural name>
This is no different than the instructions in the map.resource link above.

2. In the action create an if…elsif…else to actually control the format:
def index(self, format=”html”):
if format == “js”:
response.headers[’Content-Type’] = ‘application/javascript’
return render(’/pubscript/indexjs.mako’)
elif format == “xml”:

response.headers[’Content-Type’] = ‘application/xml’
return render(’/pubscript/indexxml.mako’)
else:
abort(404, ‘Page Not Found’)

So as the index definition provides that any index call to the controller does perform the action, only the .js returns an js (JSON) file or an .xml renders an xml file format. Any other format or none provided sends a 404 File Not Found error. Now I had complete control of what the format is and control of any unexpected calls.

Pylons has evoled to the presedence set by Ruby on Rails in that RESTful controllers can be used. Even though the default format for Pylons is HTML you can detect such as present different formats based upon such.  Being new to the Pylon framework itself I wasn’t expecting this functionality. Discovering that it has it, and is acting on the different formats, I do believe that it has emerged as a mature framework that embraces best practices of web application programming.

Still highly complicated in setting up and a huge learning curve with little correct documentation though, don’t get me wrong there.


ss_blog_claim=ef6135f29164404afb5ea2743196c435