info@a-coding-project.de

Python: Web-Frameworks

Für kleinere Anwendungen und "Quick Hacks" ist CGI-Programmierung mit dem cgi-Modul und dem DB API sicher gut geeignet, wer jedoch größere Web-Anwendungen entwickeln will, sollte einen Blick auf die verschiedenen Web-Frameworks für Python werfen; der folgende Abschnitt soll einen kurzen Überblick über zwei solche Frameworks geben. Den Frameworks gemeinsam ist die Einführung eines Templating System, mit dessen Hilfe HTML-Code einfacher und komfortabler generiert werden kann als mit dem Python 's eingebautem %-Operator.

Quixote

Quixote (http://www.mems-exchange.org/software/quixote/) verfolgt den Ansatz, den Templating-Code möglichst Python-ähnlich zu machen. Dazu erweitert Quixote den import-Befehl von Python , der dann auch Module, die in der sogenannten PTL (Python Template Language) geschrieben sind, laden kann. So kann beispielsweise ein PTL-Codefragment zur Erstellung eines HTML-Headers aussehen:

def header [plain](request,
                   title = None,
                   keywords = None,
                   meta_info = None):
    '<html>'
    '<head>'
    '<title>%s</title>' % html_quote(str(title))
    if keywords:
        '<meta name="keywords" content="%s">' % 
html_quote(keywords)
    if meta_info:
        meta_info

Im wesentlichen ist eine PTL-Funktion normaler Python-Code; der wesentliche Unterschied liegt in der Behandlung des Rückgabewertes: Jedes Statement in einer PTL-Funktion, das einen Wert liefert, trägt zum Rückgabewert bei (genauer gesagt der Wert wird mit str() in einen String umgewandelt und an den Rückgabewert angehängt).

Eine Quixote-Applikation ist typischerweise ein Python-Package (eine Sammlung verschachtelter Module). Quixote bildet dann denURLeines Requests auf eine Funktion oder Methode innerhalb eines der Module ab. Diese wird dann mit den Daten des HTTP-Requests aufgerufen und das Ergebnis an den Aufrufer zurückgeliefert. Dabei ist es auch möglich, das aufgerufene Objekt dynamisch zu erzeugen: Die Funktion _q_lookup() wird, wenn in einem Modul vorhanden, mit der URL-Pfadkomponente, die in diesem Modul traversiert werden soll, aufgerufen. Die folgende Funktion erzeugt etwa für alle URLs der Form http://.../1, http://.../2, usw. eine spezifische Seite:

def _q_lookup (request, component):
    try:
        intval = int(component)
    except ValueError:
        # Not an integer
        return None
    else:
        return "HTML page for the integer %i" % intval

Die Funktion kann entweder einen String, der direkt an den Client geliefert wird, None, was Quixote zum lieferen eines HTTP 404 "Not Found" Fehlers veranlasst, oder ein Objekt, das weiter traversiert werden soll, zurückgeben.

Quixote-Applikationen können in verschieden Konfigurationen, je nach Anwendungsfall, betrieben werden:

  • In einem Python-Webserver (z.B. Medusa oder Twisted). Dieses Setup ist einfach zu konfigurieren und eignet sich gut für Intranet- und kleine Internetapplikationen.
  • Über S CGI (ein Protokoll, das die selben Ziele wie Fast CGI hat, aber wesentlich einfacher ist) und mod_scgi von Apache . Hier läuft die Quixote-Applikation in einem eigenen Daemon-Prozess, an den Apache die Requests weiterreicht. Diese Konfiguration ist recht performant.
  • Über mod_python, das einen Python-Interpreter in Apache einbettet.
  • Als reguläres CGI-Skript, was allerdings wegen der schlechten Performance nicht empfohlen wird.

Albatross

Albatross (http://www.object-craft.com.au/projects/albatross/) verfolgt einen anderen Ansatz beim Templating: Hier wird der HTML-Code nicht in Python-Module gepackt, sondern in eigenen Template-Files gespeichert, die HTML-Syntax, mit zusätzlichen, Albatross-spezifischen Tags haben. Diese Tags erlauben z.B. die Programmierung von for-Schleifen oder den Zugriff auf Python-Werte. Werte auf die das Template zugreifen können soll, werden explizit in einem Ausführungskontext festgelegt. Diese Vorgehensweise hat den Vorteil, dass das Template mit normalen HTML-Werkzeugen bearbeitet werden können; die Arbeit zwischen Web-Designer und Web-Programmierer lässt sich so besser aufteilen. Bei Quixote hingegen muss der Web-Designer auch (ein Minimum an) Python beherrschen und den HTML-Code "per Hand" bearbeiten. Hier ein Beispiel-Template:

<html><head><title>The CGI environment</title></head>
 <body>
  <table>
   <al-for iter="name" expr="keys">
    <tr>
     <td><al-value expr="name.value()"></td>
     <td><al-value expr="environ[name.value()]"></td>
    <tr>
   </al-for>
  </table>
 </body>
</html>

Das obige Template generiert eine Tabelle mit Werten aus dem environ-Dictionary, wobei über die in keys abgelegten Schlüsselwerte iteriert wird. Das zugehörige Programm:

#!/usr/bin/python
import os
from albatross import SimpleContext

ctx = SimpleContext('.')
templ = ctx.load_template('simple.html')

keys = os.environ.keys()
keys.sort()
ctx.locals.keys = keys
ctx.locals.environ = os.environ

templ.to_html(ctx)

print 'Content-Type: text/html'
print
ctx.flush_content()

Hier wird zuerst ein Ausführungskontext für das aktuelle Verzeichnis erzeugt, das Template in den Kontext geladen, und die locals-Komponente des Kontexts mit den Werten versorgt, auf die später im Template zugegriffen werden soll. Der Aufruf templ.to_html(ctx) führt das Template aus und erzeugt den entsprechenden HTML-Code. Mit ctx.flush_content() wird das HTML dann wirklich auf die Standardausgabe geschrieben. Diese Teilung in erzeugen und hinausschreiben der Daten besteht, damit bei eventuell auftretenden Fehlern bei der Ausführung des Templates nicht eine Teilausgabe beim Browser ankommt.

Über uns

Stefan Wienströer

Wir entwickeln Webanwendungen mit viel Leidenschaft. Unser Wissen geben wir dabei gerne weiter. Mehr über a coding project

Auch interessant