Seite 1 von 1

WSGI, CGI, TAL, Python Servlet Engine, Zope

Verfasst: Montag 27. Februar 2006, 17:11
von gerold
Hi!

Ich schlage derzeit immer mal wieder CGI für kleine Webprojekte vor, da CGI ziemlich einfach gebaut ist und man damit innerhalb von wenigen Minuten kleine, dynamische Websites erstellen kann.

Der Vorteil von CGI in dem Sinne ist für mich der, dass sich der Webserver darum kümmert, die Dateien an den Browser auszuliefern. Und das macht er ohne dass ich irgendwo in eine Datei oder in einen Code reinschreiben muss, was er alles ausliefern soll.

Endet eine Datei auf ".py", dann wird diese vom Webserver an Python weiter gegeben um diese Datei zu interpretieren. So kann man ziemlich gut dynamischen und statischen Content mischen.

Genau dieses Verhalten weist auch Zope auf, deshalb arbeite ich auch extrem gerne damit.

Und jetzt zu WSGI. Jedes mal, wenn ich mir ein wenig WSGI-Code durchlese, dann lese ich etwas von irgendwelchen Klassen und von Methoden, die Daten zurück geben und alles ist eine Anwendung, aber wo bleibt die einfache Ausgabe von statischem Kontent? Was mir ebenfalls fehlt, ist die hierarchische Einteilung, etwas was einem normalen Ordner-/Dateisystem ähnelt.

Wie stelle ich mir ein erfolgreiches Web-Framework vor? Hier ein paar Stichworte:

- Einfache Ordnerstruktur nutzbar
- Jede Seite eine eigene Datei
- Trennung zwischen Vorlage und Logik
- Wenn möglich ohne Installation auf einem normalen Webserver lauffähig
- Vorlagenseiten sollen auch dann angezeigt werden können, wenn kein dynamischer Code in der Vorlage steckt.

Das was ich mir unter einem zukünfgig erfolgreichen Web-Framework vorstelle ist wahrscheinlich eine Mischung aus "Python Servlet Engine" und SimpleTal.

Das wäre mir das liebste Konzept: Wenn die Datei "index.pyt" aufgefufen wird, dann wird vorher "index.py" in den Python-Interpreter geladen und mit den daraus resultierenden "__globals__" dieses Aufrufs die Vorlage, die je nach Einstellung TAL oder ein anderes Vorlagensystem sein kann, gerendert.

Code: Alles auswählen

index.pyt --> Dynamischer Content -- Vorlage
index.py  --> Dynamischer Content -- Logik
normale_seite.html --> Statischer Content
hallo.gif --> Statischer Content
hallo_welt.pyt --> Vorlage ohne zugeh. Logikteil
Schön wäre, wenn im Hintergrund ein System laufen würde, das nicht ständig neu geladen wird und sich um Sessions, Formulardaten, Authentifizierung usw. kümmert, dann kommen wir meinem Traum-Web-Framework schon näher.

Es hat mich öfter schon mal gereizt, so etwas zu schreiben. Etwas, das wie CGI läuft und wenn man es installieren kann, im Hintergrund läuft und dem Apachen die gerenderten Daten ausliefert. Das alles verbunden mit TAL und METAL als Vorlagensprache und dem Konzept aus "Python Servlet Engine", das die Logik in eine eigene Datei auslagert. So etwas würde mir gefallen. Leider komme ich nie dazu, denn bis auf den Punkt "Lauffähig ohne Installieren" bietet mir Zope alles was ich brauche. Und nur dafür, dass ich kein Zope mehr brauche, ein Web-Framework zu programmieren, das war mir immer zu viel.

Und jetzt komme ich dazu, warum ich selten oder nie WSGI vorgeschlagen habe. --> Es war immer ein Mittelding zwischen Zope und CGI für mich. Will ich etwas kleines, das evt. auf jedem Computer laufen sollte, ohne es groß installieren zu müssen, dann bin ich mit CGI am schnellsten. Brauche ich etwas, das mir viel Arbeit durch eingebaute Authentifizierung, Vergabe und Überwachung von Zugriffsrechten, einem eingebauten Vorlagensystem, usw. abnimmt, dann muss ich jedem zu Zope raten.

Jetzt muss ich mal Pause machen. Wie sieht es mit WSGI aus? Wie ist da das Konzept? Kann ich da einzelne Seiten in Dateien auslagern oder muss alles in Klassen geschehen und in eine Gesamtanwendung importiert werden?

lg
Gerold
:-)

