Scharfe Würzmischung

Dynamische Webseiten, wie sie viele mit JSP, Perl oder PHP realisieren, lassen sich mit Python ebenfalls erstellen. Tools wie Spyce helfen bei der Arbeit.

In Pocket speichern vorlesen Druckansicht 13 Kommentare lesen
Lesezeit: 10 Min.
Von
  • Thomas Kaufmann
Inhaltsverzeichnis

Spyce, das derzeit in der Version 1.3.11 vorliegt, ist eine portable Webserver-Engine von Rimon Barr zur Erzeugung dynamischer Webinhalte in der Scriptsprache Python. Wer sofort an PHP, JSP und ASP denkt, weiß, was mit diesem Tool auf ihn zukommt - nur eben in einer anderen Sprache. Generell lässt sich sagen, dass wer mit Spyce arbeitet, Zugriff auf alle Sprachmittel und Bibliotheken der objektorientierten Programmiersprache Python hat. Spyce ist einfach zu erlernen, modular aufgebaut, leicht erweiterbar und eine Alternative zu den genannten Techniken.

Um es vorauszuschicken: Dynamische Webseiten mit Python sind nicht nur mit Spyce machbar. Das Flaggschiff unter in Python geschriebenen Webdevelopmenttools ist zweifellos Zope, bei dem man sich man sich auf Version 3 freuen kann, die nach Guido van Rossum ein großer Schritt vorwärts im Vergleich zu 2.x sein soll. Geplant ist, mit Zope 3 in der ersten Liga des Content-Managements mitzuspielen. Ein weiteres Werkzeug, aber bei weitem nicht so populär, ist der Application Server Webware (siehe „ Online-Ressourcen“) inklusive der Python Server Pages. Und Module für die klassische CGI-Entwicklung sind in der Python-Standardbibliothek ebenfalls zu finden.

Online-Ressourcen
Python www.python.org
Spyce spyce.sourceforge.net
Spyce vs. JSP, ASP, PHP et cetera spyce.sourceforge.net/doc-intro_rationale.html
Webware for Python webware.sourceforge.net
Zope www.zope.org, www.zope.com
Cheetah www.cheetahtemplate.org/
Cherry Py www.cherrypy.org
HTMLgen starship.python.net/crew/friedrich/HTMLgen/html/main.html
Jython www.jython.org

Zudem existieren effiziente Template-Generatoren (wie HTMLgen) und eine Menge anderer Hilfsmittel (Cherry Py, Cheetah) für die Programmierung dynamischer Webinhalte. Selbst die Java-Bibliotheken rücken mit Jython in das Blickfeld des Python-Entwicklers (Servlet API, Web Services API). Wer all diese Werkzeuge dennoch nicht nutzen kann/möchte oder eine solide Alternative zu den anderen serverseitigen Ansätzen sucht, sollte sich Spyce ansehen. Aus einem einfachen Grund: Es basiert auf einem überzeugenden Konzept (Skripts sind first-order-objects innerhalb der Sprache, im Gegensatz zu JSP); außerdem entwickelt Rimon Barr das Werkzeug weiter, und andere unterstützen es gut.

Last, but not least, bietet Spyce die ganze Power Pythons: die einfache Syntax (Wartbarkeit), Rapid Development, das ganze Arsenal einer objektorientierten Sprache sowie exquisite Möglichkeiten zur Textverarbeitung (inklusive XML-Processing), die umfangreiche Standardbibliothek, einfachen Zugriff auf Datenbanken et cetera. Hinzu kommt, dass die Software gut dokumentiert ist. Und sollte die Dokumentation eine Frage offen lassen, hilft fast immer die Mailingliste weiter. Bei der Dokumentation handelt es sich um Referenz, Tutorial und User Guide zugleich. Zusätzlich wird an einer Community-Plattform gearbeitet, die der Kommunikation zuträglich sein dürfte.

Drei Installationsvarianten existieren: für Linuxer die RPM-Variante, für Windows-Anwender die typische Installationsroutine (*.exe-Datei) und schließlich die manuelle Variante. Als Voraussetzung erwartet Spyce lediglich einen aktiven Webserver sowie eine Python-Installation (ab Version 1.5).

