lunes, 22 de noviembre de 2010

Escribiendo en Python una app de Facebook

Escribir una aplicación de Facebook es en esencia lo mismo que escribir cualquier aplicación web, sólo con un paso adicional en la salida de su aplicación web se procesa y se inserta en una página de Facebook. Aunque PHP parece la opción más popular (y es lo que Facebook se está escrito en) que puede utilizar cualquiera de los marcos de Python para escribir una aplicación. Incluso se podría liar si estuviera inclinado a hacerlo. Yo Turbogears, pero fácilmente se podría adaptar este marco a otro.

Sirviendo FBML

Puede generar FBML con cualquier sistema de plantillas Python. Utilize Genshi que fue muy bueno para generar FBML para mí, siempre y cuando se le instruyó para producir XML y HTML no, que usted puede hacer mediante la adición de format = "xml" al exponer decorador. Por ejemplo, aquí está el método de controlador para estadísticas.



  @expose(template="genshi:microbes.templates.stats", format="xml")
    def stats(self, *args, **kwargs):

        num_users = User.select().count()
        num_added_users = User.select(User.q.added==True).count()
        num_infections = Infection.select().count()

        return dict(num_users=num_users,
                    num_added_users=num_added_users,
                    num_infections=num_infections)


Para ver lo que hace, echar un vistazo a la fuente de http://microbes.willmcgugan.com, que se ve el FBML (que no sean procesadas por Facebook).

Agregar y quitar usuarios

La primera página que el usuario solicita probablemente no será FBML en absoluto. Cuando el usuario agrega la aplicación, a continuación, Facebook va a redirigir a una URL definida en la configuración de su aplicación. Si su aplicación necesita para almacenar los usuarios a continuación, aquí es donde debe agregar los usuarios de Identificación de la base de datos. A continuación, puede mostrar una página de bienvenida, o simplemente redirigir a una de las páginas de la aplicación. Del mismo modo, cuando un usuario elimina la aplicación de las solicitudes de servidor de Facebook otro. Este "usuario eliminado" URL no es en realidad vista por el usuario por lo que no es necesario devolver cualquier contenido significativo para él.

Uso de API en Facebook

Para otras páginas dentro de la aplicación que tiene que hacer un poco de trabajo para recuperar los parámetros de la solicitud de la página que le permiten trabajar con la API.

Hay dos módulos de Python para ayudar con la escritura de aplicaciones de Facebook. PyFacebook es un contenedor completo para API de FB y puede ser la opción obvia para escribir una nueva solicitud. Sin embargo, la documentación fue Django céntrica y yo quería para integrar una aplicación Turbogears existentes. Así que decidí utilizar minifb, que proporciona el código necesario de la caldera de la placa para hacer llamadas a la API de Facebook. Si escribo otra aplicación que probablemente usaría PyFacebook para guardar un poco de tiempo, pero resulta que hacerlo de la manera dura que no es difícil en absoluto.

Antes de utilizar los parámetros de una solicitud de Facebook, que necesitan ser validados con una llamada a minifb.validate que tiene su clave secreta (suministrada por Facebook al crear una aplicación) y un diccionario que contiene los parámetros de la petición. En Turbogears sólo tendría que pasar los argumentos clave del método de controlador de minifb.validate. Cuando un usuario ha añadido su aplicación, cada llamada tiene al menos dos parámetros proporcionados por el servidor de Facebook, "usuario" es el identificador de usuario del usuario actual y "session_key 'es una cadena que identifica el actual período de sesiones que se necesita para llamadas a la API . En el espíritu de la eliminación - aun mínimo - repetitivo escribí un decorador para agregar a los métodos de control que realiza la validación de paso y, opcionalmente, redirecciona a la página si el usuario no está conectado.


  _login_url = "http://apps.facebook.com/virtualmicrobes/"

def expose_fb(no_redirect=False):

    def decorate(f):

        def func(*args,  **kwargs):
            try:
                arguments = minifb.validate(FACEBOOK_SECRET_KEY, kwargs)
            except Exception, e:
                return str(e)

            if not no_redirect and "session_key" not in arguments:
                return '<fb :redirect url="%s" />'%_login_url

            ret = f(*args, **arguments)

            return ret

        func.__dict__.update(f.__dict__)
        return func

    return decorate



Para utilizar este decorador, simplemente añadir, antes de exponer Turbogears @ decorador, lo que hará que el controlador aparezca como cualquier otra solicitud.

La función minifb.call se puede utilizar para hacer llamadas a la API de Facebook. Toma el nombre del método de la API al que desea llamar, seguido de su clave de API, clave secreta, clave de sesión y los parámetros adicionales requeridos por el método. Se envía una solicitud POST al servidor de Facebook y analiza el JSON devuelto. El valor de retorno de minifb.call es una colección de tipos de datos básicos de Python, así que es muy fácil trabajar con ellos. Por lo general las llamadas API devolverá una lista de enteros / cadenas, o, posiblemente, una lista de los diccionarios.

Facebook Gotchas

El servidor de Facebook establece una restricción de tiempo de espera en las páginas de la aplicación. Desde mis experimentos esto parece ser alrededor de 7 segundos, si el servidor de Facebook no recibe una respuesta de su aplicación web dentro de ese plazo, se mostrará "página no encontrada", o palabras que afectan. Si el servidor está bajo tensión y que también están haciendo un montón de llamadas a la API, entonces es muy posible pasar el tiempo de espera. Yo inicialmente tenía este problema, pero resultó que se debe a un servidor DNS defectuosa que webfaction.com rápidamente fija para mí. Por lo que no puede experimentar este problema, pero si lo hace me permito sugerir la reducción del número de llamadas a la API que realice, si es posible, y si no les importa el valor de retorno de sus llamadas a la API que valdría la pena correr en un aparte hilo. Yo escribí la siguiente función auxiliar para hacer precisamente eso.

 def fire_and_forget(callable, *args, **kwargs):

    def do_callable():
        try:
            callable(*args, **kwargs)
        except:
            pass

    thread = Thread(target=do_callable)
    thread.start()



Si usted envuelve una llamada a la API con fire_and_forget se ejecutará de forma asíncrona y reducir el tiempo para atender la solicitud.

FUENTE
http://www.willmcgugan.com/blog/tech/2008/2/13/writing-a-facebook-application-with-python-pt-ii/ 

1 comentario: