Google ha puesto a disposición de los usuarios de Google App Engine un script para ejecutar código de forma remota. Este script se denomina remote_api. Una de las principales utilidades es importar o exportar datos del datastore de nuestras aplicaciones.
Lo primero que se debe hacer es modificar el fichero app.yaml añadiendo el script remote_api.py en la sección de handlers.
handlers: - url: /remote_api script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py login: admin
En este caso el script está configurado para ser accedido por la url /remote_api y se require autorización por parte de una cuenta de administrador.
Basándome en un script del blog Bill Katz he creado una plantilla para para crear scripts que usen el remote_api.
#!/usr/bin/env python
#
import os
import sys
from google.appengine.ext import db
from google.appengine.ext.remote_api import remote_api_stub
import getpass
appengine_dirs = ['/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/']
sys.path.extend(appengine_dirs)
my_root_dir = os.path.abspath(os.path.dirname('/Users/gimenete/projects/myproject/'))
sys.path.insert(0, my_root_dir)
APP_NAME = 'nombre_aplicacion'
os.environ['AUTH_DOMAIN'] = 'gmail.com'
def auth_func():
return (raw_input('Username:'), getpass.getpass('Password:'))
# Use local dev server by passing in as parameter:
# servername='localhost:8080'
# Otherwise, remote_api assumes you are targeting APP_NAME.appspot.com
remote_api_stub.ConfigureRemoteDatastore(APP_NAME, '/remote_api', auth_func)La variable appengine_dirs deberá ser modificada según el directorio de instalación del Google App Engine SDK. Y la variable myrootdir debería apuntar al directorio donde se encuentr el código de nuestro proyecto.
El script nos pedirá un nombre de usuario y contraseña para auntenticarse. Se puede modificar la función auth_func() para que esto no sea así. Se pueden meter hardcoded el usuario y contraseña, leerlos de un fichero, etc.
Con el código anterior el script ya ha sido configurado para conectarse al remote_api. A partir de ahí ya se pueden realizar consultas o modificaciones del datastore. El datastore ya se puede utilizar como si el código estuviera desplegado en los servidores de Google App Engine.
Una de las principales consultas que probablemente haremos es iterar TODOS los objetos de una clase. Esto tiene dos problemas:
No obstante estos problemas se pueden esquivar. La solución consiste en obtener N objetos y luego hacer una consulta sobre los siguientes objetos que tengan una key() mayor que la del último elemento leído. Hay que tener en cuenta que esto no nos asegura que estemos obteniendo los objetos en el orden cronológico en el que se insertaron. Esta técnica está explicada en un artículo al respecto.
A continuación muestro una forma genérica de iterar todos los elementos de un tipo:
import model
def iterate(kind, func, max=100):
entities = kind.all().fetch(max)
while entities:
for entity in entities:
func.__call__(entity)
entities = kind.all().filter('__key__ >', entity.key()).fetch(max)
def process_item(item):
print author_key
print item.title
print 'Items'
iterate(model.Item, process_item)Otra importante cuestión al trabajar con el datastore, tanto en remoto como en los controladores de nuestra web, es la navegación por las relaciones de los objetos. Si por ejemplo queremos acceder a la propiedad "author" de un objeto "model.Item", podríamos hacer lo siguiente.
author = item.author
Sin embargo si la propiedad "author" es una relación (una propiedad de tipo ReferenceProperty), acceder a ella provoca una nueva consulta al datastore. Si iteramos N items y en cada iteración accedemos a la propiedad "author", estaremos haciendo N+1 peticiones. Esto ralentiza de forma muy sensible el rendimiento de nuestro script. Este problema también ocurre aunque sólo accedamos a la key() de la referencia.
key = item.author.key()
Existe otro método para evitar tener que cargar todo el objeto solamente para obtener su key()
key = model.Item.author.get_value_for_datastore(item)
Obteniendo las keys de esta forma y no de la anterior obtendremos una mejora de rendimiento notable. Recientemente en debugmodeon hicimos un script para migrar la base de datos. El script inicial tardaba aproximadamente dos horas en descargar todo el datastore a una base de datos MySQL. Al refactorizar el script utilizando getvaluefor_datastore el script pasó a tardar solamente 8 minutos.
Para terminar simplemente comentar que el remote_api no sólo permite acceder al datastore, aunque acceder a él sea quizá una de las mayores utilidades. Google explica por ejemplo también cómo crear una consola interactiva.
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.
tonny escribió
hace 1 años
gimenete escribió
hace 1 años
Pues no lo sé, porque yo sólo he usado la remote_api de forma programática. No he usado la opción "upload_data" nunca. He visto la documentación y aparentemente lo que intentas es correcto, así que más no puedo ayudarte :(
tonny escribió
hace 1 años
Gracias con todo seguiré intentando...
Miuler escribió
hace 1 meses
Hola Gimenete, me parece fantástico la manera en que han reducido los tiempos, de tardar 2 horas a solo 8min. eso si que es optimizar, bueno yo recién le estoy entrando con fuerza a esto del appengine de google, y me parece buena opción, aunque aún tengo mis dudas pero espero que poco a poco le tome más confianza a este sistema. Realmente gracias por este articulo, realmente fue muy interesante.
gimenete escribió
hace 1 meses
Un placer, Miuler!
© Copyright 2008-2009 debug_mode=ON | Aviso legal | Contacto | FAQ | ¿Quiénes somos? |
#1
Hola Gimenete ando dias con esto del remote api y no logro acceder
segui el tutorial de google http://code.google.com/intl/es-ES/appengine/docs/python/tools/uploadingdata.html
pero al hacer
me sale el este error
si hago esto, tambien hay error
podrías talvez indicar como subir archivos csv al data store
Muchas gracias y felicitaciones por tus articulos.
Editado 1 veces. La última vez hace hace 1 años.