27 de Julio de 2016 · 3 min de lectura
SOAP (o Simple Object Access Protocol) es un protocolo de comunicación diseñado para intercambiar mensajes en formato XML en una red de ordenadores, utilizando el protocolo HTTP. Normalmente se utiliza para acceder a servicios web. Suds es una librería de Python que hace la función de cliente de un servicio SOAP para facilitar la conexión a un Web Service.
En los últimos días en la oficina hemos desplegado un nuevo proyecto en el entorno para mostrarlo por primera vez a los clientes. Este proyecto se conecta con un PMS, del cual consulta disponibilidad y le envía las reservas que se realicen a través de la web. Por esto, se utiliza un paquete donde se encuentra el servicio para la conexión. Este paquete utiliza la librería Suds, concretamente la versión 0.6 del fork suds-jurko, ya que la librería original no está mantenida.
Cual fue nuestra sorpresa al ver que cuando se instanciaba el cliente para la conexión al PMS se producía un error 500 (Internal Server Error), cosa que no nos había pasado durante el desarrollo. La sorpresa fue mayor al ver que este error 500 se producía porque la suds intentaba acceder a un fichero sobre el cual no tenía permisos, ya que pertenecía a otra aplicación desplegada en el mismo servidor.
Después de una primera búsqueda, encontramos que este fichero se utiliza como una pequeña caché por parte de la librería i que se indica el fichero a partir de otro, el “version”. Este fichero “version” lo escribe la propia librería suds en el directorio por defecto “/tmp/suds/”. ¿Qué pasaba entonces? que cuando se utilizaba la librería en el cliente de este nuevo proyecto, este veía que el fichero ya estaba creado en “/tmp/suds/version” y que este le indicaba el fichero de caché del otro proyecto. Por esto, cuando iba a escribir en la caché fallaba porque no tenía permisos de escritura en ella.
A raíz de esto, un compañero que ya se había encontrado con este tema nos indico que dos despliegues diferentes que utilicen suds en el mismo servidor tienen conflictos por este motivo, pero hay una solución: a la hora de instanciar el cliente se le puede indicar qué caché ha de utilizar. De esta forma, si la caché no existe se crea y no se confunde con la ya existente de otra aplicación.
A nivel de código, la solución es la siguiente: se ha de importar la clase “ObjectCache” a la vez que el cliente de suds. Hay que instanciar esta caché indicándole una nueva ruta y el tiempo de duración que se quiere que tenga. Para seguir el patrón que marca la librería, la nueva ruta la indicaremos como “/tmp/suds/APP_SLUG”. A continuación, cuando se instancia el cliente de suds, se le ha de pasar por parámetro la nueva caché. Internamente, la librería tendrá en cuenta esta nueva configuración y no entrará en conflicto con otros despliegues que utilicen suds.
from suds.client import Client, ObjectCache
cache_path = "/tmp/suds/{}".format(APP_SLUG) cache = ObjectCache(location=cache_path, days=1) client = Client(url, cache=cache)
from suds.client import Client, ObjectCache
cache_path = "/tmp/suds/{}".format(APP_SLUG) cache = ObjectCache(location=cache_path, days=1) client = Client(url, cache=cache)
from suds.client import Client, ObjectCache
cache_path = "/tmp/suds/{}".format(APP_SLUG) cache = ObjectCache(location=cache_path, days=1) client = Client(url, cache=cache)