Barr hat das Tool mit Apache 1.3.22 entwickelt und getestet, obwohl es nicht allein auf den Apache-Server und nicht auf diese Version beschränkt ist. Zur Installation: da wäre zunächst der „Fast CGI“-Ansatz, zweitens lässt sich Spyce mit mod_python koppeln, diese Option liefert bei weitem die beste Performance, oder man kann Skripts im Webserver-Mode evaluieren - das ist ebenfalls schnell. Die mit Abstand langsamste Interaktion ist die via CGI. Für die Arbeit auf localhost reicht das aber oft aus; diese Installationsart ist übrigens mit dem geringsten Aufwand verbunden.

Zudem lässt sich Spyce auf der Kommandozeile zum Pre-Processing von Skripten nutzen, oder zur Erstellung statischer HTML-Seiten, was sich als überaus praktisch erweist. Die Dokumentation informiert ausführlich.

Nutzer, seien sie nun mit JSP, PHP oder ASP vertraut, finden in den Standard-Modulen die folgenden vor: request, response, redirect, error, debug, include, cookie, session, template, transform, compress, taglib und ein paar andere. Diese Liste sollte jedoch genügen, um vor Augen zu führen, dass Spyce die wesentlichen Bedürfnisse des Webentwicklers abdeckt. Und fehlt etwas, ist es nicht schwierig, eigene Module hinzuzufügen; auf Wunsch ist Rimon Barr meistens sogar bereit, notwendige Neuerungen oder probate Techniken anderer Server-Engines in die Sprache zu integrieren.

Ein Spyce-Skript besteht aus normalem HTML- und Einsprengseln von Python-Code. Letzteren kann man durch bestimmte Formatierer auf folgende Arten in ein Skript einbetten:

[[-- Spyce-Kommentar --]]
[[. Spyce-Direktive ]]
[[ Python-Statement(s) ]]
[[\ Python-Chunk ]]
[[= Python-Ausdruck ]]
<taglib:name attr1=val1 ...>

Ein paar Beispiele sollen die Verwendung wichtiger Konstrukte verdeutlichen. Ein Python-Statement könnte so aussehen:

[[ for i in range(10): { ]]
[[=i]]
[[ } ]]

Ein Python-Chunk wiederum kann folgendermaßen aufgebaut sein:

[[\
def printHello(num):
for i in range(num):
response.write('hello<br>')
printHello(5)
]]

Achtung: Hier ist die Identation (die pythontypische Codeeinrückung) zu beachten. Und zum guten Schluss ein Python-Ausdruck: [[=myvar ]].

Darüber hinaus erkennt die Spyce-Engine seit einiger Zeit ASP/JSP-Auszeichner, sodass damit vertraute Entwickler die folgenden Formatierer ebenfalls verwenden können.

<%-- Spyce-Kommentar --%>
<%@ Spyce-Direktive %>
<% Python-Statement(s) %>
<%\ Python-Chunk %>
<%= Python-Ausdruck %>

Ein simples Skript soll den Umgang mit Spyce demonstrieren. Es muss sich in einem Verzeichnis des Webservers befinden, in dem Skripts ausgeführt werden dürfen (unter Apache üblicherweise cgi-bin), und es muss ausführbar sein.

beispiel.spy wurde unter Linux (Suse 7.1), mit Python 2.2, Spyce 1.3.9 und einem herkömmlichen Apache-Server sowie unter Red Hat 8.0, Spyce 1.3.11 und Apache 2.0.46 getestet - der Einfachheit halber mit der CGI-Installationsvariante; der Pfad zur Spyce-Engine muss in diesem Fall, nach einem Leerzeichen, direkt hinter der Shebang-Zeile (dem Interpreter-Pfad) stehen:

#!/usr/bin/python /Pfad/zu/spyce

#!/usr/bin/python /Pfad/zu/spyce Je nach verwendetem Betriebssystem sehen die Pfade anders aus. Dieses Skript generiert eine Tabelle mit den Umgebungsvariablen des Webservers und zeigt die Verwendung einiger Spyce-Konstrukte im Zusammenspiel mit Python. Ein paar Spyce-Module wie compress müssen importiert werden, während so elementare Module wie request dem Entwickler automatisch zur Verfügung stehen. Apropos: Das Modul compress extrahiert Whitespaces (Leerzeichen, Newlines, Tabs) aus dem von der Spyce-Engine generierten HTML-Code. Dadurch geht die Übertragung an den Client fixer über die Bühne.

