Google App Engine

XML, JSON… Protocol Buffers

El intercambio de información en los sistema distribuidos o en cualquier tipo de servicio, es un tema clave, para lo cual, a lo largo de los años han surgido un montón de soluciones y tecnologías. Hasta ahora la formula mas utilizada era el formato XML, en muchos caso envueltos de una capa extra de gestión, como son el caso de SOAP o WCF impulsados por Microsoft. En general XML sigue siendo claro dominador a la hora de proveer información estructurada. Los feeds de nuestra Web, Sitemaps o muchos proyectos de OpenData proporcionan información en este formato.

A pesar de ello, XML para muchos es un formato engorroso, su interpretación o extracción de la información, a pesar de que existen muchas librerías que lo facilitan, suele traer de cabeza a muchos desarrolladores y cada vez, tiene mas presencia la tecnología JSON a la hora de acceder a servidores de datos, APIs, etc.. la facilidad para generar y recuperar la información que ofrece JSON esta haciendo que sea estándar de facto en prácticamente todos los servicios que permiten interactuar con servicios terceros. Empresas como Facebook o WOT, apuestan por JSON para el acceso a la información, sobre todo cuando esta se genera de forma dinámica. Aun así en la mayoría de los casos sigue estando opcional el acceso s los datos en XML.

En este articulo trato de presentar Protocol Buffers, una solución que pretende ser mas optima, en lo que respecta a trafico de datos, y mas opaca, si lo que interesa es que la información no viaje de forma totalmente visible. Personalmente, creo que lo mas interesante de este sistema es que reduce considerablemente el volumen de trafico generado en cada petición de información, lo cual es muy interesante si lo que queremos es desarrollar un servicio explotado por aplicaciones móviles, donde podemos conseguir aplicaciones mas fluidas, si conseguimos que el tiempo de conexión sea el menor posible.

En mi caso, Protocol Buffers me parece una solución interesante, ya que suelo usar Google App Engine, como web service generador de datos, y para terminales móviles suelo trabajar con Android, para el cual existen librerias. Además hay que tener en cuenta que muchas de las aplicaciones de serie en Android como el Market usan Protocol Buffers internamente (a pesar de que oficialmente la SDK de Android no ofrece acceso a dichas librerías).

En próximos post explicare como manejar Protocol Buffers en python.

Curso de Iniciación de Google App Engine

Este sábado dentro de las iniciativas llevadas a cabo por GTUG (Google Technology User Group) Bilbao, se va a llevar a impartir un curso de iniciación a la plataforma Google App Engine. El curso será este Sábado 19 de Febrero en la sede de Creativity Zentrum Bilbao a las diez de la mañana.

El curso básicamente va a ser una introducción a la plataforma y se realizará la guía “Getting Started” de forma interactiva, mientras se resuelven dudas realizando todos los ejemplos y alguna prueba mas que pueda ser de interés. Se supondrá que los usuarios tienen cierto conocimiento en Python, aunque al tratarse de un lenguaje muy sencillo con tener conocimientos en lenguajes orientados a objetos seria suficiente.

Así que si no tenéis planes para este sábado a la mañana y siempre habéis tenido ganas de hincarle el diente a este servicio de Google no lo dudéis y confirmar vuestra asistencia en el siguiente enlace: http://doodle.com/wm7a4ucbaf4xhmxi

Asociacion Creativity Zemtrum Bizcaya


Ikusi mapa handiagoa

Posibilidad de Cross-Site Scripting mediante Jquery.getJson() para OpenBizkaibus API

He actualizado la API de OpenBizkaibus para que sea posible realizar peticiones getJson() desde otras paginas. A continuación se muestra un ejemplo de cómo realizar esta petición. En el ejemplo se muestra como completar un selectbox con el listado de municipios de la consulta Consultar_FamiliasCentros y una vez seleccionado un municipio se completará otro selectbox con las lineas mediante LineasMunicipio.

<br />
&lt;!DOCTYPE html&gt;<br />
&lt;html&gt;<br />
&lt;head&gt;<br />
  &lt;style&gt;img{ height: 100px; float: left; }&lt;/style&gt;<br />
  &lt;script src=&quot;http://code.jquery.com/jquery-1.4.4.js&quot;&gt;&lt;/script&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;</p>
<p>&lt;p&gt;<br />
	&lt;select name=&quot;town&quot; id=&quot;townsel&quot;&gt;<br />
	&lt;/select&gt;<br />
&lt;/p&gt;<br />
&lt;p&gt;<br />
	&lt;select name=&quot;lines&quot; id=&quot;linesselsel&quot;&gt;<br />
	&lt;/select&gt;<br />