Verfasst: Montag 27. Februar 2006, 18:52
von Kompottkin
WSGI ist meines Wissens nicht zur direkten Verwendung durch einen Webentwickler gedacht. Der Sinn von WSGI ist es, ein standardisiertes Interface zu bieten, auf das man Webframeworks aufbauen kann.

Die Motivation dahinter ist ganz einfach: der Anwender des Webframeworks kann sich sein WSGI-Backend aussuchen. CGI, mod_python, FastCGI, ein ganz eigener Server nur für die Anwendung oder auch ein spezieller Python-Webapplikationsserver -- um diese ganzen Möglichkeiten muß sich der Webframeworkentwickler nicht mehr kümmern, weil WSGI zwischen dem Framework und dem Server vermittelt (sofern beide den Standard unterstützen). Der Anwender kann seinerseits problemlos zwischen den genannten Möglichkeiten hin- und herwechseln (beispielsweise kann er dieselbe Anwendung daheim auf seinem speziellen Python-Testserver mit Debugging und am leistungsoptimierten Firmen-Apacheserver laufen lassen).

Unterstützt wird WSGI zum Beispiel von CherryPy. Mir persönlich gefällt dieses Framework sehr, nicht nur (aber auch) als Teil von TurboGears.

Verfasst: Montag 27. Februar 2006, 19:18
von Kompottkin
Zu Deinem Wunschframework: Ich werfe mal einfach TurboGears als Vorschlag in den Raum.
- Einfache Ordnerstruktur nutzbar
Darüber kann ich leider wenig sagen. Ich schätze, das mußt Du ausprobieren.
- Jede Seite eine eigene Datei
Ich nehme an, Du meinst: jede Vorlage eine eigene Datei? Diese Voraussetzung wäre bei Kid (dem Templatingsystem, auf dem TurboGears aufbaut) wohl erfüllt.
- Trennung zwischen Vorlage und Logik
Auch hier: Punkt für Kid/CherryPy/TurboGears :)
- Wenn möglich ohne Installation auf einem normalen Webserver lauffähig
CherryPy unterstützt WSGI. Damit ist auch dieser Punkt erfüllt (denke ich). Ich habe diese Funktion allerdings noch nie ausprobiert.
- Vorlagenseiten sollen auch dann angezeigt werden können, wenn kein dynamischer Code in der Vorlage steckt.
Das ist nun endlich der Punkt, an dem Kid sich besonders hervortut (ich bin mir sicher, daß es noch weitere Frameworks gibt, die die anderen Punkte erfüllen). Da jedes Kid-Template gültiges XHTML ist, kann ein XHTML-fähiger Browser Kid-Templates als solche problemlos auch ganz ohne Server anzeigen. Recht praktisch, wenn man sich nicht um den Inhalt kümmert und erst mal das Layout hinkriegen will.

(Beachte aber, daß Kid-Templates zwar immer gültiges XML sein müssen, die Ausgabe des Webservers dieser Einschränkung jedoch nicht unterliegt! Man kann mit Kid durchaus reine Textdateien erzeugen. Es reicht bei TurboGears sogar, ein bestimmtes Flag zu setzen, und schon ist das Ergebnis nicht mehr XHTML, sondern HTML 4.)

Conclusio: TurboGears ist einen Blick wert :D

Es gibt allerdings noch eine ganze Reihe weiterer Webframeworks. Ich frage mich, was die anderen hier bevorzugen.

Verfasst: Dienstag 28. Februar 2006, 05:15
von mitsuhiko
Ich nutze django, der Kern ist WSGI und der Aufbau ist genial.

@TG: Cherrypy nutzt auch WSGI, ihr habt die Funktion schon verwendet ^^, aber CP hat einen kleinen Bug in der Implementierung, was es unmöglich macht das ganze aktuell in Paste laufen zu machen.

Und was colubrid angeht, worauf du dich möglicherweise referenzierst:

Code: Alles auswählen

from colubrid import RegexApplication

class MyWebpage(RegexApplication):
    urls = [
        r('^$', 'pages.index.display'),
        r('^downloads/$', 'pages.download.display'),
        r('^downloads/(\d+)/$', 'pages.download.display')
    ]
    append_slash = True

app = MyWebpage

if __name__ == '__main__':
    execute()
Im "pages" ordner liegt dann beispielsweise die datei "download":

Code: Alles auswählen

def display(req, download=None):
    if download is None:
        req.write('Download Index')
    else:
        req.write('Download %s' % download)

Verfasst: Dienstag 28. Februar 2006, 09:43
von gerold
Hi blackbird!
blackbird hat geschrieben:Und was colubrid angeht, worauf du dich möglicherweise referenzierst:
Stimmt :-)
blackbird hat geschrieben:

