Introducción a Google App Engine

Seguro que has oído hablar de ella. Seguro que has visto alguna vez su logotipo. Seguro que uno que conoces tiene un primo que una vez programó una aplicación para ella. Seguro que has escuchado rumores de una gente rarísima que programa aplicaciones web en Python en lugar de en Ruby, Django en lugar de Rails y usa un tal Google App Engine en lugar de Heroku

Hoy vamos a hacer una pequeña introducción a Google App Engine y aprenderemos qué es, para que se utiliza y que puede hacer por nosotros. Todo el código fuente y descripciones que hago en este artículo son para el lenguaje de programación Python. Para su contrapartida en Java aconsejo echar un vistazo a la documentación del proyecto.

Un poco de historia

Google App Engine o también conocido más comúnmente como GAE o App Engine nos abre la infraestructura de producción de Google de forma gratuita como plataforma de desarrollo y hospedaje de aplicaciones web.

El servicio fue lanzado el 7 de abril del 2008 como un servicio de cloud pero a diferencia de otros servicios en la nube como Amazon Web Services o Azure Services Platform de Microsoft, el servicio ofrecido por Google es un servicio de Plataforma como Servicio y no de Infraestructura como Servicio.

El uso de la infraestructura de servicio de Google App Engine es completamente gratuita hasta un Gigabyte de almacenamiento y cinco millones de visitas mensuales. Si superamos esos límites entonces tendremos que pagar por más recursos a Google a unos precios bastante asequibles. Además podemos usar un dominio propio para la URL de nuestra aplicación o bien podemos usar un subdominio de appspot.com ofrecido de manera gratuita por Google al estilo de Heroku.

Recomiendo encarecidamente echarle un ojo a la página de cuotas para ver bien como va el tema de los servicios gratuitos y tal porque eso de los cinco millones de visitas es cuanto menos un número muy subjetivo.

Características

GAE soporta de manera oficial los lenguajes de programación Python y Java de manera estable y en modo de beta testing en lenguaje de programación Go creado por ellos mismos. Al soportar Java, es posible además utilizar cualquier lenguaje JVM o lo que es lo mismo, cualquier lenguaje que pueda ejecutarse sobre una máquina virtual de Java, aunque eso si, con serias limitaciones. Entre dichos lenguajes se encuentran:

  • Groovy

  • JRuby

  • Scala

  • PHP

  • Clojure

  • Perl


En el siguiente enlace puedes encontrar un listado completo de implementaciones de diferentes lenguajes sobre JVM.

GAE soporta varios frameworks bajo Python como CherryPy, Pylons, Flask y Django 0.96 y 1.2. Además la misma Google ha desarrrollado un framework propio llamado —viva la originalidad que les caracteriza— webapp para aplicaciones web que van mejorando y actualizando. También existe un framework desarrollado específicamente para GAE y siguiendo —supuestamente— la filosofía de Django llamado GAE framework.

En cuanto a lo que respecta a Java, parece ser que es posible utilizar Grails de forma bastante sencilla y poco traumática utilizando para ello el Plugin para App Engine.

Restricciones

  • Las aplicaciones solo tienen permisos de lectura a los archivos del sistema de archivos. Para almacenar datos y archivos en modo lectura y escritura es necesario utilizar un sistema de archivos virtual sobre el DataStore.

  • Solo se puede ejecutar código a través de consultas HTTP

  • Las aplicaciones Java solo pueden usar el conjunto considerado seguro de clases del JRE estándar. ( Comprueba el Listado de clases)

  • Las aplicaciones no pueden crear nuevos hilos de ejecución

  • Los usuarios de Python pueden subir módulos para su uso en la plataforma pero no aquellos que están completamente desarrollados en C o Pyrex

  • El soporte para SSL solo está disponible par dominios *.appspot.com

  • Un proceso iniciado en el servicio para responder a una consulta no puede durar más de treinta segundos

  • No soporta sesiones persistentes, solo sesiones replicadas a las que además se les aplican ciertos límites.

  • No se pueden abrir sockets, por lo tanto, no se puede usar Twisted

El entorno de desarrollo

El SDK de Google App Engine viene con un entorno de desarrollo que puede ser ejecutado en local en nuestra máquina antes de subir los cambios a la nube y que simula completamente el entorno del App Engine. El SDK puede ser decargado de la página de descargas del proyecto.

Para ejecutar el servidor del entorno de desarrollo tan solo debemos ejecutar el script dev_appserver.py y como parámetro el path al directorio que contiene la aplicación. Por ejemplo en una consola de un sistema tipo UNIX:

genbeta@dev ~ $ python dev_appserver.py mi_app

El script dev_appserver.py admite numerosas opciones, mira la ayuda para verlas.

El entorno de ejecución de Python

App Engine ejecuta nuestras aplicaciones mediante un intérprete de Python 2.5.2 cargado en un entorno “sandboxed“. Toda aplicación programada para correr en la nube de Google debe incorporar un archivo de configuración llamado app.yaml donde se configuran diferentes aspectos de la aplicación y el entorno de ejecución.

El entorno de ejecución admite módulos de terceros programados íntegramente en Python y no deben incluir ninguna extensión C o cualquier otro código susceptible de ser compilado. El entorno incluye la librería estándar de Python a excepción de algunos módulos que han sido desactivados por seguridad como por ejemplo la escritura de disco o los sockets.

Otros módulos de Python han sido reemplazados o personalizados para hacerlos compatibles con App Engine. Un ejemplo de archivo de configuración app.yaml sería como el que sigue:

application: appdelaostia
version: 1
runtime: python
api_version: 1
handlers:
- url: .*
  script: appdelaostia.py

El tema del entorno de ejecución de Python es bastante complejo y se escapa de la intención de esta introducción a Google App Engine, así que te recomiendo que revises la documentación del proyecto si estás interesado/a en saber más sobre él.

El datastore

Cuando usamos Google App Engine, no tenemos acceso a una base de datos relacional tradicional como MySQL, Oracle o Postgres. Nuestros datos se almacenan en el Google Datastore que usa un enfoque jerárquico orientado a objetos al estar basado en otra tecnología de Google, el Google Bigtable que es un sistema distribuido de almacenamiento de datos estructurados.

El enfoque de utilizar Bigtable como almacenamiento a través del Google Datastore consiste en ofrecer una forma eficiente de escalabilidad a nuestras aplicaciones en la nube de Google, las bases de datos NoSQL son conocidas por su predisposición a facilitar la escalabilidad.

La forma de describir un Modelo en el Datastore es muy similar a como lo describiríamos en Django:

from google.appengine.ext import db
class Person(db.Model):
    name = db.StringProperty()
    password = db.StringProperty()

Introducir un nuevo registro en el Datastore no tiene complicación alguna:

newperson = Person(name="Perico", password="62f3b966a2ba0903d5b9da1440eef6c7")
newperson.put()

Consultar al modelo de datos es realmente sencillo:

query = db.Qurery(Person)
query = query.filter('name =', name)
query = query.filter('password = ', password)
results = que.fetch(limit=1)

Al igual que con las bases de datos relacionales, Google Datastore nos provee de una interfaz de consulta a través de una cadena GQL:

query = db.GqlQuery("SELECT * FROM Person WHERE name = :name "
                    "AND password = :pwd ",
                    name="Perico", 
                    password="62f3b966a2ba0903d5b9da1440eef6c7")

  • Hay que recordar que GQL no puede ejecutar JOINS en las consultas SELECT.

El App Engine webapp framework

Como el uso de Django o cualquier otro framework disponible para App Engine queda bastante alejado de la finalidad de este post, vamos a ceñirnos a lo que trae el App Engine sin software de terceras partes para mantener la introducción sencilla y complexity less. Al igual que Django o Rails, webapp es una implementación del patrón de diseño MVC (Model View Controller).

Un ejemplo sencillo de una aplicación web que use el framework WSGI compilant webapp de Google sería la siguiente:

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
class MainHandler(webapp.RequestHandler):
    def get(self):
        self.response.headers["Content-Type"] = "text/plain"
        self.response.out.write("Hello World!")
application = webapp.WSGIApplication([('/', MainHandler)],
                                            debug=True)def main():
    run_wsgi_app(application)
if __name__ == "__main__":
    main()

Si tenemos más de un Handler o Controlador podemos definir más de una dirección URL a través del objeto WSGIApplication:

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
application = webapp.WSGIApplication([('/', MainHandler),
                                      ('/newentry', NewEntry),
                                      ('/editentry', EditEntry),
                                      ('/deleteentry', DeleteEntry),
                                     ],
                                     debug=True)
def main():
  run_wsgi_app(application)
if __name__ == '__main__':
  main()

El constructor del objeto WSGIApplication hace uso de una lista de tuplas para definir las rutas a sus respectivos controladores. Al igual que ocurre en Django, la ruta URL es una expresión regular. También puede utilizarse el archivo app.yaml para asignar rutas de URL.

Servicios

En entorno de ejecución de Python de Google App Engine también provee de una API para varios servicios de App Engine. Vamos a verlos de pasada.

Memcache

App Engine incluye un servicio de memoria caché distribuida con la utilidad de almacenar datos en ella en lugar del Datastore. Lo que se almacene en la memoria cache se conserva el mayor tiempo posible. Obviamente, los datos pueden ser expulsados de la memoria cuando se introducen nuevos y la memoria esta baja. El tamaño máximo de un valor almacenado en la memoria cache del App Engine es de un megabyte. El uso de la memoria cache es muy sencillo:

from google.appengine.api import memcache
# Añadir un valor si no existe en la cache con una caducidad de una hora.
memcache.add(key="talla_usuario_11987", value="XXL", time=3600)

Extracción de URL

El servicio de extracción de URL sirve para realizar solicitudes a otros hosts mediante HTTP o HTTPS y su uso es bastante simple:

from google.appengine.api import urlfetch
url = "https://www.genbetadev.com/"
result = urlfetch.fetch(url)
if result.status_code == 200:
  doSomethingWithResult(result.content)

Correo


Las aplicaciones de App Engine pueden enviar mensajes de correo electrónico a través de la API del servicio de correo utilizando el objeto mail:

from google.appengine.api import mail
class ConfirmUserSignup(webapp.RequestHandler):
  def post(self):
    user_address = self.request.get("email_address")
    if not mail.is_email_valid(user_address):
      # prompt user to enter a valid address
    else:
      confirmation_url = createNewUserConfirmation(self.request)
      sender_address = "support@example.com"
      subject = "Confirm your registration"
      body = """
Thank you for creating an account!  Please confirm your email address by
clicking on the link below:
%s
""" % confirmation_url
      mail.send_mail(sender_address, user_address, subject, body)

El mensaje solo puede pesar un megabyte incluidos archivos adjuntos.

Transformación de Imágenes

También se proporciona la calidad de manipular imágenes por medio de un servicio de imágenes dedicado. El servicio permite redimensionar, rotar, voltear y recortar imágenes (crop), hacer composiciones y convertir imágenes a varios formatos.

Para utilizar el servicio en nuestro entorno local, es necesario que instalemos la librería de imágenes de Python PIL, conocida también como “python-imagin”, recomiendo la lectura de la wiki del proyecto para entender su uso:

from google.appengine.api import images
class PaginaDelCarajo(webapp.RequestHandler):
...
avatar = images.resize(self.request.get("img"), 32, 32)
...

Cuentas de Google

Las aplicaciones App Engine pueden autenticar usuarios a través de Cuentas de Google. Si un usuario accede con su cuenta de Google, la aplicación puede por ejemplo acceder a la dirección de correo electrónico del usuario y a varios datos del perfil del mismo.

Recomiendo la lectura de la documentación de la wiki sobre el asunto.

Más allá de la API de App Engine

Podemos utilizar el módulo de Python de Google Data para utilizar la API de datos de Google y solicitar permiso al usuario para acceder a sus datos y acceder así a infinidad de servicios ofrecidos por Google como por ejemplo YouTUBE.

Es imprescindible la lectura del artículo sobre recuperación de feeds de datos de Google autenticados a través de App Engine en la página del proyecto.

Conclusión

La nube tiene sus ventajas e inconvenientes, el sistema de Plataforma como Servicio de Google App Engine tiene un nivel de abstracción tan alto que al utilizarlo solo tenemos que prestar atención al desarrollo de nuestra aplicación y no a infraestructuras, servicios y tecnologías como si ocurre por ejemplo con la nube de Amazon, donde somos nosotros los que debemos iniciar y parar los servicios que vamos a utilizar.

Los precios del App Engine son bastante asequibles y para la mayoría de las aplicaciones que podemos construir los mortales, es complicado que rebasaremos las cuotas gratuitas. Como todo en esta vida, puedes amar el servicio de App Engine u odiarlo con todas tus fuerzas, el caso es que está ahí para que lo uses o no y hoy en Genbeta Dev, hemos realizado una introducción al mismo.


Más Información | Página principal del proyecto

Portada de Genbeta