Google App Engine with Python: webapp2 in action

Posted by in Frameworks, Python

After some months with several topics on #manejandodatos, let’s come back to talk about Google App Engine using the example shown here: http://www.manejandodatos.es/2014/12/google-app-engine-python. In previous entrances, I wrote about how to install the correspondant SDK, and also, how to write a small peace of code in order to try the webapp2 framework and develop web apps with Python. Today it is turn to move this framework to use under the Google App Engine platform.

What is webapp2

Well … a framework that has methods and properties that allow the developer to focus in the interface of the app, becuase the rest of “framework stuff”. Webapp2 is an update of webapp, another framework (the base), but improved. The good part is that webapp2 has support for URI routing, session management and localization.

Form validation

Although the example shown, where a form can be fill with some name in order to show a Hello message, now let’s go to improve the code and add some validation. So instead of showing No has puesto nombre (No name was found), let put a restriction that the name need to have at least two characters. The redirect is to the root path self.redirect(“/”).

The problem due to redirections is that you can loose data with complex forms, so the best way of not loosing anything (and also to improve the user experience) is to “store” this info. Let’s use sessions!

Sessions in GAE

Let’s add sessions to or code, and for that, We need to use aditional code found in gae-sessions, aGAE library that is prepared for sessions. As you can see in its documentation, it is a light library, easy to use, and the only limitatios is the 1 Mega size per sessions (I think it’s enough for a web app).

You can download the filh on GitHub and now, let’s copy the directory gaesessions to our app:

Sesiones en GAE

Sessions en GAE

In order to use the library, it is neccesary to create a configuration file, called appengine_config.py, with this code:


from gaesessions import SessionsMiddleware

from gaesessions import
def webapp_add_wagi_middleware(app):
app = SessionsMiddleware(app, cookie_key="qwertywewaawasdpdfsdfkllddlkeerrer")
return app

The key is the cookie cookie_key that you want, but it is compulsory to have at least 32 characters!.

Let’s go back to the main code. We need to import get_current_session de gaesession (this is what is does the tark for us).

Playing with values

First, let’s store some info in the session variable by calling the post method. Now, We can add the restriction of having at least 5 characters, and if not, a message will be shown:

    def post(self):
        session = get_current_session()
        count = session[self.contador]
        nombre = self.request.get("nombre")
        # Guardo la info en Sesion
        session[self.nombre] = nombre
        session[self.mens] = ''
        if len(nombre) < 5:
            session[self.mens] = 'Nombre demasiado corto!'
            self.redirect(root)
        mensaje = ('Hola ... %s, Has entrado %d veces' % (nombre, count))
        self.response.out.write(mensaje)
        session[self.contador] = 0

For retrieving this info, you need to use the get method:

    def get(self):
        session = get_current_session()
        nombre = session.get(self.nombre, '')
        count = session.get(self.contador) + 1
        session[self.contador] = count
        self.response.write(html % (count, nombre))

And it works!

Probando GAE

GAE and Python

There is a small detais that the developer should take into account when working with strings, because maybe the user can insert the necesary code for closing the HTML, introducing extrange behaviour. Let’s try to insert m”> a, and see what happend. Something is not working properly, as you can see in the next image when reloading the page:

Probando GAE con Python

GAE with Python

The problem is that if something with no good intentions can inject Javascript code, as an example, and so to retrieve info of our app. So let’s add cgi.escape when retrieving data. The final code is here:


#!/usr/bin/env python
#   Manejandodatos.es
#   Probando Google App Engine con Python
#
import webapp2
from gaesessions import get_current_session
import cgi

root = '/'
html = """
<html lang="es">
<head><title>Probando Google App Engine for Python</title></head>
<body>
<h1>Probando Google App Engine for Python</h1>
Cargado %d veces %s
<form method="post">
<label for="nombre">Nombre</label>
<input name="nombre" id="nombre" type="text" value="%s" />
<input type="submit" value="Enviar">
</form>
</body>
</html>
"""

class MainHandler(webapp2.RequestHandler):
contador = 'count'
nombre = 'nombre'
mens = 'mensaje'
def post(self):
session = get_current_session()
count = session[self.contador]
nombre = self.request.get("nombre")
# Guardo la info en Sesion
session[self.nombre] = nombre
if len(nombre) < 5:
session[self.mens] = 'Nombre demasiado corto!'
self.redirect(root)
mensaje = ('Hola ... %s, Has entrado %d veces' % (nombre, count))
self.response.out.write(mensaje)
session[self.contador] = 0

def get(self):
session = get_current_session()
nombre = cgi.escape(session.get(self.nombre, ''), quote=True)
count = session.get(self.contador, 0) + 1 # El contador es INTERNO y no necesita control de ESCAPE
session[self.contador] = count
mensaje = cgi.escape(session.get(self.mens, ''), quote=True)
self.response.write(html % (count, mensaje, nombre))

app = webapp2.WSGIApplication([(root, MainHandler)], debug=True)

Let refresh the browser to see that the problem is not arising any more!:

Probando GAE

Test with GAE for Python

I hope you like it and join to use Google App Engine!!