&lt;/p&gt;<br />
&lt;script&gt;</p>
<p>$(document).ready(function(){ </p>
<p>	//Get Town list<br />
	$.getJSON(&quot;http://openbizkaibus.appspot.com/api/Consultar_FamiliasCentros?jsoncallback=?&quot;,<br />
  {},<br />
  function(data) {<br />
    $.each(data, function(i,object){<br />
    	$.each(object.Registros, function(i,registro){<br />
    		$(&#8216;#townsel&#8217;).append(new Option(registro.DescripcionElemento, registro.CodigoElemento, true, true));<br />
    	});<br />
    });<br />
  });</p>
<p>  //<br />
  $(&quot;#townsel&quot;).change(function()<br />
    {<br />
        var CodigoElemento<br />
        var DescripcionElemento</p>
<p>        CodigoElemento = $(&quot;#townsel&quot;).val();<br />
        DescripcionElemento = $(&quot;#townsel option:selected&quot;).text();</p>
<p>        if(CodigoElemento.length &lt; 2){<br />
        	CodigoElemento = &quot;00&quot;+CodigoElemento;<br />
        }<br />
        if(CodigoElemento.length &lt; 3){<br />
        	CodigoElemento = &quot;0&quot;+CodigoElemento;<br />
        }</p>
<p>        $.getJSON(&quot;http://openbizkaibus.appspot.com/api/LineasMunicipio?jsoncallback=?&quot;,<br />
	{<br />
		codmunicipio: CodigoElemento,<br />
		descmunicipio: DescripcionElemento<br />
	},<br />
	function(data) {<br />
	  	$(&#8216;#linesselsel&#8217;).find(&#8216;option&#8217;).remove().end();<br />
	  	$.each(data, function(i,object){<br />
	  	 	$(&#8216;#linesselsel&#8217;).append(new Option(object.DenominacionLinea, object.CodigoLinea, true, true));<br />
	 	});<br />
	});<br />
    });<br />
});<br />
&lt;/script&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;<br />

Para ver el ejemplo funcionando pulsar aquí.

Publicada la versión 0.01 de la API de OpenBizkaibus

Cuando hice mis primeras aproximaciones de la aplicación para Bizkaibus, las opciones que se barajaba eran:

  • Hardcodear la lista de líneas, paradas, municipios…
  • Crear un Cliente SOAP para Android y comunicarme directamente con la API de Bizkaibus
  • Crear un servicio WEB sencillo que me hiciera de pasarela con la API de Bizkaibus

La segunda opción la descarte desde el principio ya que creía que iba a ser un vector de riesgo importante en la aplicación ya que podía dar a lugar a gran cantidad de problemas: excepciones incontroladas, consumo de recursos,…

La primera opción fue con la que empecé a trabajar (e incluso llegue a tener un prototipo) ya que me permitía hacer algunas consultas sin conexión a Internet. El problema era que en las primeras pruebas, trabajando solo con una parte de la información, el prototipo funcionaba correctamente, pero llego un punto en que el volumen de datos era tal que era inmanejable. Además, el nos últimos meses se han añadido paradas nuevas por lo que el tener que sacar nuevas actualizaciones cada vez que se hacia algún cambio en el servicio de Bizkaibus no lo veía muy manejable. Además seguía existiendo una parte que tenia que seguir siendo online, como es la parte en la que se consultan el tiempo que queda para que llegue un autobús a una parada.

Por tanto, al final opte por la tercera opción, que era, crear un servicio WEB que hiciera la función de interfaz, sencilla y comoda de manejar, desde un terminal Android. Por tanto la solución era desarrollar una seria de servicios accesibles a través de una petición HTTP GET y que diera como resultado la información en formato JSON. Esto simplificaba en gran medida toda la parte de obtención y tratamiento de datos, lo cual evitaba los problemas que me llevaron a descartar la opción de hacer peticiones SOAP desde el propio terminal.

Aunque todavía la aplicación para Android no este lista, he creído interesante publicar la interfaz que usara la aplicación para comunicarse con la API de Bizkaibus. La intención de esta publicación es la de que independientemente de la aplicación de Android que estoy desarrollando, este interfaz pueda ser utilizado para otros propósitos, en diferentes plataformas y lenguajes de programación.

Espero que este nuevo servicio os sea de gran ayuda a muchos y también espero que la diputación de Bizkaia y mas concretamente Lantik no tome ninguna medida para impedir el acceso desde esta interfaz.

Más información sobre el servicio OpenBizkaibus en:


http://openbizkaibus.appspot.com/api/

Usar/Crear Filtros para las plantillas de django/Google App Engine

Una de los temas mas interesante en Google App Engine es la posibilidad de usar plantillas. En la página de GAE existen ejemplos sencillos de cómo utilizar plantillas.El problema empieza cuando dentro de esas plantillas quieres hacer tratamiento de los datos para mostrar los datos correctamente. En esta articulo intentaremos explicar como usar esos filtros y como crear propios.

Como habéis podido ver en el ejemplo de la pagina de GAE, la forma de mostrar un valor en la plantilla es usando la sintaxis {{ variable }}. En la mayoría de los casos dichas variables serán de tipo string o integer por lo que su visualización no tendrá mayor problema. Pero por ejemplo en el caso de variables tipo datetime u otro tipo de objeto propio, el sistema de plantillas no es capaz de mostrar el contenido de dichas variables, ya que solo es capaz de mostrar valores tipo string o integer.

Para los tipos de datos mas comunes existen ya filtros por defecto como es el caso de los valores datetime. La forma de aplicar un filtro es la siguiente:

<br />
{{variable|filtro}}<br />

Y en algunos casos:

<br />
{{variable|filtro:argumento}}<br />

En el caso de los valores datetime que hemos comentado antes, para mostrar un valor de fecha deberemos usar el filtro date de la siguiente manera:

<br />
{{mydatevar|date:"j"}}<br />

Esto seria equivalente a ejecutar una función date(mydatevar,”j”) y lo que estoy haciendo es mostrar el día del mes (código %j) similar a como se hace en otros lenguajes de programación.

Aquí podéis encontrar un listado con los principales filtros predeterminados en django

El problema es cuando estas funciones no son suficientes para hacer lo que nosotros queremos, o queremos tratar tipos de objetos poco comunes o propios.

Por ejemplo imaginemos que queremos tenemos un libro de visitas donde los usuarios puede escribir entradas, e indican su dirección de correo. Pero no queremos que esa dirección de correo sea visible para que no pueda ser rastreada por spammers, por lo que optamos por mostrar solo los 5 primeros caracteres de el nombre de usuario de la cuenta de correo mas tres puntos suspensivos (algo parecido a lo que se hace en las listas de distribución). Es decir para estoesunaprueba@gmail.com nos generara una dirección del tipo estoe…@gmail.com.

Por tanto nuestra función en python seria algo así como:

<br />
def securemail (mail):<br />
	return mail.split(‘@’)[0][:5]+”…@”+ mail.split(‘@’)[1]<br />

Es decir, dividimos la dirección en usuario y dominio con la función split y el carácter @, y generamos una nueva dirección con los primeros 5 caracteres de el usuario mas tres puntos suspensivos la arroba y el dominio.

Para poder usar esta función en nuestras plantillas haremos lo siguiente. Crearemos un script customfilters.py donde guardaremos todas nuestros filtros. Dicho script tendrá la siguiente forma

<br />
from google.appengine.ext import webapp<br />
from datetime import datetime</p>
<p>register = webapp.template.create_template_register()</p>
<p>def securemail (mail):<br />
	return mail.split(‘@’)[0][:5]+”…@”+ mail.split(‘@’)[1]</p>
<p>register.filter(securemail)<br />

Para importar los filtros en nuestra aplicación añadiremos la siguiente sentencia justo después de los imports.

<br />
webapp.template.register_template_library('customfilters')<br />

De esta forma podremos usar nuestro filtro de la siguiente manera:

<br />
{{mail|securemail}}<br />

Imaginemos que damos la opción al usuario que la función securemail muestre su cuenta de dos modos, uno, el por defecto que es el funcionamiento explicado anteriormente, y otro, que hace que solo se muestre el usuario sin el dominio. Por tanto deberemos definir un parámetro en la función para poder elegir el tipo de ofuscación. La función en este caso nos quedaría así:

<br />
def securemail (mail,default=true):<br />
	if default:<br />
		return mail.split(‘@’)[0][:5]+”…@”+ mail.split(‘@’)[1]<br />
	else:<br />
		return mail.split(‘@’)[0]<br />

Por tanto si la variable mail tomara el valor estoesunaprueba@gmail.com este seria el resultado para las diferentes expresiones:

<br />
{{mail|securemail}} #estoe…@gmail.com<br />
{{mail|securemail:true}} #estoe…@gmail.com<br />
{{mail|securemail:false}} #estoesunaprueba<br />

De esta forma podemos controlar y procesar la información a mostrar en nuestra plantilla cuando esta se trata de un objeto no string (o integer).

 Scroll to top