Nautilebleu

Dive into my universe

Posts tagged django

0 notes &

Testing a ØMQ async job with Python Mock

At Greenbureau, we are huge fans of ZeroMQ, a network library that eases building our queue management tool, called HGMQ.

Below is a typical job:

@hgmq.job('async_job')
def async_job(msg):
    # Do something usefull here
    actor = Actor.objects.get(name=msg["name"])
    msg = {
        "results": [fact.title for fact in actor.facts.all()]
    }
    hgmq.send_job('core/back', 'recv_async_job', msg)

The @hgmq.job decorator as the same role as the @task in Celery or the @job for rq.

As always, testing an async process is a hard job (^^). Not only being able to test the whole context, we can call the function in a blocking manner. But how to test what is done, as the function doesn’t return a value? If it saves some data to the DB, we can check how they are altered but what if the job is read only?

Hopefully, we can count on Python Mock library and especially the call helper.

So in a test, we are able to get the message sent via ØMQ:

from django.test import TestCase
from mock import Mock

from apps.corehgmq import hgmq  # Our hgmq instance

# Prevent to send job to the back during tests
hgmq.send_job = Mock(return_value=None)


class JobTestCase(TestCase):
    def test_async_job(self):
        msg = {
            'params': {
                'name': 'chuck'
            }
        }
        responses = [
            'Chuck Norris a déjà compté jusqu’à l’infini. Deux fois.',
            'La gravité, c'est la force qui fait tenir la Terre sous Chuck Norris',
            'L'avenir se demande parfois ce que Chuck Norris lui réserve.',
            'Dieu voulait créer l'Univers en 10 jours. Chuck Norris lui en a laissé 6.',
            'Chuck Norris est la raison pour laquelle Cthulhu se cache.',
            'Chuck Norris a lu le texte de la Constitution européenne.'
        ]
        async_job(msg)
        dest, job, response = hgmq.send_job.call_args[0]
        self.assertEquals(dest, 'core/back')
        self.assertEquals(job, 'recv_async_job')
        self.assertEquals(response["results"],
                          responses)

Note that the call helper has lots of other goodies, such as call_list(), which stores the sequences of call to the mocked object.

Filed under python zmq unittest async django

15 notes &

Github comme backup du web

Ce matin je cherchais un article dont je me souvenais qu’il était paru sur django advent, à l’occasion de la sortie de django1.2. Problème le site est down et même Google n’a pas cache pour ce site.

Finalement, en reformulant ma requête je me suis rendu compte que les articles étaient disponibles dans un dépôt sur github.

Ce qui m’amène à me demander si github ne pourrait jouer un rôle pour la préservation des documents, notamment avec la multiplication des blogs utilisant Pelican, Jekill ou encore Octopress ?

Filed under github django octopress pelican jekill

0 notes &

Get the verbose name of a Django model field

Today during the developpement of a management command that merge fields of a model into one field, I was looking for a way to reuse the verbose_name of the field.

Say for example your model is defined like that:

# models.py
class Page(models.Model):
    title = models.CharField("Your page's title", max_length=200)
    body = models.TextField("Some thoughts")

In your management command, you can get the verbose name from the class:

Page._meta.__dict__['_field_name_cache'][idx].__dict__['verbose_name']

or from the object’s instance:

p = Page()
p._meta.__dict__['_field_name_cache'][idx].__dict__['verbose_name']

where idx is the position of the field in the class.

Because this position may change, it’s probably a better idea to loop over the _field_name_cache:

for field in p._meta.__dict__['_field_name_cache']:
    if field.__dict__['name'] == 'title':
        print field.__dict__['verbose_name']
>>> Your page's title

One last thing, because two of the key names starts with an underscore, these dicts are treated as internals. They may change or disappear with a django upgrade… The _meta nearly official API really needs to turn into something more consistant.

Filed under django model field verbose_name

0 notes &

Importer dans django depuis Tumblr

Je travaille depuis quelque temps à me (re)créer un site personnel, avec django. Mais je ne voudrais perdre les articles postés sur Tumblr.

Grâce à python tumblr [en], c’est très simple. J’ai choisi de faire une commande personnalisé, qui pourra être lancée depuis le shell de cette façon :

$ python manage.py import_from_tumblr

Pour cela il faut créer un dossier management dans le dossier de votre application, puis un dossier commands à l’intérieur de celui-ci. En plus des inévitables __init__.py, créer dans le dossier commands un fichier nommé import_from_tumblr.py.

Dans ce fichier, coller le code de ce lien sur Friendpaste [en]

Pour une fois la document sur le site est assez limitée, mais tout est très bien expliqué sur ce post de Brian Rosner[en].

Filed under django python tumblr management command

0 notes &

django_hg UI

Although I didn’t post any message, I did not stay off these last days. I work on django_hg UI. I take my time, to refine, which is a real pleasure too rare in production. In addition, this leads me to some reflections on the underlying code.

Normally, the code logic should have been based on uses cases. However, given the highly experimental kind of this project (for me), it was quite difficult to conceive any architecture code and the corresponding UI before me diving into the code. In fact, before I start, I was not sure to be able to list the contents of a Mercurial repository in django, and I did not really dream up doing the authentication by django! This project is going much further than I thought, which explains that the code will have to evolve.

In short, I realized that had 3 levels django_hg (between parentheses, the name of the corresponding django_hg):

  • The list of repositories (list);
  • Different views of a repository: Browse (browse), list revisions (Changesets), display a revision (Changeset) and view an overview (Overview)
  • Different views of a file in a repository: the revisions experienced by this file (filelog), display the source code or a preview for images and pdfs (filerev), diff between 2 revisions (filediff, very far to be operational yet)

From the viewpoint of the interface, these three types of files use different templates. But I’m currently thinking that I should refactor my code so that it has only 3 views, with cases for some of them.

This does not however going to be right away, because I would move the graphic considerations. Speaking about that, what is the good practice to distribute graphics (images, css, …) for a reusable application?

Filed under django django_hg mercurial

0 notes &

Interface de django_hg

Bien que je n’ai pas posté de message, je ne suis pas resté inactif ses derniers jours. Je travaille sur l’interface. Je prend mon temps, pour peaufiner, ce qui est un véritable plaisir, trop rare en production. En outre, cela m’amène à certaines réflexions sur le code sous-jacent.

Normalement, la logique du code aurait dû être issue des uses-cases. Cependant, étant donné la nature très expérimentale (pour moi) de ce projet, il était assez difficile de concevoir toute l’architecture du code et l’interface correspondante avant de me plonger dans le code. En fait, avant de commencer, je n’étais pas sûr d’arriver à lister le contenu d’un repository Mercurial dans django, et je n’imaginais pas vraiment faire l’authentification par django ! Ce projet est donc allé beaucoup plus loin que je ne le pensais, ce qui explique que le code soit amené à évoluer.

Bref, je me suis rendu compte que django_hg avait 3 niveaux (entre parenthèses, le nom de la vue correspondante dans django_hg) :

  • la liste des repositories (list) ;
  • différentes vues d’un repository : parcourir (browse), lister les révisions (changesets), afficher une révision (changeset) et afficher un aperçu général (overview)
  • différentes vues d’un fichier au sein d’un repository: les révisions qu’a connu ce fichier (filelog), afficher du code source ou d’un aperçu pour les images et les pdfs (filerev), les différences entre 2 révisions (filediff, très loin encore d’être opérationnel)

Du point de vue de l’interface, ces trois types de fichiers utilisent des templates différents. Mais je suis en train de me dire que je pourrais refactoriser mon code pour qu’il n’ait que 3 vues, avec pour certains, plusieurs cas de figure.

Cela ne vas toutefois pas être pour tout de suite, car je voudrais avancer sur les considérations graphiques avant. À ce propos, quelles sont les bonnes pratiques pour distribuer des ressources graphiques (images, css, …) pour une application réutilisable ?

Filed under django django_hg mercurial

0 notes &

django_hg : authentication throught django is OK

This is an important step in django_hg build has been reached : authentication — HTTP(S) only — of clone, pushand pullcommands sended by Mercurial is completely handled by django.

There’s two majors workflows:

  • For public projects (with anonymous_access sets to True), clone et pull are anonymous. push requires an authentication, the user must have the read/write permission for the projet. This schema is often used for open-source projects.
  • For private projects (anonymous_access sets to False), all commands require to have read/write permission for the projet.

In this context, read permission only allow to display project in the browser. I will rename it into web view. This change won’t have any impact on the software, but it will clarify things.

In the next weeks, I will work on the UI, which leads me to see how CSS and images are handled in django reusable apps, like those found in pinax [en]. I also need to complete unavailable functionalities, like diff, branches, …

Afterwards, I think I will add a mini bugtracker, so django_hg will be a simple yet complete tool.

Filed under django django_hg hg mercurial authentication