Suds cache

December 12, 2012

I’m not a fan of cache where they are not needed, because it can turn a simple task into a no-so-simple task, specially when you don’t expect a cache to exists. This happens to suds, the probably best web service access package existing in python. It uses a cache with a default duration of one day stored in /tmp/suds. That cache only cache wsdl and xsd.

I see this feature could have huge advantages to projects using lots of wsdl and xsd under heavy load, because wsdl and xsd don’t change that often,  however its default values could lead to a headache, because you (at least not me) don’t expect to be a cache at all, and, after you realize there are a cache, you wouldn’t expect to be stored in disk.

To purge the cache, well in my case just the entry of the wsdl I need to be reloaded, it works to remove the file containing it.


Django signals and fixtures

December 10, 2012

Django signals are one of the more powerful tools we have. They let you focus in what you want to do, and the keep you dry. They can be also a real nightmare when there are lots of them, not well documented, and even one signal could perform tasks that sends signals to other handlers. Under this circumstances testing is your only ally, but creating fixtures is a tedious work, well, creating fixtures that works on medium complex projects is always a pain, but if you have lots of signals connected, then it turns into hell.

As the project is complex, you can’t simply dumpdata, so you must write your fixtures “by hand”. When you do this, and try to load them with loaddata, you realize that some of the database objects you manually created in your fixture, are magically generated when the fixture is loaded, and then, when it tries to load what you wrote, it fails because the data is already on db. The question is that, when your fixtures are loaded, they send signals, so you will need to note this. However the django developers provided us a way to skip those signals when a operation such as syncdb or loaddata is in progress. Whenever this happens, the signal handler will receive an extra keyword in **kwargs raw, so you can use it to avoid running a signal handler like this.

@receiver(post_save, sender=ModelA)
def signal_handler(sender, **kwargs):
    raw = kwargs.get('raw', False)
    if not raw:
        <do whatever>

Unfortunately you need to do this in all the signals you want to skip. I’m considering do it in all the signals handlers that perform database inserts or updates.


Vacations over, Jasig CAS and Django

September 7, 2012

This is my first week after a whole month on vacations, so I’m feeling plenty of energy to work in my two principal projects at work:

  • Jasig CAS
  • A Django app to manage digital identity

On the Jasig CAS side, I have some upgrades to do, and also some challenges to face. Jasig CAS has a problem with the documentation. It symply doesn’t exists. The documentation is maintained separated from source, and they don’t have any QA process on it. I manage a custom deployment with a custom theme, and custom authentication handlers and repositories, to support spanish DNIe. To do this I need a custom login-webflow, so every new versión I need to figure out what changed to incorporated it into our login-webflow. With the source in Github the best  way to do this is using “history” on the login-webflow of the project.

I often need to expose user data through Web Services to other apps. Depending on the nature of the user data exposed this has some security concerns. My challenge regarding Jasig CAS is to include in the attributes some ones gathered throw web services. Doing this way I ensure the user data are exposed when the user is logged, so I have a point, a crazy developer won’t be able to poll the entire user database.

On the other hand the Django project has tons of things to do. The upgrade work is a continuous task, because I use so many libraries, that they are always getting security upgrades. This project is being developed in an internal svn repository. I want to move the project to git, mainly because I want to use feature branches to avoid hot fixes issues. I’m using jenkins to tests the test, although our test coverage is not that high now. I would like to publish this project in github too,  my boss used to agreed me, but he always said we need to improve the project to publish it “finished”. I convinced him that developing in github is a good idea, because if no one gets involve then I won’t be slower, but if some one gets involve I’ll expend some time in managing his/her collaborations, but also won’t expend time actually doing what he/she commited.


The (almost) perfect Django IDE: Pycharm 2.5

May 16, 2012

Disclaimer: Como hace algún tiempo escribí unos cuantos artículos sobre IDEs en inglés, considero justo hacer lo mismo con este.

Some time ago, I wrote a bunch of posts about state of the art IDEs for Django in that moment. I didn’t give up in my search, but I felt there was not reason to continue writing about thart. Until now.

The first time I gave a chance to PyCharm 2.5 I finished it thinking “What else can I expect for a Django IDE?”. I decide not to write a post in that moment, but to use it exclusivly as long as free trial allows me. It has several features I’m really keen on such as code autocompletion, django debugging, imports assitant, etc. One of the features surprised me more was the posibility of using the editor as a plain VIM (althought I don’t use it after all).

This is much better than any other Django IDE I have tried, but not everything shine. It’s propietary software and that’s a painful kick for a free software fan like me. Ok, it’s cheap, but I’m most concerned about the ‘free’ as in free speech (not in free beer). I found myself using ‘grep -r’ to find some usages, although usages features works really good in most circumstances. The dictionary import is easy, but involve the conversion of aspell dict manually, it should be automatically. Theres not support no wsdl, which is a pity, but you still can use a standalone such as soapUI, (which was suggested by jetbrains staff).

On the pros, I felt it really smooth, not as resource greedy as Eclipse or Netbeans, the code completion works really well, the debugging is pretty easy too, although it should be possible to use it for management command in an easy way too. One of the most interesting features is the code inspection. It performs a bunch of test on code, and let you see were you are not doing the things perfectly in a lot of different ways, such as ensuring PEP-8, checking CSS syntax, etc. this drive you to a better, more compatible, code; and hooking this feature to commits is awesome, as it prevents you from putting bad code into repository.

As I said we almost have the perfect Django IDE. Thank you Jetbrains folks!.


Generando “fixtures” con sentido

April 25, 2012

Una de las cosas que menos me gusta de trabajar con Django es la generación de datos de prueba. Habitualmente cuando desarrollamos aplicaciones más o menos sencillas tenemos un servidor de explotación o producción, un servidor de pre-explotación o pre-producción y máquinas de desarrollo. Cuando la aplicación ya tiene cierta entidad, se hace necesario disponer de un conjunto de datos que podamos usar para comprobar el correcto funcionamiento de las distintas características ya sean nuevas o no. Además estos datos son también necesario para poder ejecutar los tests. Nunca he encontrado un mecanismo suficientemente bueno para, coger datos de producción, y pasarlos a los entornos de pre-producción o desarrollo.

He inspeccionado un poco por encima las alternativas que se muestran en Django Packages, pero ninguna me termina de parecer del todo buena. Muchas están centradas en la generación de datos para tests, que es tremendamente interesante, pero no es exactamente lo que estoy buscando.

A mi me gustaría tener un mecanismo mediante el que pudiera elegir unos cuantos objetos, y simplemente que todos los related a dichos objetos “vinieran” con ellos. De este modo si estuviera trabajando en un sitio en el que existiesen distintos tipos de roles, podría elegir un usuario de cada rol, y generar un conjunto de datos que me permita comprobar que cada uno puede hacer lo que se supone que puede hacer.

Alguien había publicado este snippet, pero no funciona debido a que utiliza partes internas de la api de django y cambiaron en la versión 1.3, así que me puse manos a la obra e hice lo mismo utilizando los mecanismos que existen ahora para hacer eso.

Este código es una acción para la interfaz administrativa, que se puede hacer disponible “site-wide”. Lo que hace es, dada una lista de objetos (qs), calcular la lista de objetos que se borrarían a través de “on cascade”, etc. Utiliza ese mecanismo, así que si se modifica el comportamiento ante borrado de un modelo probablemente no funcione adecuadamente.


Cadenas y Tuplas

April 24, 2012

Esta tarde he estado trabajando en una aplicación y me ha ocurrido una cosa curiosa, no es que no me hubiera ocurrido antes, pero no me había llevado tanto tiempo darme cuenta.

>>> a = "NIF"
>>> type(a)
<type 'str'>
>>> a = "NIF",
>>> type(a)
<type 'tuple'>

La moraleja de la historia es que una coma, puede tener entretenido veinte minutos.

No obstante, estoy seguro de que volveré a tropezar en la misma piedra.


La historia se hace como se puede

April 20, 2012

Decía hace unos días la presidenta argentina Cristina Fernández de Kirchner que la “Historia se hace como se puede”. Esto unido a que los últimos días he podido rescatar mi faceta como desarrollador me ha hecho darme cuenta de que tiene razón. Siempre pensé que soy más un desarrollador que un administrador de sistemas o de servicios, pero en mi vida profesional esta última faceta siempre ha sido más importante que la primera.

Desde hace unos meses cuando dejé Galotecnia, no he podido dedicarme en profundidad a desarrollar, que es lo que realmente me apasiona, pero esto ha cambiado en las últimas semanas. Ayer fue uno de los días en los que más he disfrutado de mi trabajo en los últimos meses.

Como siempre sigo “picando” Django, y la aplicación que me ocupa está muy dirigida por los datos (data-driven) esto hace que haya que buscar un mecanismo para poder pasar de pre-explotación a explotación con nuevos datos. Básicamente se me ocurren tres aproximaciones:

  • Utilizar initial_data
  • Utilizar south
  • Utilizar scripts fabric

En condiciones normales me decantaría probablemente por las “data-migration” de south, pero la aplicación utiliza una base de datos no soportada (no preguntes), así que esto representaba una gran oportunidad para trabajar con fabric. Aunque fabric no está diseñado exclusivamente para esto su integración don Django permite importar los modelos y crear las entradas que sean necesarias. Anteriormente teníamos unos scripts hechos en una mezcla entre python y bash para cargar algunos datos, pero estos no estaban actualizados, así que ahora ya podemos usar fabric para eso.

Por otro lado he podido probar bootstrap que es algo que llevaba algún tiempo queriendo hacer. Yo no soy un diseñador y contar con una herramienta como esta me parece muy positivo. Sin embargo creo que no voy a poder profundizar mucho en esta herramienta con este proyecto. Ya habrá más proyectos!.

Hoy me toca seguir trabajando en este proyecto. En principio tendré que llamar a un procedimiento almacenado en una base de datos Oracle que es algo que tampoco he hecho nunca, aunque he leído que es relativamente sencillo

Una cosa “chula” que hice ayer fue implemenar un Mixin que permite validar un NIF, NIE o CIF español. En “django.contrib.localflavor.es” hay un tipo de form field que permite hacer esto (aunque creo que la validación del NIE es incorrecta), pero en mi formulario se almacena por separado el tipo de documento identificativo y el propio documento. Hice un pequeño mixin que contiene un método clean que tiene en cuenta todas las posibilidades, las clases que hereden de forms.ModelForm o forms.Form y este mixin pueden aprovechar esta validación lo cual, teniendo en cuenta que se usa en varios formularios por toda la aplicación, es muy deseable.