martes, 29 de junio de 2010

usar blobstore api en app engine

El modelo debe definirse así:


from google.appengine.ext import db
from google.appengine.ext import blobstore

class MiModelo(db.Model):
....#algunos campos
archivo=blobstore.BlobReferenceProperty() #aqui se registrara la llave del archivo
....#otros campos


En la clase que maneja las peticiones se liga la url estática definida en con el resto de las peticiones con la URL que genera blobstore para la sesion esta se registra en una variable que se pondrá dentro del formulario html de forma dinámica.


from google.appengine.ext import webapp, db
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers

class MiClase(webapp.RequestHandler):
pathtemplate = os.path.join(path, 'el_template.html')
template_values ={ #en esta variable se liga la URL con la direccion de la sesion
"upload_url": blobstore.create_upload_url('/upload'),
}
self.response.out.write(template.render(pathtemplate, template_values))


Este sería el código del formulario en el template, ver que en el campo action se asigna el valor de la variable upload_url



La clase que maneja el blob sería la siguiente, donde el blob es almacenado al momento de entrar a la clase y solo se registra la llave para poder instanciarlo despues.


class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
upload_files = self.get_uploads('file')
blob_info = upload_files[0]
miclase=MiClase()
miclase.archivo=blob_info.key()
miclase.put()
self.redirect('../OtraPagina' )

martes, 16 de febrero de 2010

Generar archivo CSV para descargar en APPENGINE

Para generar un archivo CSV que funcione como una liga que permita descargar el archivo es necesario seguir los siguientes pasos:

1.- Crear la url



En el archivo donde se creen las ligas entre las clases y las url (lazy loading)

application = webapp.WSGIApplication([ 
("/csv",Csv),
], debug=False)

def main():
run_wsgi_app(application)



2.- Generar el CSV



En la clase Csv se genera el string y el handler para manejar las peticiones get del servidor.

import wsgiref.handlers 
import StringIO
from google.appengine.ext import webapp

class Csv(webapp.RequestHandler):
def get(self):
out=StringIO.StringIO()
cabeceras="..." #defino las cabeceras de los campos del csv
out.write(cabeceras)
MisDatos="..."#Obtengo los datos de alguna fuente, muy probablemente del DataStore
for renglon in MisDatos:
csv=""
csv=csv+"..."+"|"# obtengo los datos necesarios agregandolos a la variable csv
#continuo asi....
csv=csv+"\n" #eol
out.write(csv)
#agrego los header para que se comporte como archivo
self.response.headers["Content-Type"] = "application/vnd.ms-excel"
self.response.out.write(out.getvalue())


Agrego un link en el template



<a href="/csv">csv</a>


y listo....

viernes, 22 de enero de 2010

Conceptos básicos de bazaar

Rama (Branch) - Línea de desarrollo de un proyecto
Arbol de trabajo (Working tree) - Directorio de versiones controlado (por bazaar obviamente)
Repositorio (Repository) - Almacén para las revisiones de bazaar
Revisión - Version del código fuente registrada (commited) en el repositorio
Etiqueta (Tag) - Nombre de la revisión
ramas relacionadas (Related branches) - Ramas con un ancestro en común
Mezcla (Merge) - La operación de aplicar a una rama todos los cambios en el código fuente que se hicieron en otra rama

Fuente: Bazaar Quick Reference

Deshaciendo cambios en bazaar

Para revertir los cambios de una revisión (commit) a otra es necesario seguir dos pasos (En este orden)

1.- Deshacer el commit
2.- Revertir los cambios

En bazaar explorer son las siguientes opciones:

Tutorial básico de bazaar (GUI)

Bazaar es un SCM , o mejor dicho, el SCM de canonical, que tiene un conjunto de herramientas GUI (para windows) que lo hacen sumamente atractivo y fácil de usar para desarrolladores independientes.

Instalar bazaar



Hay que descargar el instalador standalone, y hacer el clásico siguiente, siguiente, siguiente. Solo hay que tomar en cuenta instalar TortoiseBzr.

Una vez instalado es posible que falle Bazar Explorer (posiblemente por causa de dependencias lo que hace que se muestre una pantalla de msdos negra y se cierre sin previo aviso), por lo que es necesario instalar manualmente esta herramienta; nuevamente siguiente, siguiente, siguiente.

Lo que sigue es lanzar explorer y registrar los datos del programador (esto no es obligatorio)


Crear Proyecto



En la tercera cejilla ("Iniciar nuevo proyecto") permite seleccionar la carpeta donde estará la carpeta principal ("trunk") del proyecto


Una vez seleccionada la carpeta se tiene 5 opciones de proyecto:
- Feature branchs: Crea un repositorio compartido en el directorio seleccionado y crea la rama principal (trunk)

- Shared tree: Crea un repositorio compartido, crea la rama principal (trunk) y un arbol de trabajo separado.

- Plain branchs: Crea una rama plana en el directorio seleccionado, si es parte (o esta adentro) de un repositorio compartido (Shared repository) las revisiones serán almacenadas allí, de lo contrario (no esta dentro de un repositorio compartido) las revisiones se almacenan en la rama

- Shared repository: Crea un repositorio compartido en el directorio seleccionado. Las ramas creadas dentro de este repositorio se usaran para almacenar las revisiones.

- Shared repo with treeless branch: Crea un repositorio compartido en el directorio seleccionado, configura al repositorio y sus ramas creandas sin un árbol de trabajo. Los repositorios en los servidores suelen estar configurados de esta manera.

¿Cual elegir?



Segú la documentación de bazaar "Para la mayoría de los proyectos pequeños y medianos, se recomienda el modelo de Feature branchs. Para los proyectos grandes (como GIT) se prefiere a menudo el módelo Shared tree.

Administrando el proyecto



Hay que copiar el código (si es que existe) dentro de la carpeta trunk.
Bazaar explorer abrirá un nuevo tab con el nombre del directorio seleccionado,
se debe cerra esta y entrar a la cuarta cejilla ("Abrir una ubicación existente") seleccionando la carpeta trunk.



Se mostraran todos los archivos "sin versionar" y hay que añadirlos a la rama principal.




Hay que hacer la primera revision (commit) se puede hacer de forma automática seleccionando la flecha verde que esta en la parte inferior de la pantalla.



Listo, se tiene el proyecto listo para iniciar a modificar el código de forma ordenada.

miércoles, 26 de agosto de 2009

Pruebas unitarias con App Engine


A pesar que voy empezado con las pruebas unitarias de App Engine, encontré una utileria que permite ejecutarlas y obtener resultados visuales inmediatos, se llama gaeunit y utilizarla es muy facil.


  • Se necesita copiar el archivo gaeunit.py a la carpeta raíz del proyecto
  • Se crea una carpeta "test"
  • Se crean las pruebas en tantas clases y archivos sean necesarios (siempre en la carpeta test) sin olvidar que los métodos deben iniciar con la palabra test
  • Para ejecutarlos entrar a http://localhost:puerto/test y listo

jueves, 6 de agosto de 2009

Limitantes App Engine

Despues de trabajar un cierto tiempo en un proyecto mas completo encontre las siguientes limitantes en App Engine:

  • No existe LIKE para las consultas
  • No existe OR para las consultas
  • No es posible concatenar operadores > y/o <>
  • Las consultas son Case Sensitive