Pyramid en Google App Engine
Crearem un projecte Python: Pyramid framework per instal·lar-ho després al Google App Engine (GAE).
Contingut
Instal·lació ràpida
Partim de la màquina virtual FunkyDesktop (Ubuntu 12.04 Desktop actualtizada però sense instal·lar cap paquet addicional).
- Instal·la els paquets de python necessaris:
$ apt-get install python-pip pyhton-dev g++ python-virtualenv
- Actualitzem la darrera versió del sistema de distribute. OJU: és l'únic cop que farem un sudo pip.
$ sudo pip install --upgrade distribute
- Crea un virtualenv:
$ virtualenv --no-site-packages --distribute env
- Entrem permanentment en el nou virtualenv:
$ source ~/env/bin/activate
- Per no tenir embolics de versions, utilitzarem l'arxiu requirements.txt on us poso les versions del paquets que m'han funcionat. Crea l'arxiu requirements.txt com s'indica a la següent subsecció.
- Carrega les versions de treball en el nou env:
(env)$ pip install -r requirements.txt
- O bé (sense fer el source d'abans):
$ ~/env/bin/pip install -r requirements.txt
- Genera la plantilla del nou projecte (aneu a un altre directori de treball primer):
(env)$ cd
(env)$ pcreate -t appengine_starter projecte1
- Arregleu el problema del setuptools afegint a versions.cfg:
setuptools = 1.1.5
- Opcionalment podeu utiltizar els servidors de descàrrega local seguint les instruccions de PyPI mirror, modificant l'arxiu buildout.cfg.
- Sortiu del virtualenv (només en calia per crear la plantilla de projecte):
(env)$ deactivate
- Instal·leu el nou projecte (cal haver sortit del virtualenv):
$ python bootstrap.py
$ bin/buildout
- Arrenquem el servidor:
$ bin/devappserver parts/projecte1 --use_mtime_file_watcher
- Visiteu el nou servei:
http://localhost:8080
requirements.txt
Aquest arxiu conté les versions dels paquets de Python que tens en un moment donat al teu sistema o al virtualenv. No és recomanable fer-ho al sistema, però.
Exemple de Nov'2013. Si no està actualtizat potser convé més que realitzis els tutorials genèrics de més avall.
Chameleon==2.13
Mako==0.9.0
MarkupSafe==0.18
PasteDeploy==1.5.0
WebOb==1.2.3
argparse==1.2.1
distribute==0.7.3
pyramid==1.4.5
pyramid-appengine==0.8.2-a2
repoze.lru==0.6
translationstring==1.1
venusian==1.0a8
wsgiref==0.1.2
zope.deprecation==4.0.2
zope.interface==4.0.5
Per carregar-lo (normalment al virtualenv):
(env)$ pip install -r requirements.txt
Per generar-lo:
(env)$ pip freeze > requirements.txt
Instal·lant la plantilla de projecte
si has fet la instal·lació ràpida, no cal que facis aquest apartat
Treballarem amb el Buildout i el scaffold de Pyramid per GAE.
OJU: no treballeu com a root. Aquest entorn (virtualenv) està pensat per no interferir en el sistema ni barrejar llibreries.
- Tutorial Pyramid amb Buildout per GAE: http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/deployment/gae_buildout.html
- Descarregueu A TOTA XUFA amb el PyPI mirror del departament.
Més coses interessants però per mirar-les després:
- Tutorial alternatiu Pyramid amb Buildout per GAE: https://github.com/jensens/pyramid-gae-tutorial
- Instal·lador PIP per Python (més modern que easy_install): http://www.pip-installer.org . Mireu-vos-el si voleu tenir la darrera versió o si voleu instal·lar-ho en Windows o Mac OSX.
Seguint els passos d'aquest tutorial podem posar en marxa el nostre primer projecte.
OJU: poden aparèixer problemes de versions (al menys en Ubuntu 12.04) que cal arranjar del tutorial. La versió del pyramid_appengine (paquet amb la plantilla del buildout) no baixa en la seva darrera versió en algunes ocasions.
Troubleshooting
A data d'octubre de 2013 hi ha alguns conflictes de versions per posar en marxa un projecte de Pyramid GAE amb buildout.
Particularment el mòdul (egg) rod.recipe.appengine dóna l'error "setuptools not found".
Sol·lucions actual (oct 2013)
- Descarregar la versió correcta del pyramid_appengine amb:
$ pip install pyramid_appengine==0.8.2-a2
- Forçar a descarregar una versió de setuptools que ens funcioni al fitxer versions.cfg:
[versions]
setuptools = 1.1.5
He detectat altres problemes afegits que poden donar maldecaps. No està de més fer-li un cop d'ull a:
- Instal·lar el pip darrera versió de http://www.pip-installer.org (veure apartat install). Això no ens assegura, però que ens descarregui correctament la darrera versió de pyramid_appengine.
- Un cop creat el buildout, canviar la versió del appengine-sdk. Anar a buildout.cfg:
ae-sdk-version=1.8.5
- ...posant la darrera versió que trobem a la pàgina oficial de GAE.
Solucions anteriors però que no van ara:
- Seguir el tutorial fins realitzar el
$ bin/buildout
- ...ens donarà l'error "setuptools not found".
- Aplicar aquest patch al mòdul rod.recipe.appengine. Modificar l'arxiu:
$ gedit eggs/rod.recipe.appengine-2.0.2-py2.7.egg/rod/recipe/appengine/__init__.py
- Tornar a executar el buildout i arrencar el servidor normalment.
Creant views al projecte
Per veure com utilitzar Pyramid podeu llegir Pyramid: arquitectura.
Activant plantilles Mako
Si volem utilitzar les plantilles Mako (que són les que hem utilitzat des del principi) caldrà fer alguns ajustos al projecte generat:
$ bin/buildout -v
__init__.py
Afegirem a la funció make_app():
...
__here__ = os.path.dirname(os.path.abspath(__file__))
...
def make_app():
...
settings = {}
settings['mako.directories'] = os.path.join(__here__, 'templates')
config = Configurator( root_factory=Root, settings=settings )
...
# afegim la URL "/home" a la que accedim amb "http://localhost:8080/home"
config.add_route( "home", "/home" )
config.add_view( views.home_view, route_name="home", renderer="main.mako" )
# OJU: el config.scan() no li agrada al GAE!!
views.py
Afegirem les views pertinents:
# OJU: al GAE no li agraden els decorators @view_config !!!
def home_view( request ):
return {"project":"gapp1"}
templates/main.mako
<html>
<head>
<title>${project}</title>
</head>
<body>
<h1>Projecte ${project}</h1>
<p>Aviam que tal va aixo...</p>
</body>
</html>
Afegir plantilles
Quan afegim una nova plantilla .mako cal refer el projecte, ja que els arxius s'han de traslladar al directori "parts":
$ bin/buildout -v
Exemple: Pyges
Pyges és un projecte per CMS basat en Pyramid i GAE. Pots instal·lar-lo per tenir un exemple de codi i realitzar els exercicis proposats més avall.
Descarrega el projecte Pyges de githum.com :
$ git clone https://github.com/emieza/pyges.git
Oju, perquè hi ha 2 versions de buildout:
- buildout.conf.lacetania: utilitza el mirror que tenim dins l'escola (taupaipai)
- buildout.conf.main: utiltiza el servidor principal pypi.python.org . Utilitzeu-ho per treballar a casa.
Per treballar amb un o altre cal que copieu un dels dos i sobreescriviu el buildout.conf abans de començar a construir el projecte.
Construeix el projecte amb:
$ python bootstrap.py $ bin/buildout
I finalment l'arranquem amb:
$ bin/devappserver parts/pyges --use_mtime_file_watcher
(amb aquesta opció es recarrega automàticament quan guardem canvis en algun arxiu).
Mireu-vos el codi per realitzar els exercicis que venen a continuació.
Exercici 1: Zodíac
Farem una pàgina on puguem entrar la nostra data de naixement i que ens digui el signe del zodíac que ens correspon, amb imatges estupendes per fer-ho més cool.
Mira't el codi d'exemple més amunt (projecte Pyges).
Us recomano seguir les següents passes:
- Crear una pàgina "home" com s'indica anteriorment en aquest tutorial i titular el nostre projecte adequadament. Substituïu la pàgina per defecte del template (elimineu la original).
- Afegir les fotos dels signes del zodíac a la pàgina "home". Inicialment ho farem en la plantilla .mako com si fos un HTML normal.
- Els arxius de les fotos les heu de col·locar dins el subdirectori
static
- Els arxius de les fotos les heu de col·locar dins el subdirectori
- Canvieu el HTML del template per un bucle de la plantilla
mako
.- Des de la view cal que li passeu la llista, per exemple en la variable "imatges".
- Consulteu a http://www.makotemplates.org com funcionen els bucles de
mako
.
- Feu un formulari per mostrar el signe del zodíac que demani a l'usuari data de naixement, que calculi el seu signe i que mostri la foto pertinent.
- La manera de recollir i utilitzar les dades d'un formulari en Pyramid (dins la view) és utilitzant la variable request.POST, de manera pràcticament idèntica al $_POST de PHP. (mireu l'exemple de Pyges més amunt). En principi hauria de ser:
data = request.POST['data']
- Però si voleu saber si existeix la variable podeu fer
data = request.POST.get('data')
- Una altra manera seria fent:
if 'data' in request.POST: ...
- La manera de recollir i utilitzar les dades d'un formulari en Pyramid (dins la view) és utilitzant la variable request.POST, de manera pràcticament idèntica al $_POST de PHP. (mireu l'exemple de Pyges més amunt). En principi hauria de ser:
- Pots afegir una "frase de la sort" aleatòria a escollir d'una llista de frases que tinguis per llegir la bonaventura de l'usuari.