Incalement votre

Entries in the Category “Python”

Python gathering at Confoo

written by arrakis, on Mar 12, 2010 12:28:00 PM.

Hello Pythonistas !

This Friday, at 9 am., we want to invite you to an unofficial montreal-python gathering, at Savoir-Faire Linux’s booth, in the St-Pierre room (across from the blue “Dinner/Lunch” room). (Hilton Bonaventure Hotel)

Proposed subjects

  • Intro to Python, for newcomers
  • Hands-on Pylons, Django and TG2
  • Distutils2, packaging .deb, .rpm, .egg
  • Documentation in Python, Sphinx and al

And more than that, you can come if you’re registered to Confoo after 13h30 !

Wow !

At Confoo

written by arrakis, on Mar 12, 2010 12:10:00 PM.

confoo_pub

I will be back with tons of ideas of posts and code after Confoo.

What's Confoo?

Confoo is a pretty conference about web developement and opensource in general, organized by 3 associations of Montreal (Montreal-Python, PHPQuebec, W3Quebec and OWASP). In fact Confoo was in the past the annual PHPQuebec's Conference and they decided to open the event to others technologies and languages. It's now very large and open.

Job fare

If you are coming to Confoo and you are going to the Job fare, come see us at the Savoir-Faire Linux stand.

Conferences

If you are going to see conferences, I'll see the following for sure:
  • Django + RESTful APIs as an application server (Pierre-Luc Beaudoin)
  • Le trio gagnant: SQLAlchemy, FormAlchemy et Pylons (Tarek Ziade)
  • TurboGears: An Exercise in Natural Selection (Christopher Perkins)
  • Open source configuration management systems (Guillaume Pratte)
  • Email Deliverability For All (Nicolas Toper)
  • Pylons: you mean "fast" Web development? Live demo (Alexandre Bourget)
  • Le packaging avec Python (Tarek Ziadé)
  • Open Source Content Management with Plone (Jordan Baker)
  • NoSQL : vers la fin du relationnel ? (Raphaël Rougeron)
  • Yet Another Python Web Framework (Alice Bevan-McGregor)
  • Web et Python : optimiser vos applications (Antoine Pitrou)
  • Migrating to MongoDB (Bruno Morency)
  • An Introduction to MapReduce (part 1-2) (David Zuelke)

The mysterious Grid class of Formalchemy

written by arrakis, on Jan 20, 2010 6:18:00 PM.

Formalchemy is offering us multiple ways to render our data and to display it. With a form we can create new instances of your objects and modify existing ones. But, more importantly, in our case, we can use it to create multiple new instances at a time

Background

For a project at work, it was needed to generate multiple instances of an item. I decided to use formalchemy to render different form. At first, it was not that easy, when I launched the validation process, an exception was thrown because multiple values with the same key were found. The problem was caused by the fact that each new item was using the same fields name.

It was necessary to use a kind of unique id for each new item and to make sure that their fields would use this in their id

How to use it

Yeah that's cool, but how to propagated a unique to id the field and how to make the validation process to use them?

The main form

All form's definition are built using zope.schema and it's type definition tools

from formalchemy.ext.zope import FieldSet, Grid, Pk
class IOrderEditForm(interface.Interface):
      """Interface of order's edition form"""
      number = schema.Int(title=u"Id of the order", required=True)
      supplyer = schema.List(title=u"Supplyer", required=True)

class IOrderAddItemForm(interface.Interface):
      line = schema.Int(title=u"Line", required=True)
      product = schema.List(title=u"Product", required=True)
      quantity = schema.Int(title=u"Quantity", required=True)

OrderAddItemForm = Grid(IOrderAddItemForm)
OrderEditForm = FieldSet(IOrderEditForm)

class OrderEdit(object):
      _pk = Pk("number")
      interface.implements(IOrderEditForm)

class OrderAddItem(object):
      _pk = Pk("line")
      interface.implements(IOrderAddItemForm)

The pylons controller

The controller is responsible of the rendering of the different fields and to launch the validations. In our case, it's important to configure item's form with pk (primary key) flag to True.

     def edit(self):
         c.instance = OrderEdit()
         c.instance_items = []
         for i in range(0,request.params['item_count'] or 1):
             item = OrderAddItem()
             item.line = i+1
             c.istance_items.append(item)
         c.form = OrderEditForm.bind(c.instance, data=request.params or None)
         c.form_items = OrderAddItemForm.bind(c.instance_items, \
                             data=request.params or None)

         supps = [('One',1),('Two',2),('Three',3)]
         params = [c.form.supplyer.dropdown(options=supp)]  

         c.form.configure(options=params)
         c.form_items.configure(pk=True)
         if request.method == "POST" and c.form.validate() \
               and c.form_items.validate():
            #... ...
            # save routine
            #... ...
            return render("/order/detail")
         return render("/order/edit")

Conclusion

By using a primary key for your multi-items form, it will generate the correct name for each fields, including this primary key value. By example, the name of line field of the first item would be:

OrderAddItem-1-line

When you will validate your form, it will bind each post's data to the corresponding item, depending of the primary of each item ! You just need to create a cool ajaxified interface for your form and it would complete your multi-item form. Oh! And by the way, you should think about using jquery.form.js if you need to submit in an Ajaxified way your form !

Using formalchemy and zope.schema with non-sql databases

written by arrakis, on Jan 14, 2010 7:27:00 PM.