Python-Module werden auf dem üblichen Weg importiert - einziger Unterschied sind die eckigen Klammern (siehe oben und im Listing bei import os).

Mehr Infos

Listing 1: beispiel.spy

#!/usr/local/bin/python /hier/steht/der/spyce/pfad

[[.import name=compress args="spaces=1" ]]
[[ import os ]]
<html>
<head><title>Server Environment</title></head>
<body>
[[-- Das ist ein Kommentar --]]
[[ anyvar = 'Hallo Spyce-Welt' ]]
<%=anyvar %>
[[=anyvar ]]
[[ response.write('<br>noch mal ' + anyvar) ]]
<br>
Ihr Betriebssystem: [[=os.name ]]
<br>
<hr>
<br>
[[\
# Python-Chunk
se = request.env() # server environment=se
print '<table>'
for k in se.keys():
print '<tr><td>%s</td><td>%s</td></tr>' % (k, se[k])
print '</table>'
]]
</body></html>

<%=anyvar %> ist JSP/ASP-Syntax, die die Engine klaglos evaluiert - unmittelbar darunter befinden sich zum Vergleich die Spyce-spezifischen Varianten.

Im letzten Block unten (ein Python-Chunk, auf Deutsch: ein paar Python-Anweisungen), den nach den eckigen Klammern ein Backslash einleitet, liest die Methode env() des request-Moduls das Server-Environment in ein Dictionary (vergleichbar einem Hash in Perl oder Hashtable in Java) ein und gibt die Variablen und Werte anschließend in einer Schleife aus. In diesen Blöcken darf der Entwickler alles tun, was in Python-Programmen erlaubt ist - ohne Beschränkung (Klassen, Ausnahmen, Funktionen et cetera). Das gilt ebenso für die Indentierung, die Einrückung des Codes, die in Python-Chunks selbstverständlich zu berücksichtigen ist.

Normale HTML-Tags sind von der Arbeit der Spyce-Engine nicht betroffen, sie ignoriert sie einfach. In diesem Kontext sei auf die so genannten Active Tags hingewiesen (sie stehen in Tag Libraries, die explizit zu importieren sind); diese Tags evaluiert die Engine an der Position ihres Auftauchens. Entwickler müssen besondere Elemente vorher spezifizieren. Überdies dürfen Active Tags mit ihresgleichen im Dokument kommunizieren. Erfahrungsgemäß trägt die Anwendung von Tag Libraries zur Minimierung der Codemenge bei.

Ein paar Worte zum Code in Listing 3 und 4; zuerst wird in einer typischen Python-Klasse das gewünschte Tag spezifiziert (Listing 3);

Mehr Infos

Listing 3: myTaglib.py

from spyceTag import spyceTagLibrary, spyceTagPlus

class tag_foo(spyceTagPlus):

name = 'foo'
def syntax(self):
self.syntaxPairOnly()
self.syntaxExist('val')
self.syntaxNonEmpty('val')
def begin(self, val):
val = self.contextEval(val)
self.getOut().write('<font size="%s"><b>' % str(val))
return 1
def end(self):
self.getOut().write('</b></font><br>')

class myTaglib(spyceTagLibrary):
tags = [tag_foo,]

anschließend kann Listing 4 dieses Modul importieren (die Zeile [[.taglib name=myTaglib as=me]] regelt das) - das wars schon. Beide Dateien dürfen sich im gleichen Verzeichnis befinden (im Falle der einfachen CGI-Variante im cgi-bin-Verzeichnis).

Mehr Infos

Listing 4: activetags.spy

#!/usr/local/bin/python /hier/steht/der/spyce/pfad

[[.taglib name=core as=spy]]
[[.taglib name=myTaglib as=me]]

<html><body>
<spy:for var=x items="=range(2,8)">
<me:foo val="=x">size <spy:print val="=x" /></me:foo>
</spy:for>
</body></html>

