debug_mode=ON

Buscar en

 
 

Consumir servicios web REST en Python: ejemplo con Flickr

Escrito por gimenete hace 1 años bajo una licencia de Creative Commons Creative Commons License
2184 visitas. Etiquetas: python, flickr, web-services, rest

Flickr tiene un API REST de web services. Para utilizarla basta pedir un api_key. Esto es muy frecuente en cualquier API de web services. Para solicitarla previamente tendremos que estar registrados.

REST es una forma muy sencilla de crear y usar servicios web. Se utiliza la semántica del protocolo HTTP (métodos POST, PUT, GET, DELETE) para realizar operaciones en el servidor. El resultado de cada petición suele ser XML aunque puede ser JSON, YAML o lo que se desee. Eso lo establecerá cada servicio. Si el resultado de la petición es XML este no cumple un DTD o Schema fijo, sino que también cada servicio web suele implementar el suyo.

En este artículo simplemente voy a obtener un resultado de Flickr y lo procesaré obteniendo los datos que me interesan. Voy a obtener las fotos más recientes publicadas en Flickr. El sitio web de Flickr contiene información sobre cada método disponible en el API. El método que voy a utilizar es: flickr.photos.getRecent. Flickr además tiene un "API explorer" que permite hacer pruebas y obtener ejemplos de resultados en la propia web. Por ejemplo puedo realizar una llamada de prueba al método flickr.photos.getRecent. En la web que acabo de enlazar al enviar el formulario aparece un <iframe> con el resultado de la petición y abajo la URL que se ha invocado. La URL es:

 http://api.flickr.com/services/rest/?method=flickr.photos.getRecent&api_key=<TU_API_KEY> 

Cada uno tendrá que colocar su api_key en la URL.

Como se puede ver un servicio web REST es muy intuitivo. Se invoca la URL pertinente con el método HTTP adecuado (en nuestro caso GET, el más simple, pero podría ser PUT, POST, DELETE), y el servicio web devolverá la información solicitada o ejecutará una acción en el servidor y responderá con un mensaje.

En el caso del método flickr.photos.getRecent nos devolverá una cosa así:

<rsp stat="ok">
<photos page="1" pages="10" perpage="100" total="1000">
<photo id="3038447399" owner="41339158@N00" secret="0e064db90d" server="3193" farm="4" title="Therapy dogs at the museum - how cool!" ispublic="1" isfriend="0" isfamily="0"/>
<!-- más fotos ... -->
</photos>
</rsp>

Ahora que sabemos cómo llamar el servicio web y cómo es la información que devuelve, hay que invocarlo desde el código y parsear la respuesta. En este ejemplo al parsear el XML voy a generar una lista de objetos Photo. Esta es la clase Photo

class Photo():

    def __init__(self, id, owner, secret, server, farm, title, ispublic, isfriend, isfamily):
        self.id = id
        self.owner = owner
        self.secret = secret
        self.server = server
        self.farm = farm
        self.title = title
        self.ispublic = ispublic
        self.isfriend = isfriend
        self.isfamily = isfamily

    def getimageurl(self):
        return "http://farm%s.static.flickr.com/%d/%d_%s.jpg" % (self.farm, self.server, self.id, self.secret)

Es simple. Solamente tiene un constructor y un método. El método getimageurl() lo que hace es devolver la URL de la imagen. La forma de construir la URL está documentada en la web de Flickr.

Ahora voy a crear un ContentHandler que parsee el XML que devuelve el servicio web.

class PhotoHandler(xml.sax.handler.ContentHandler):

    def __init__(self):
        self.photos = []

    def startElement(self, name, attributes):
        if name == "photo":
            self.photos.append(Photo(int(attributes["id"]),
            attributes["owner"],
            attributes["secret"],
            int(attributes["server"]),
            int(attributes["farm"]),
            attributes["title"],
            attributes["ispublic"],
            attributes["isfriend"],
            attributes["isfamily"]))

Este ContentHandler procesará el XML guardando los datos en una lista. Por cada elemento <photo> se creará un objeto Photo con sus atributos y se añadirá a la lista. Así de simple.

Lo que queda es "ejecutar" la URL, usar el ContentHandler para parsear la respuesta, y mostrar los datos parseados:

url = "http://api.flickr.com/services/rest/?method=flickr.photos.getRecent&api_key=<TU_API_KEY>"
content = urllib.urlopen(url).read()

handler = PhotoHandler()
xml.sax.parseString(content, handler)

for photo in handler.photos:
    print photo.getimageurl()

Para ejecutar el ejemplo basta copiar y pegar los tres fragmentos de código en un fichero y poner al principio estos imports:

import urllib
import xml.sax
import xml.sax.handler

Y eso es todo. Se mostrarán por pantalla las URLs de las fotos más recientes de Flickr.

Para mejorar este ejemplo habría que:

  • Gestionar los posibles errores. El código supone que la respuesta será siempre de éxito.
  • No llamar a read() al abrir la URL porque eso guarda la respuesta en un string. Eso no es eficiente y puede traer problemas de memoria si la respuesta es muy grande. En vez de ello habría que usar streams.
 

¡Votalo! 4 votos
¡Compártelo!

        

&nbps;

&nbps;

gimenete

Sobre gimenete

Gimenete es un tipo al que le encanta programar. Lleva media vida programando en Java, y ahora le da bastante también a Python. No le hace ascos a JavaScript. Su tema de investigación favorito ahora es el cloud computing.

 
Regístrate o haz login para participar.
¿Todavía no conoces debugmodeon?
debugmodeon es la red social para profesionales de la informática
descubre debugmodeon
 

 

© Copyright 2008-2009 debug_mode=ON | Aviso legal | Contacto | FAQ | ¿Quiénes somos? |