Not so long ago, I started to work on a new pylons project at work. I was now in charge of the development of a new website dealing with accountancy datas.

The particularity of this project is that data is stocked in a proprietary software and we communicate with it using a socket and a special kind of textual request language.

Doing it with Zope ?

Request are in a csv-like format. For example, to fetch all products id, name and available quantity in stock, we would send this:

RQ39,R01,,PRO,PNOM,,PNUM,PNOM,PQST

The response will be something like a csv list of the requested attributes and values. I decided to build a simple kind of ORM and to connect it to pylons with formalchemy and normal html tables.

Formalchemy is a form generator especially useful when using SQLAlchemy. But I did not want to create a kind of adaptor for our strange request system. So I decided to use zope.schema and zope.interface to define the structure of the different fields and to connect everything to my custom ORM.

1. First of all, I defined my form's model with the different field types and their attributes, that way:

class IBuyEditForm(interface.Interface):
      buyid = schema.Int(title=u'Id', readonly=True)
      prodid = schema.Int(title=u'Product', required=True)
      quantity = schema.Int(title=Quantity', required=True)

2. Secondly I implemented my form model as a new type of FieldSet:

from formalchemy.ext.zope import FieldSet

     BuyEditForm = FieldSet(IBuyEditForm)

3. Now I use my form's fieldset in a pylons controller:

from formalchemy.ext.zope import FlexibleDict
from your.project.forms import BuyEditForm
from your.project.lib.buy import BuyWriter

def edit(self):
    instance = FlexibleDict()
    c.form = BuyEditForm.bind(instance, data=request.params or None)
    if request.method == "POST" and c.form.validate():
       c.form.sync()
       BuyWriter.update(**instance)
       return redirect_to(controler='buy', action='detail', id=instance.id)
    return render("/buy/edit.mako")

Conclusion

With the simplicity of formalchemy and zope.schema, I successfuly implemented all needed forms dealing with all my custom queries in my custom ORM. The zope.schema part is very useful to define generic validation parameters and structure of forms. The formalchemy part was very easy to integrate with this kind of strange logic of development, connected with a none common way to interact data.

Thank you zope, you can be easy and useful some times!

Thank you formalchemy, you're the best !

Django, setuptools, distutils and the python environment

written by arrakis, on Oct 10, 2009 7:21:00 PM.

A couple of months ago I started to worked on a django project for a big organisation. I didn't have any experience of django but I came from the pylons/plone/python world.

For me it was logical to use the following architecture for the project:

projectname/
   src/
     django-app1
     django-app2
     django-main-project
   buildout/
     bin/
        django
        buildout
        python
        ...
     development.cfg
     production.cfg
     ...

I found a "good" recipe for django on pypi, djangorecipe. This recipe deploy a django architecture for a buildout-style project. There is a couple of problems with this recipe and with django in setuptools like projects:

1. The first problem with this recipe is that you cannot create your project as an egg, you need to use it directly in your buildout directory. It cause me problem cause all the configuration of my projects and parts of the code need to be in the django-project director. I WANT AN EGG!

2. Secondly, it try to download django from the svn repository, but I want to use the one available from pypi.

3. When I install an application for django, from pypi, I don't wanna be forced to configured it in settings.py. Entry points everybody ?

4. Paster is now the way to work when deploying and creating projects in Python. It would be easier and better to use paster and templates to create new django type of projects.


Maybe I should just re-switch to pylons but I'm not one who could take this decision....

What is your experience with django, buildout and the kind of things ?

 

Experimenting Couchdb and Python

written by arrakis, on May 20, 2009 12:22:00 PM.

For my website, I wanted to try a new type of database.

I was searching for a system free of all the difficulties and the planification needed to deploy when you are using a classical relational database.

You know, my website is really a work in progress. Depending of the time and the motivation I have, it evolve and some day I can decided to change everything. A relational schema can be hard to manipulate cause you have to fixed the basic structure at root all persistent objects.

With couchdb, I discovered that I can develop my objects in pure Python and to code the persistent routines, and after that I don't have any preocupation of the way it'll be saved.

Right now I used a small script which fill in the data into the db and by using python-couch it's really easy to do it.

By example, the topic object definition, it describe the structure of the object and all needed index: no sql, no real data type definition, just pure python and a little bit of javascript:

class Topic(Object):
    db = "topics"

    title = TextField()
    name = TextField()
    url = TextField()
    order = IntegerField()
    by_order = View('topics_by_order', '''\
             function(doc) {
                 emit(doc.order, doc);
             }''')

Really simple, with just the by_order field that can be a little bit confusing, I'll explain. Couchdb is working with JSON datatype and with a JS interpretor you can do request and manipulate data. In this case:

I create a new view on the current collection, I name it topics_by_order and I want to order the result by the order field.

As I wanted to simply the manipulation of the data, I created a new method for each view consultation. The request is just a couple of really pythonic lines of code:

def by_order(self):
    for e in Topic.query(Topic.fd, \
        Topic.by_order.map_fun, ''):

            yield e
The good thing with views is that they are stored in the database, it's a kind of index which is recalculated everytime you insert new data. The bad thing is that insertions are little slower but it's not a big trouble for me.

As you can see, python-couchdb is a really cool API. It's not very mature but I'll work on it :)

 

Resume Blog Contact Projects Buildbot Code Slides fr en