Search This Blog

18 November 2010

Documenting web services with restructured text

Let's say you're programming a web service with a REST interface.

You might return different HTTP codes that you want to explain in your documentation.
Of course you will use ReST (restructured Text) to document.

Wouldn't it be helpfull that you could link to a full explanation of the code ?

here is a file that you can import from your ReST files like so

.. include:: http_errors.txt

http_errors.txt being :

.. _`100 Continue`:
.. _`101 Switching Protocols`:

.. _`200 OK`:
.. _`201 Created`:
.. _`202 Accepted`:
.. _`203 Non-Authoritative Information`:
.. _`204 No Content`:
.. _`205 Reset Content`:
.. _`206 Partial Content`:

.. _`300 Multiple Choices`:
.. _`301 Moved Permanently`:
.. _`302 Found`:
.. _`303 See Other`:
.. _`304 Not Modified`:
.. _`305 Use Proxy`:
.. _`307 Temporary Redirect`:

.. _`401 Unauthorized`:
.. _`402 Payment Required`:
.. _`403 Forbidden`:
.. _`404 Not Found`:
.. _`405 Method Not Allowed`:
.. _`406 Not Acceptable`:
.. _`407 Proxy Authentication Required`:
.. _`408 Request Timeout`:
.. _`409 Conflict`:
.. _`410 Gone`:
.. _`411 Length Required`:
.. _`412 Precondition failed`:
.. _`413 Request Entity Too Large`:
.. _`414 Request-URI Too Long`:
.. _`415 Unsupported Media Type`:
.. _`416 Requested Range Not Satisfiable`:
.. _`417 Expectation Failed`:

.. _`500 Internal Server Error`:
.. _`501 Not Implemented`:
.. _`502 Bad Gateway`:
.. _`503 Service Unavailable`:
.. _`504 Gateway Timeout`:
.. _`505 HTTP Version Not Supported`:

21 October 2010

validate documentation before uploading to pypi

python --long-description | rst2html > description.html

tip taken from

30 September 2010

using CascadingSelection with tw.dynforms

Here I took some note on my usage of the CascadingSingleSelectField from tw.dynforms

It is not that well documented, so I took an extract of code.

class MailForm(TableForm):

        # this will be used to id the widget

        help_text = 'Please choose the region.

        # what controller to call onchange
        cascadeurl = '/choices/region',
        # this is the default js event, but can be overriden
        event = 'onchange',
        # id of other widgets if you need their value to compute your choices
        extra = ['gender', 'senior'],   
        size = 10,
        help_text = 'Please select a person.',
        cascadeurl = '/choices/people',

in the controller let's add some methods

def region(self, **kw):
    """ called by the region widget
    # this is the value of the "gender" widget
    gender = kw.get("gender")
    # same for senior, they were defined in the extra attribute
    senior = kw.get("senior")
    # "value" is the value of our widget (region here)
    region = kw.get("value")

    # here we suppose that the _get_people method returns a list of tuples
    # (value, display). it will result in display
    people = self._get_people(gender, senior, region)

    # the keys of the resulting dict will be used to determine
    # what widget should be changed there could be many of those 
    return dict(people=people)

Further readings :

you might want to read this tw.dynforms tutorial

or the official documentation

16 September 2010

elixir internationalization of content

I was recently challenged to implement an internationalization of the content of my TG application.

There is of course many tools, mostly Babel, to translate the interface and the message strings that live in the python vivarium. A good documentation can be found on the pylon website.

More difficult is to manage the i18n of the content of the RDBMS.

werner, on the sqlalchemy mailing list pointed me to an old thread regarding a discussion about dynamic_loader.

He also sent me links to a blog with a lot of thoughts about my problem.

Graham Higgins had derived the versioning extension of elixir and modified it to implement a concept of Local content. He shared his code, but it failed to pass its tests, elixir had moved up from 0.4 to 0.7. So I took upon me to rewrite this component and make it work, it is now available as an elixir extension.

It is hosted on google code and you can easily check out a copy.

12 September 2010

search insides the sources with glimpse

I use the pydev plugin of eclipse which permits a simple search of a method or a class. Still, sometimes (often really) I need to search for a snippet of javascript or css or .po file.

I found glimpse usefull to this kind of searches, here is how I use it.

A good tip is to only install python package unzipped in your virtualenv, that is provide a -Z option parameter to the easy_install command. This will help pydev and glimpse to parse the packages content.


to install glimpse, download the latest release from

then the usual commands

#>make install

this will give you two new commands, glimpse to search in the index, glimpseindex to build the index

if you can't access the root privileges, it is possible to set a --prefix parameter.

you then create a place to store the indexes, I issued a

$>mkdir index.tg2

you don't want to index a few extensions, in the newly created folder create a file named .glimpse_exclude containig something like :


to ease the use of the commands you can set a few aliases in your environment

#Aliases for glimpse
# search all
alias tsh='glimpse -n -H ~/index.tg2'
# search po translation files
alias tshpo='glimpse -F \.po$ -n -H ~/index.tg2'
# search python sources
alias tshpy='glimpse -F \.py$ -n -H ~/index.tg2'
# search css
alias tshcss='glimpse -F \.css$ -n -H ~/index.tg2'
# search javascripts
alias tshjs='glimpse -F \.js$ -n -H ~/index.tg2'
# search genshi templates
alias tshhtml='glimpse -F \.html$ -n -H ~/index.tg2'
# reindex glimpse
alias treindex='glimpseindex -H ~/index.tg2 ~/virtualenvs/tg2/'

This setup has proven quite efficient in numerous situation.

example: I need to find where the Spacer Class from the tw.forms is defined

$ pchpy Spacer | grep class
/lib/python2.6/site-packages/tw.forms-0.9.9-py2.6.egg/tw/forms/ 667: class Spacer(FormField):

more details with the help commands

$>glimpse --help
$>man glimpse
$>man glimpseindex

tosca widgets

I have released some tosca widgets to use with turbogears.

  • tw.uitheme : a thin wrapper around several styles from uitheme
  • tw.jqmultiselect : packaging of the excellent jquery multiselect plugin which provides a nice representation of multiple select options list, with search and drag and drop.
  • tw.jqgrid : tosca widget around the jquery grid plugin, very useful indeed.
  • tw.gravatar : this widget lets you insert a gravatar image for any given email address, it of course relies on the gravatar web service.
  • tw.epiclock : this widgets allows for easy insertion of countdowns (is your session about to expire soon ?) of the current time on the server. It is based on the epiclock javascript library.

I also became maintainer of tw.swfobject a widget to easily insert a flash content

I've had a go at using jstree, but it wasn't what I wanted for my immediate need, so I didn't go to package it as a tosca widget, anyone ?

share a javascript development

I work remotely and sometimes need the javascript expertise of some of my colleagues or of the good fellows of the #jquery community.

jsfiddle allows you to share a minimal running example, and your friends can try and/or modify your code. It is like a pastebin dedicated for javascript, it is alpha for now but has already proven useful.

graphs display as image with python

Some notes on graph manipulation with python.

My main goal was to provide a graphic output, I finally went to use pydot

This lib allows to generate dot files (for graphviz use)

it's simple and intuitive and allowed me to provide 2 controller methods, one for the image and one for the image map associated with it. This and a small script based on jquery drag and drop plugin, I could provide a nice and intuitive interface for manipulating my graphs.

I successfully managed to use the cytoscape flash widget to display my graphs, but I stumbled upon some restriction.

networkx seems a good lib to create and search path in a graph, I studied it briefly but I didn't fill my current needs.