Voy a intentar explicar paso a paso cómo se crea un robot en Python desde mi propia experiencia, es decir a partir del robot que creé yo.
El robot que creé yo, Lasty está pensado para mostrar la canción que estás escuchando a través de Last.fm, más tarde llegaremos a cómo se hace eso.
Preparación
El primer paso, es crear una cuenta en App Engine, ya que por el momento Google sólo deja usar éste servicio para los robots en Wave, éste servicio aparte de dejarnos alojar nuestro robot, también tiene una completa interfaz de uso (estilo Analitycs), control de versiones, logs para debugar, servicios para configurar cron jobs, incluso un pequeña base de datos, y nos deja alojar hasta 10 aplicaciones.
El siguiente paso es obviamente tener Python instalado la versión 2.5 o mayor, si eres usuario de Mac OS X seguramente ya lo tendrás instalado, para asegurarte, abre un terminal y escribe:
~usuario$ python --version Python 2.5.1
Ahora que sabemos que tenemos Python instalado, debemos bajar la Wave Robot Python Client Library que es simplemente una carpeta con la API que debemos colocar dentro de nuestro proyecto.
Ahora es hora de crear nuestra aplicación en App Engine , nos pedirá la identificación de la aplicación (es lo que se usará en la dirección Wave de nuestro robot), el mío por ejemplo fue last-robot, y luego la Application Title que será el nombre de nuestro robot, en mi caso Lasty, al darle a Save se creará nuestra aplicación y tendremos acceso al Dashboard y todas las opciones.
Ahora que ya tenemos nuestra aplicación creada, tenemos que bajarnos el SDK de AppEngine , en ésta parte si que cambia bastante el hecho de tener Windows o Mac OS X, yo explicaré la versión para Mac OS X, pero para el resto de usuarios hay una documentación bastante completa sobre como hacerlo en otras plataformas. En Mac OS (a diferencia de Windows) han creado una interfaz gráfica bastante agradable y completa para subir el código a los servidores de AppEngine, pero también te permite ejecutarlo montando un pequeño servidor local (útil sólo para gadgets o robots con interfaz web). Cómo veis en la imagen de la derecha la interfaz es sencilla, el botón [+] para añadir una aplicación y el botón Deploy para subirla.
Mi consejo es que creéis la aplicación con el botón [+] ya que te crea la mayoría de archivos y estructura de carpetas necesarias (te ahorra tener que hacerlo tu y a mi explicarlo).
Estructura de un robot
La estructura típica de un robot es la siguiente (como siempre tomando como ejemplo a Lasty):
/Lasty app.yaml index.yaml lasty.py main.py /waveapi /assets lasty.png
Como podéis ver, los ficheros más importantes son el fichero app.yaml (de configuración e información del robot), lasty.py (archivo en Python donde hay el código del robot), carpeta /waveapi (dónde se aloja la API de Wave para Python que hemos descargado anteriormente, no hace falta que se llame así determina la importación de librerías en el fichero en Python), y la carpeta /assets (definida en el app.yaml para guardar archivos opcionales).
Empezaremos por el fichero app.yaml éste fichero es el que determina la configuración del robot, como el nombre, el archivo principal, las carpetas que tiene dentro, la version, etc:
application: last-robot version: 2 runtime: python api_version: 1 handlers: - url: /_wave/.* script: lasty.py - url: /assets static_dir: assets
Éste es un ejemplo de app.yaml, cosas importantes a tener en cuenta:
- version: Cada vez que cambiemos la versión AppEngine lo detectará y creará una rama totalmente nueva de nuestro robot, para que el cambio de versión se aplique a todo el mundo tendremos que ir al apartado Versions de nuestra cuenta de AppEngine, escoger la última versión y clicar en Make Default para que se active la nueva versión.
- url: /assets: Ésta línea define una carpeta assets que en mi caso contiene la imagen de perfil del robot, se tienen que definir aquí todas las carpetas extras que vayamos a usar y que se puedan acceder vía url (por ejemplo).
¿Cómo funciona un robot? Eventos
Un robot funciona vía Eventos, es decir cuando ocurre algo se dispara una determinada función. Hay muchos eventos, los más típicos son los que se disparan cuando un usuario es añadido al Wave, o alguien añade un nuevo blib, o alguien cambia algún texto de un blib determinado, etc.
Éstos eventos se definen en la función __main__ del código del robot, y se reflejan posteriormente en el capabilities.xml del robot, que es un fichero que le dice a Wave las capacidades o qué eventos escucha el robot.
Aprovechando los eventos explicaremos la función __main__ del código de Lasty (lasty.py):
if __name__ == '__main__':
facey = robot.Robot('Lasty',
version='2',
image_url='http://last-robot.appspot.com/assets/lasty.png',
profile_url='http://last-robot.appspot.com/')
facey.RegisterHandler(events.WAVELET_PARTICIPANTS_CHANGED, OnParticipantsChanged)
facey.RegisterHandler(events.WAVELET_SELF_ADDED, OnRobotAdded)
facey.RegisterHandler(events.BLIP_SUBMITTED, OnBlipSubmit)
facey.Run(debug=True)
Vamos a analizarlo con detalle:
En la línea 2 vemos como se define el objeto Robot, al cual le definimos el nombre del robot (el que saldrá en los Waves), la versión, la imagen de avatar y la url del perfil (aunque no sirve de nada actualmente, en el futuro puede ser útil).
En las líneas 6,7 y 8 vemos la definición de qué eventos va a escuchar el robot, en éste caso, cuando cambien los participantes, cuando se añade el robot a un Wave y cuando alguien envía un blib, como vemos después de la constante del evento, le pasamos el nombre de la función que manejará el callback del evento.
En la línea 9 activamos la función de debug, para poder escribir strings para debugar y verlas en el log del dashboard de AppEngine.
Pero antes del main, vamos a echar un vistazo a la cabecera:
# Lasty is ment to replace user-is-listening for the song that 'user' is listening
# getting that information from the last.fm rss
# last-robot@appspot.com
# author: Marti Planellas (beldar.cat@gmail.com)
# in Wave: beldar@wavesandbox.com
__author__ = 'beldar.cat@gmail.com (Marti Planellas)'
from waveapi import events
from waveapi import model
from waveapi import robot
from waveapi import document
from xml.dom import minidom
from waveapi.document import Range
import urllib
import logging
import re
logger = logging.getLogger('Facey')
logger.setLevel(logging.DEBUG)
Bueno, las líneas de la 1 a la 5, creo que es cuestión de etiqueta explicar cuál es el propósito del robot, cuál es su dirección y el autor.
De la 9 a la 12, podemos ver como se importan los módulos de la API necesarios (waveapi es la carpeta donde está la API), normalmente ésta parte siempre es igual. Cómo explicaré en siguientes posts para añadir estilos en el texto necesitaremos el objeto Range para definir el rango donde está el texto que no está incluido por defecto en el package document, por eso lo importo por separado en la línea 14.
En las líneas 13, 15, 16 y 17 se incluyen librerías de python que son necesarias en el código para diferentes asuntos.
Y finalmente en las líneas 19 y 20 se configura y activa la función de debug para lo que he explicado anteriormente.
Bueno hasta aquí la primera parte, si habéis llegado hasta aquí no os perdáis la siguiente entrega, donde comentaré las funciones de callback de los eventos y cómo añadir estilos al texto.
Posts relacionados:




#1 por David el 5 de Septiembre de 2009
| Citar
Muy bueno el tutorial. Enseña de forma simple y con un ejemplo funcional como has creado un robot para Wave con Python, además de explicar algunos detalles.
Excelente para crear el primer robot en el que poder ver la estructura básica a partir de la cual ir aprendiendo / sacando cosas de la API.
#2 por Al el 27 de Noviembre de 2009
| Citar
Imagino que si no tienes cuenta wave no sirve para nada, ¿sabes tu como conseguirlas para probarlo?
#3 por g4mb4 el 27 de Noviembre de 2009
| Citar
Para tener una cuenta de wave Al tienes que recibir una invitación, si quieres mándame tu correo a campollo@gmail.com y te envío una invitación