Web Services amb Pyramid i Cornice
Contingut
Web services: teoria
Un web service és un servei al que se li poden fer consultes a través del protocol HTTP o HTTPS.
No té perquè respondre HTML, i el més habitual és que no ho faci, ja que ens complicarà el parsejar les dades i introduir-les al nostre programa. És més habitual utilitzar JSON (en altres tecnologies s'utilitza XMLRPC -Java- o SOAP -Microsoft-).
Per Python/Pyramid treballarem amb JSON: wikipedia i json.org.
Avantatge de JSON: té la mateixa sintaxi (o molt semblant) a les estructures de dades de Python:
- Strings entre cometes:
"això és una cadena de caràcters"
- Llistes o arrays amb claudàtors
[1, 4, "hola", 3.5]
- Diccionaris o arrays associatius (en JSON en diuen "objects") amb claus
{ "nom":"Xavier", "cognom1":"Sánchez" , ... }
- Booleans: true i false (en minúscules, aquest no és com en Python :(
- ...
Web Services a Pyramid: llibreria Cornice
Package: Cornice
Preparant scaffolds/buildout
Abans de començar cal crear un nou projecte amb Pyramid (Buildout) i cal afegir la llibreria cornice al buildout.cfg.
Teniu 2 opcions:
- Instal·lar el cornice al vostre virtualenv, amb el què es crearà una nova plantilla que podeu utilitzar creant un nou scaffold per cornice:
(env) $ pcreate -t cornice nomprojecte
- Si volem incorporar cornice a un projecte Pyramid amb Buildout, cal modificar:
- __init__.py , cal afegir:
config.include("cornice")
- Afegir la llibreries cornice i PasteDeploy al buildout.cfg.
setup.py : als "requires" cal afegir "cornice", "PasteScript" i "waitress".- NOTA: no cal instal·lar cornice al virtualenv si només treballem amb buildout.
- NOTA2: si estem testejant els serveis ens convé desactivar la "pyramid_debugtoolbar". Ho pots fer traient-la del development.ini o bé engegant la versió de producció (production.ini) on la toolbar no apareix als includes.
- __init__.py , cal afegir:
Desenvolupant el web service
Anem al lío:
- Recorda que treballarem amb JSON: wikipedia i json.org.
- Altres tecnologies: Java utilitza XMLRPC, i Microsfot SOAP.
- Doc.oficial: http://packages.python.org/cornice/
- Interessant i essencial el "Quick Start for people in a hurry" (emmagatzema objectes JSON),
però hi ha un error: on diu _VALUES.set(...) en realitat ha de ser:_VALUES[key] = json.loads(request.body)
En aquest exemple tenim un diccionari (_VALUES) on anem enregistrant dades per POST. A través de GET podem obtenir de nou aquests valors.
Arranquem el servei amb la versió de producció (no té la pyramid_debugtoolbar i ens anirà millor per depurar algunes pàgines):
$ bin/pserve production.ini
Testejant el servei amb CURL
Els serveis es poden provar des de la línia de comanda amb comanda curl (instal·leu-la amb apt-get). Consulta el man o també manual curl online.
- OJU amb JSON i curl, les cometes han de ser simples per encapsular el string de la comanda, i dobles pels elements:
$ curl http://el/meu/servei -d '{"nom1":"valor1",...}'
- Més opcions curl: -X {GET|POST|PUT}
Exemples
Exemples amb el cas del "Quick start for people in a hurry", si arrenquem el test des d'un Buildout:
- POST: (afegint -d a "curl")
- Insertem el string "manel" en la clau (key) "nom":
$ curl http://localhost:6543/values/nom -d '"manel"'
- Insertem la llista [1, 5, 3.5, "hola"] en la clau "cosetes":
$ curl http://localhost:6543/values/cosetes -d '[1, 5, 3.5, "hola"]'
- NOTA: para atenció en què la llista és format JSON, que és exactament igual al de les llistes de Python. Si cometem algun error de sintaxi el servei ens tornarà "false".
- Insertem el string "manel" en la clau (key) "nom":
- GET: (sense paràmetres al "curl", a part de la URL)
- Extraiem el valor de la clau "nom" (ens ha de tornar "manel"):
$ curl http://localhost:6543/values/nom
- Extraiem el valor de la clau "nom" (ens ha de tornar "manel"):
Per veure que no funciona qualsevol cosa, podem insertar una booleana:
$ curl http://localhost:6543/values/prova -d 'true'
...i el servei ens respondrà "true" (= "tot ha anat bé")
Però si insertem un valor qualsevol (sense cometes, per tant NO és un string):
$ curl http://localhost:6543/values/prova -d 'truexx'
...el servei ens respondrà "false" (= "alguna cosa ha anat malament", en particular no s'ha descodificat com a JSON vàlid).
Cridar un web service des d'un altre mòdul Python
Per fer crides des d'un altre mòdul de Python tenim bàsicament 2 llibreries:
- urllib: més senzilla i ja ve incorporada al sistema per defecte (no cal instal·lar res).
- Llibreria PycURL: ens permet fer crides des de python amb cURL.
- Oju: s'ha d'instal·lar al sistema (o al virtualenv) i cal afegir prèviament els paquets: python2.?-dev i libcurl4-gnutls-dev
- Després ja es pot instal·lar amb
$ easy_install pycurl