Googles Appengine steht für hochskalierbare Anwendungen in der Cloud. Locandy ist unser Startup für mobile Location based Games.
Auf der Cloud-Platform mit ihrer sehr restriktiven Python-Umgebung haben wir das Portal für Spieler, Autoren und Business Kunden umgesetzt. Browser, Mobile-App und PDF-Server werden damit bedient.
Dabei ist nicht alles so rund gelaufen, wie wir es gerne gehabt hätten. Die Probleme wurden gelöst - dank Python mit seinem starken Werkzeugkasten.
Der Vortrag geht kurz auf die Anforderungen ein, zeigt auf welche Probleme es gab und wie wir sie gelöst haben. In einem Github Repository stelle ich ein Buildout inkl. kleiner Beispielapplikation mit den meisten dieser Lösungen zur Verfügung.
Schlangenhochzeit in-der Wolke - Pyramid auf Google Appengine
1. 3. Deutsche
Python-Konferenz
Köln 2013
Schlangenhochzeit
in der Wolke
Python / Pyramid
auf Googles Appengine
Jens W. Klein
jk@kleinundpartner.at
http://kleinundpartner.at
16.10.2013
1 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
3. 3 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
4. 4 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
5. 5 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
6. 6 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
7. ●
Startup Unternehmen mit Sitz in Innsbruck
●
Location based Games
●
gefördert durch die FFG (Östereichische
Forschungs-Förderungs-Gesellschaft) von
1/2012 bis 6/2013
●
4 Gesellschafter
●
KUP: Gesellschafter seit 11/2012
●
KUP-Aufgaben: Projektmanagement,
Development Support, Portalumsetzung
7 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
8. 8 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
9. Anforderungen
1
●
●
Entwicklung eines Mixed Reality Media Formats
für Location based Games.
Entwicklung eines MRM-Players für
Smartphones
–
–
HTML5/Javascript basiert
–
●
100% Offline-fähig
Native App stellt nur Laufzeitumgebung zur
Verfügung
Entwicklung eines Editors für das MRM-Format
9 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
10. Anforderungen
2
●
Entwicklung eines Portals für eine wachsende
Locandy-Community für
–
–
●
Spieler und Autoren,
kommerzielle Kunden und Werbetreibende.
das Portal soll
–
skalierbar sein,
–
verfügbar sein und
–
kaum Personalaufwand für Hosting verursachen.
10 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
11. Anatomie
Suche
Appengine
Google Cloud
Android/ iOS (native)
Download
PORTAL
APP
Spielergebnis
Browser
HTML5
Javascript
Apache Cordova Webview
+ Plugins
Editor
Player
Spiel
Player
Vorschau
11 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
12. 12 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
13. Google Appengine
1: Google sagt
●
●
●
wird bei größter Belastung und hohen
Datenmengen zuverlässig ausgeführt wird.
Automatische Skalierung und Lastenausgleich
Eine lokale Entwicklungsumgebung mit allen
Funktionen, die Google App Engine auf Ihrem
Computer simuliert
●
Aufgaben-Queue außerhalb einer Webanfrage
●
Cron-Job-ähnliche Zeit/ Intervall Aufgaben
●
https://developers.google.com/appengine/docs/
whatisgoogleappengine?hl=de
13 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
14. Google Appengine
2
●
Cloud Plattform von Google seit 2008
●
Applikationen laufen in einer Sandkiste
●
Programmiersprachen:
–
Python - erste unterstützte Sprache
–
Java - häufigst genutzte Sprache
–
Go - Google Eigenentwicklung, Nische
–
PHP - erst seit wenigen Monaten
14 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
15. Google Appengine
3
●
eingeschränkter Funktionsumfang der Sprache
–
–
Laden von externen URLs über eigene API/Dienst
–
●
Mail muss über eigene API/Dienst verschickt
werden
–
●
keine Egg-Unterstützung, Sockets, Tempfiles,
Dateisystem nur RO
keine Python C-Erweiterungen möglich
Blobstorage/ Google Cloudstorage erfordert
spezielle Handhabung von Binärdaten
eigene Objekt-Datenbank
15 von 36
...uvm.
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
16. 16 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
17. Pyramid
1
●
FOSS Python Webframework
●
Ausgewähltes Bestes aus der Welt von
–
–
Django,
–
●
Zope,
–
●
Pylons,
und einigen anderen Inspirationen.
Der Kern ist Minimal, nur wenige Vorgaben,
dafür viele Add-Ons um verschiedene Ziele zu
erreichen.
17 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
18. Pyramid
2
●
Die Qual der Wahl
–
Urlmatch oder Traversal? Oder beides?
–
Datenbank relational oder objektorientiert?
–
Mako, Chameleon-ZPT, Jinja oder was als
Template-Sprache?
–
Welche Art von Authentifizierung und
Authorisierung?
–
Strukturierung des Projektes nach Layern, nach
Fachklassen oder wie sonst?
–
...?
18 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
19. Pyramid
3
●
●
●
●
●
Pyramid ist komplett Komponenten basiert,
verwendet Zope Kompenenten Archiktektur,
aber versteckt sie für den Otto-NormalProgrammmierer.
Es gibt viele fertige Komponenten, die einem
das Leben leicht machen,
und es werden ständig mehr!
Hinter Pyramid steht eine noch kleine aber sehr
lebendige Community.
19 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
20. 20 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
21. Hochzeit
Pyramid mit Appengine
●
Pfarrer ist zc.buildout
●
collective.recipe.appengine spielt die Musik
–
noch unreleased, code auf github
–
Fork von eingeschlafenem Projekt
appfy.recipe.appengine
–
wir lieben Pull-Requests!
–
automatische Installion von Appengine SDK, Tools
und Development Server,
–
mixt aus Eggs eine Baumstruktur.
21 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
22. ├──
│
│
│
│
│
│
│
├──
├──
├──
├──
└──
app
├──
├──
├──
├──
├──
└──
Pyramid mit
zc.buildout auf appengine
app.yaml
1: Struktur vor buildout
gaefixes.py
main.py
pkg_resources.py
Python Wurzel
settings.yaml
aus Sicht der Appengine
static
├── [... css, png, jpg, ...]
bootstrap.py
buildout.cfg
versions.cfg
ab hier Egg-Struktur
gaetools.cfg
source
└── example_app
├── setup.cfg
ab hier example_app,
├── setup.py
Wurzel aus Sicht
└── src
von Python
└── example_app
├── __init__.py
├── [...] 22 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
23. Pyramid mit
zc.buildout auf appengine
2: Beispiel Code
Aller Code und Buildout lauffähig auf
http://github.com/jensens/pyramid-gae-tutorial
23 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
24. Pyramid mit
zc.buildout auf appengine
3: buildout laufen lassen
●
Python 2.7
●
Virtual-Env größer Version 1.9
$ cd path/to/buildout
$ virtualenv --no-site-packages
--no-setuptools --clear .
$ ./bin/python2.7 bootstrap.py
$ ./bin/buildout
24 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
25. Pyramid mit
zc.buildout auf appengine
4: nach dem Lauf
●
●
●
●
●
./bin enthält dev_appserver und viele andere
tools, jedoch nicht alle benötigt in der
Appengine,
./app/distlib enthält Eggs in Baum aufgelöst
./app/example_app ist symbolischer Link auf
die Python Wurzel der Beispiel App,
./parts/appengine_sdk enthält das offizielle
Google Appengine SDK,
./var ist angelegt, dort wird die Datenbank der
Entwicklungsumgebung abgelegt.
25 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
26. Pyramid mit
zc.buildout auf appengine
5: dev_appserver starten
●
●
●
●
./bin/dev_appserver startet den
Entwicklungsserver
die App läuft per default auf
http://localhost:8080
die Admin-Benutzeroberfläche läuft auf
http://localhost:9000
die Einstellungen für den dev_appserver werden
aus der Datei ./gaetools.cfg eingelesen.
26 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
27. 27 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
28. Kommunikation in der Ehe
GAEFixes
●
Fixes/ Monkeypatches sind leider tw. notwendig
●
müssen als erstes im main.py geladen werden
●
sys.path anpassen
●
●
●
pkg_resources im Entwicklermodus: Appengine
import_hook registrieren
chameleon zpt im Entwicklermodus: Patchen
des Debug Lade-Modus, da keine Tempfiles
erlaubt sind.
zudem evtl. Library spezifische Hacks.
28 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
29. Initialisierung der
Pyramid App
●
●
●
●
●
settings.yaml enthält Pyramid- und AppEinstellungen Google-mäßig als YAML
(normalerweise in Pyramid im INI-Format),
main.py wie für normale WSGI-Anwendungen
und stellt hier Pyramid application Objekt zur
Verfügung,
main.application ist in appengine config file
app.yaml für alle Anfragen registriert,
statische Ressourcen können direkt via
Appengine Routing ausgeliefert werden.
29 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
30. 30 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
31. Debugging Probleme und
der Wert des Testens
●
pdb funktioniert im dev_appserver nicht!
●
print funktioniert nicht (aber logging geht),
●
●
●
scheinbar gibt es Remote-Debugging hooks
-> noch nicht ausprobiert,
-> kompliziert einzurichten,
-> nur für Eclipse, evtl. andere IDEs möglich;
pdb in Tests funktioniert, ipdb (ipython)
funktionert in Tests.
interlude interaktive Konsole für Doctests
funktioniert (inkl. ipython).
31 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
32. Test getriebene
Entwicklung
●
Appengine bietet Funktionen um verschiedene
Teile der Laufzeitumgebung zu starten und
stoppen (Datastore, Blobstore, Memcache usw.),
●
Test/Testumgebung muss diese verwenden,
●
Nose-Tests: nosegae ! -> nicht lauffähig
●
eigenen Testrunner geschrieben, zu unflexibel
●
●
schließlich zope.testrunner mit Appengine
verheiratet
dann plone.testing Test-Layers integriert
32 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
33. Tests in Schichten
plone.testing + zope.testrunner
●
●
●
●
●
Layers werden für Test Fixtures (Test
Ausstattungen) genutzt, die von mehreren TestFällen gemeinsam genutzt werden,
vereinfacht/ vereinheitlicht Setup/ Teardown
Aufteilung z.B. pure Python Tests, Tests mit
Datenbank, Tests gegen Webserver, ...,
bzw.: Unit-Test, Functional-Tests und IntegrationTests,
bei sehr vielen Tests schnellere Ausführung.
33 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
34. Test-Beispiel
1: mit Datenbank, ohne Webtest
creating a first node::
>>> from example_app import models
>>> node = models.create_node('test1',
...
'Test One', 'This is a first test.')
>>> node
TreeModel(key=Key('TreeModel', 'test1'),
body=u'This is a first test.', title=u'Test One')
trying to create a node that already exists raises ValueError::
>>> node = models.create_node('test1', 'X', 'X')
Traceback (most recent call last):
...
ValueError: node with name test1 already exists
34 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
35. Test-Beispiel
2: mit Datenbank und Webtest
>>> node = models.create_node('test1', 'Test One',
...
'This is a first test.')
>>> node
TreeModel(key=Key('TreeModel', 'test1'),
body=u'This is a first test.', title=u'Test One')
>>> response = layer.webtest.get('/test1')
>>> 'Test One' in response
True
>>> 'This is a first test.' in response
True
>>> response = layer.webtest.get('/nonexistent',
...
status='404', expect_errors=True)
>>> response.status
'404 Not Found'
35 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
36. 36 von 36
Text: Creative Commons Namensnennung-Keine
kommerzielle Nutzung- Keine Bearbeitung 3.0
Österreich Lizenz.
Hinweis der Redaktion
Dank Roland,
ich möchte jetzt ein wenig in die Welt der Virtualisierung, der Redundanz und des technischen Webpublishings mit Plone eintauchen.
Wenn dies für Sie noch Fremdwörter sind bleiben Sie trotzdem sitzen. Ich versuche behutsam die Begriffe zu erklären.