Ein wichtiges Thema ist, wie überall, die Wiederverwendbarkeit von Code beim Programmieren. Lambdas bieten dem Entwickler die Möglichkeit, Templates vorzuhalten, um sie bei Bedarf an beliebigen Stellen in den Code einzubauen. In der einfachsten Form sieht das aus wie Listing 2.

Mehr Infos

Listing 2: template.spy

#!/usr/local/bin/python /hier/steht/der/spyce/pfad

[[-- Templating mit Spyce Lambdas --]]
[[
gruss = [[spy besucher: Willkommen [[=besucher]] ]]
]]
<html>
<head><title>Templating mit Spyce Lambdas</title></head>
<body>
[[-- Einfuegen des Templates gruss --]]
[[ gruss(request.env('REMOTE_ADDR')) ]]
</body></html>

Wer mit der Anwendung von Lambda in Python vertraut ist, dem dürfte dieses Konzept grundsätzlich bekannt vorkommen. Dieses simple Mini-Template kann überall auf einer Webseite eingebettet werden, wo es erforderlich ist. Es liegt auf der Hand, dass sich mit den Lambdas ganze Bausätze an wiederverwendbaren Komponenten (Tabellen, Formulare et cetera) anlegen lassen. Entwickler können Lambdas in separaten Dateien ablegen (per Konvention mit der Endung .spi versehen); bei Bedarf müssen sie aber durch das Modul inlcude importiert werden, was jedoch einfach ist und die Flexibilität der Applikation erhöht.

Kurz zur schon erwähnten XML-Verarbeitung: Sie ist mit Spyce genauso leicht zu bewerkstelligen wie mit jeder anderen heute im Einsatz befindlichen Webserver-Engine (siehe Listing 6).

Mehr Infos

Listing 6: xmlsample.spy

#!/usr/local/bin/python /hier/steht/der/spyce/pfad

[[ import sys ]]

<html>
<body>
[[\
# Python-Chunk
import xml.sax
from xml.sax.handler import ContentHandler
class textParser(ContentHandler):
def characters(self, ch):
print (ch.encode("Latin-1")), '<br>'
parser = xml.sax.make_parser()
handler = textParser()
parser.setContentHandler(handler)
parser.parse("user.xml")
]]
</body></html>

Entwickler können mit Spyce schließlich auf jedes Modul der Python-Standardbibliothek zugreifen; selbstredend gilt das für alle XML-Processing-Module. Listing 6 arbeitet mit SAX, und es werden nur die Inhalte (was zwischen den Tags steht) der Datei user.xml (Listing 5) ausgegeben.

Mehr Infos

Listing 5: user.xml

<?xml version="1.0" encoding="UTF-8"?>
<user>
<name>Karin Musterfrau</name>
<alter>40</alter>
<name>Herbert Mustermann</name>
<alter>35</alter>
</user>

Spyce ist zwar erheblich umfangreicher, als hier ersichtlich sein kann, aber schlank genug, um es Entwicklern zu erlauben, sich schnell einzuarbeiten. Eine Frage drängt sich angesichts vieler Lösungen für die Programmierung dynamischer Webseiten allerdings auf: Warum noch eine Servertechnik? Wer diesbezügliche Gedanken hegt, dem sei der der Vergleich mit PHP, ASP, JSP und Zope ans Herz gelegt (siehe „Online-Ressourcen “). Wer Python kennt, dürfte schnell professionelle Resultate vorweisen können, die den Ansprüchen moderner Webprogrammierung vollauf genügen. Und die Wahl des Werkzeugs hängt immer davon ab, welche Eigenschaften das verwendete Werkzeug haben soll.

Thomas Kaufmann
ist freier Python/Zope-Entwickler sowie Datenbankadministrator und arbeitet als IT-Consultant für mehrere Berliner Firmen.

Mehr Infos

iX-TRACT

  • Dynamische Webseiten lassen sich mit Python auf unterschiedliche Weise erstellen, beispielsweise mit Spyce.
  • Wer das serverbasierte Spyce verwendet, kann auf alle Sprachmittel Pythons zurückgreifen und sich zusätzlich Taglibs schreiben.
  • Spyce lässt sich sowohl mit (Fast)CGI als auch als Apache-Modul nutzen.


(hb)