El Blog de Trespams

Blog personal sobre tecnologia, gestió de projectes i coses que se me passen pel cap

Creant un web service de proves amb Bottle

Els cap de setmanes mira que intento estar una mica allunyat de la programació, intent llegir, passejar un poc i estar amb la família, però quan arriba el vespre i l'opció és convertir-se ja en un xuclador passiu d'anuncis publicitaris ja no puc més. Amb el temps el meu nivell de tolerància a les pauses publicitàries ha baixat molt. Ja no puc aguantar més de tres minuts, mir el mòbil a veure quines piulades noves hi ha al twitter, llegeixo un poc, ... Però si la pausa ja es fa massa gran ja m'avorreixo, no m'agrada estar avorrit, així que sovint acab davant l'ordinador, a provar idees, ...

Aquest cap de setmana m'ha passat això. Estava provant una web que hem fet que connecta amb un web service i se m'ha passat pel cap emular el servei, creant el meu propi servei web a efectes de test. Si ho pensau bé és una xorrada: es fan les peticions contra el servei real i es guarden les respostes. Després sols hem de substituir el servei real amb el nostre i en funció de les peticions enviar les respostes predefinides que hem capturat.

La primera intenció era fer-ho amb Django, però fet i fet el servei és tan simple que no necessita de tot l'aparell i funcionalitat de Django. Era hora de cercar un micro-framework ·[1]. De micro-frameworks per Python n'hi ha per donar i remanar. En aquest cas vaig optar per provar-ne un que m'agrada força, el bottle, més que res perquè es un sol mòdul, no té dependències externes i està ben documentat. Un hello world és

from bottle import route, run


@route('/:name')
def index(name='World'):
return '<b>Hello %s!</b>' % name
run(host='localhost', port=8080)

Com que es tracta d'obtenir i tractar peticions xml [2] vaig utilitzar també la llibreria lxml. Així es tracta de capturar una petició xml que es reb via POST i en funció del contingut d'aquest xml enviar una resposta predefinida com a resposta.

La cosa queda així:

# -*- coding: UTF-8 -*-

import route, run, request
from lxml import etree
import os

app_root = os.path.abspath(os.path.dirname(__file__))


@route('/', method='POST')
def fake_ws():
body = request.body.read()
root = etree.fromstring(body).getroottree()
rq = root.getroot().tag
if rq == 'op1':
arx = os.path.join(app_root, 'rta/op1.xml')
elif rq == 'op2: arx = os.path.join(app_root, 'rta / op2.xml')' # etc #ja es veu com pot anar no?
return open(arx, 'r').read()


run(host='localhost', port=9090, reloader=True)

Donant-li nom a l'arxiu i executant-lo tindrem un servei web xorra escoltant al port 9090 i que per testejar va més que bé.

Òbviament convertir això en un vertader servei que en lloc de respostes predefinides faci més feina és sols cosa de programar. Estendre el servei de proves a més opcions o contemplar altres casos, és també igual de senzill.

Està clar que això ho podem fer en gairebé qualsevol llenguatge. Python en aquest cas el que té és que ens dóna unes eines molt potents i simples. No hem de recompilar res, podem anar afegit nous exemples per testejar de manera trivial i el millor de tot, el servidor de test és tant senzill que no introdueix renou addicional a l'hora de provar. Com que les respostes les tenim predefinides podem optar per enviar-ne una o altra segons convengui, modificar-la per tractar casos frontera, o bé tractar-les com a una plantilla, Bottle té també un mini-llenguatge de plantilles, i que la resposta varii segons ens convengui.

[1] Bé, ho podria haver fet amb el servidor web que duu la llibreria estàndard de Python, però què voleu, m'encanten aquestes coses!

[2] També hi ha eines que farien bé la feina a la llibreria de Python, com l'xml.etree però m'agrada lxml.

blog comments powered by Disqus