Code: Alles auswählen

        r('^downloads/(\d+)/$', 'pages.download.display')
[...]
Im "pages" ordner liegt dann beispielsweise die datei "download":
Wie ich das sehe, könnte man also in jedem Ordner eine "Handler"-Datei haben, die sich um die Logik kümmert und je nach URL eine der Vorlagen im Ordner aufruft.

Code: Alles auswählen

        r('^kontakt/(\d+)/$', 'kontakt.handlermodul.handler')

Code: Alles auswählen

# -*- coding: utf-8 -*-
from simpletal import simpleTAL, simpleTALES 

def handler(request, urldata = None):
    if not(urldata):
        f = file("index.tal", "r")
    else:
        f = file(je_nach_urldata, "r")
    ...
    context.addGlobal("main_template", main_template_path) 
    request.write(...)
Sehe ich das richtig? Könnte man so etwas machen? Wenn ja, dann wäre das die Ordnerstruktur, die mir so wichtig ist. Man könnte in der Handler-Funktion auch im Ordner nachsehen ob eine angeforderte Datei existiert und wenn diese die Endung "html" hat, diese ohne interpretieren zurück liefern.

Wird das aufgerufene Modul wie gewohnt *importiert* oder wird es auf besondere Art aufgerufen? Verweist z.B. *__file__* auf das aufgerufene Modul selbst oder muss man dabei etwas besonderes beachten?

Kann man auch globale Variablen hinterlegen, um z.B. den Pfad zu einer Hauptvorlage bereit zu halten?

Sehe ich das alles richtig, dann könnte man auch so etwas wie die Acquisition von Zope realisieren, so dass z.B. die Hauptvorlage zuerst im aktuellen Ordner gesucht wird. Wird diese im aktuellen Ordner nicht gefunden, dann wird im Elternordner gesucht. So lange, bis man im Ordner des Hauptprogrammes angelangt ist oder die Datei gefunden hat.

lg
Gerold
:-)

Verfasst: Dienstag 28. Februar 2006, 09:56
von jens
gerold hat geschrieben:
blackbird hat geschrieben:

Code: Alles auswählen

        r('^downloads/(\d+)/$', 'pages.download.display')
Wie ich das sehe, könnte man also in jedem Ordner eine "Handler"-Datei haben, die sich um die Logik kümmert und je nach URL eine der Vorlagen im Ordner aufruft.
Das ist eine Art, wie die Programmlogik gehandelt wird.

Eine andere wäre die http://wiki.python.de/Colubrid/ObjectApplication
Dabei muß man nicht mit re-URLs arbeiten.

Verfasst: Dienstag 28. Februar 2006, 10:06
von gerold
jens hat geschrieben:Eine andere wäre die http://wiki.python.de/Colubrid/ObjectApplication
Dabei muß man nicht mit re-URLs arbeiten.
Hi Jens!

Nichts für ungut, aber genau das ist das Beispiel das mich abgeschreckt hat.

lg
Gerold
:-)

Verfasst: Dienstag 28. Februar 2006, 10:21
von jens
:P

Ja, das Beispiel sieht recht komplex aus, ist es aber nicht wirklich! Ich hab es nochmal mit ein paar DocString versehen, ich hoffe so wird schneller klar, wie eine ObjectApplication funktioniert: http://wiki.python.de/Colubrid/ObjectApplication

Ergänzent dazu: http://wsgiarea.pocoo.org/colubrid/docu ... pplication

Verfasst: Dienstag 4. Juli 2006, 12:30
von keppla
Sehe ich das richtig? Könnte man so etwas machen? Wenn ja, dann wäre das die Ordnerstruktur, die mir so wichtig ist. Man könnte in der Handler-Funktion auch im Ordner nachsehen ob eine angeforderte Datei existiert und wenn diese die Endung "html" hat, diese ohne interpretieren zurück liefern.
Ich weis nicht, ob es das ist, was du suchst, aber bei django kann man soetwas z.B. dadurch erzielen, dass z.B. du apache Direktiven á la

Code: Alles auswählen

<LocationMatch "\.html$">
SetHandler None
</LocationMatch>

<Location "/mystaticdir">
SetHandler None
</Location>
gibts. (Keine Gewähr für Korrektheit des Apachekrams)

Man kann in Django auch ein statisches Verzeichnis oder Datei auf irgendeiner regexp verfügbar machen, die sagen aber dazu, dass das eine Notlösung ist, und dass für sowas eigentlich Apache&co zuständig sind