Verlaufen auf dem Weg zu WSGI

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Freitag 22. September 2006, 23:28

Hallo,

nun habe ich mich nach einigen Jahren doch mal hier im Forum angemeldet :)

Ich stehe ein wenig wie der Ochs' vor'm Berg beim Thema WSGI. In schätzungsweise den letzten zwölf Monaten habe ich vielerorts vom WSGI-Boom mitbekommen, bin aber bis heute nicht *exakt* dahinter gekommen.

Ich habe die PEP, das Python.de-Wiki und vieles mehr gelesen und mir auch diverse Pakete zu WSGI angesehen, so etwa wsgiref, Jason, Paste, Colubrid, flup, yaro, selector und noch so einige mehr, die mir gerade nicht einfallen.

Bisher habe ich intensiv mit Python über CGI gearbeitet und mich von vielen der zahlreichen Web-Frameworks inspirieren lassen und Ideen übernommen. Vor nicht all zu langer Zeit sind auch kleinere Sachen mit CherryPy hinzugekommen. Da ich seit einigen Wochen endlich einen eigenen Server habe, auf dem ich keinen nervigen Restriktionen wie uralten Python-Versionen (gruß an Host Europe...), fehlender Shell oder eben auch der Beschränkung auf CGI unterliege. Deshalb möchte ich jetzt die Gelegenheit nutzen und auf WSGI migrieren.

Mein Problem ist, dass ich einfach noch nicht in der Lage war, den "Verlaufspfad" vor meinem inneren Auge zu visualisieren und die genannten Pakete in Teilbereiche einzuordnen.

Wie genau kommen die Daten denn dann vom Webserver zur Applikation? Ruft dieser ein Python-Script auf? Oder läuft *immer* ein Script, das selbst ein Webserver ist? Wie sieht bspw. der Weg über Apache aus (ohne mod_python)?

Letztlich will ich nicht den gesamten Code meiner Applikation und insbesondere deren Teilmodulen ändern. Ich benutze in etwa einen MVC-Aufbau, wie CherryPy ihn anbietet, d.h. pro Controller-Modul eine Klasse mit mehreren Methoden, die den Actions entsprechen. Ich möchte folglich zentral wie bisher Daten wie eben dem Query-String, den POST-Parametern und den Umgebungsvariablen (bisher os.environ) erhalten und die dann an mein System weitergeben (also quasi eine eigene, für mein System geschriebene, kleine WSGI-Middleware?).

Ist mein Problem verständlich? Könnt ihr diese Lücken schließen? Vielen Dank im Voraus!
Benutzeravatar
jens
Moderator
Beiträge: 8481
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Samstag 23. September 2006, 10:52

Den Ärger mit den Provider kann ich gut nachvollziehen. Deswegen hab ich u.a. die Wikiseite [wiki]Python Webspace[/wiki] geschrieben :)

Leider gibt es nicht so viel (deutsche) Doku zum Thema [wiki]WSGI[/wiki] :(

Noch eine WSGI Implementierung würde ich allerdings nicht anfangen. Ich denke am besten eignet sich vielleicht das Mini-"Framework" [wiki]Colubrid[/wiki] für dich. In Kombination mit wsgiref kann man so recht einfach WSGI-Apps als CGI ausführen lassen.

Der einfachste Weg wäre vielleicht dir das [wiki]Colubrid/Hello World[/wiki] mal lokal aus zu Probieren und damit zu starten...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Samstag 23. September 2006, 12:10

Danke für deine Antwort.

An wsgiref.simple_server stört mich ein wenig dieser Satz:
It has not been reviewed for security issues, however, and we strongly recommend that you use a "real" web server for production use.
Das "Test" in "Test-Server" bei Colubrid hört sich auch nicht besser an. Was tun, welchen nehmen?

Was ich eben *nicht* machen möchte, ist meinen Code wie das Beispiel HelloWorld_app.py aufbauen. Ich benutze auch keine Request- und Response-Objekte und greife nur sporatisch auf os.environ zu. Auch will ich meine Controller-Klassen von nichts abeiten, also mir möglichst viel Abstraktion und Flexibilität erhalten. Letztlich muss ich doch nur irgendwie das environ-dict von WSGI in meine Applikation hineinbekommen, oder?

Hier ein Beispiel von selector:

Code: Alles auswählen

def say_hello(environ, start_response):
    start_response("200 OK", [('Content-type', 'text/plain')])
    return ["Hello %s!" %environ['selector.vars']['name']]
    
from selector import Selector

s = Selector()
s.add('/myapp/hello/{name}', GET=say_hello)

from flup.server.scgi import WSGIServer
WSGIServer(s).run()
Über Funktionen mit den Argumenten environ und start_response bin ich des öfteren gestolpert, auch die ganze obige Funktion ist mir glaube ich schon anderswo begegnet.
Kleiner Exkurs: Das URL-Mapping gefällt mir wohl. Bisher habe ich sowohl mod_rewrite (wohl durch die Apache-Abhängigkeit und die zentrale Definition aller regeln etwas zu unflexibel) und Routes verwendet. Paste besitzt auch einen URL-Dispatcher. Was bei selector allerdings noch nicht zu meiner Anwendung passt, ist, dass stets die zwei Argumente übergeben werden, die meine Methoden aber gar nicht empfangen sollen, sondern die möchte ich zentral erhalten und dann selbst weitergeben.

Weiterhin ist mir untergekommen, dass WSGI-Objekte Iteratoren zurückliefern und __call__ für den aufruf wie eine Funktion implementieren sollen. Was genau hat es damit auf sich? Das scheint auch der Punkt zu sein, an dem ich ansetzen würde.

Edit: Ist das, was ich machen will, nun eine WSGI-Middleware? Muss ich dazu so etwas wie das LatinIter/Latinator-Beispiel in PEP 333 schreiben? Kann mir wohl jemand davon ein vereinfachtes Beispiel geben?

Edit (Leonidas): Code-Tags in Python-Tags geändert.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 23. September 2006, 15:06

Ohne auf deine Fragen genauer einzugehen habe ich deine Anmerkung zu CherryPy gelesen. Es gibt ein anderes, von CherryPy inspiriertes Framework, RhubarbTart welches dich vielleicht interessieren könnte.

Die wsgiref-Bemerkung mit dem "real server" kannst du befolgen indem du die WSGI-Server von flup verwendest. Mit flups FastCGI-Server binde ich über WSGI Django in Apache und Lighttpd ein.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Samstag 23. September 2006, 15:16

Y0Gi hat geschrieben:An wsgiref.simple_server stört mich ein wenig dieser Satz:
It has not been reviewed for security issues, however, and we strongly recommend that you use a "real" web server for production use.
Das "Test" in "Test-Server" bei Colubrid hört sich auch nicht besser an. Was tun, welchen nehmen?
flup. Die Standalone Server sind nur für Entwicklungszwecke. Das Gateway tauscht man auf richtigen Installationen dann gegen flup oder python-fastcgi aus.
TUFKAB – the user formerly known as blackbird
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Samstag 23. September 2006, 15:58

Danke, dann werde ich zunächst mal flup für CGI probieren. Sehe ich das richtig, dass meine Anwendung, wenn ich sie denn WSGI-kompatibel habe, sich dann zum testen lokal ohne separaten Webserver starten lässt?
Leonidas hat geschrieben:Ohne auf deine Fragen genauer einzugehen habe ich deine Anmerkung zu CherryPy gelesen. Es gibt ein anderes, von CherryPy inspiriertes Framework, RhubarbTart welches dich vielleicht interessieren könnte.
Da bin ich auch schon drüber gestolpert. Allerdings geht es mir weniger um eine Alternative zu CherryPy, sondern insgesamt wohl darum, mein eigenes, kleines Web-Framework (bah, dieses Wort ist so over-used in letzter Zeit...) auf WSGI aufzusetzen.

Bzgl. Middleware und des Latin-Dings-Beispiels, könnt ihr mir da noch weiterhelfen?
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Sonntag 24. September 2006, 17:50

Heute habe ich das Posting WSGI and WSGI Middleware is Easy von Ben Bangert wiederentdeckt und es hat mir wahrlich sehr geholfen. Eine sehr kleine Site habe ich bereits lokal mit wsgiref als Server (Gateway) und yaro mit weniger als zehn Zeilen WSGI-fähig gemacht.

Um auch statische Dateien liefern zu können, habe ich nach erfolglosem Test von 'static' (wie yaro auch von Luke Arno) dann die StaticExports-Klasse aus Colubrid verwendet.
Auch den Blogeintrag von blackbird zum Problem mit statischen Dateien habe ich gelesen; ich denke, parallel zur Einrichtung eines WSGI-Gateways muss man entsprechend auch die Auslieferung der statischen Dateien konfigurieren (in meinem Fall wäre das zunächst weiterhin mod_rewrite via .htaccess).

Auch die Idee hinter der Middleware ist mir nun klar: Es wird einfach ein Wrapper um die Applikations-Methode gesetzt, der dann so Dinge wie Sessions, Authentifizierung, Fehlerbehandlung/-reporting oder Komprimierung (sollten alle u.a. in Paste enthalten sein) hinzufügt. Klasse, so kann man etwa (so meine aktuelle Annahme) unabhängig vom Framework Sessions verwenden. Das sollte die Portierbarkeit nochmal deutlich erhöhen.

Vor etwa einer Woche hat Ben übrigens eine interessante Präsentation zum Thema veröffentlicht: Google TechTalk on WSGI, Middleware, Paste, and Pylons
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Freitag 29. September 2006, 19:04

Neue Frage: Ich möchte WSGI benutzen, aber nicht über CGI. flup bietet ja zahlreiche Gateways, aber welches System ist empfehlenswert? Extra mod_python halte ich für zu überdimensioniert. mod_scgi scheint ein kleines Nischenprodukt zu sein. FastCGI habe ich auch noch nicht benutzt, aber wie schaut es da mit der aktuellen Weiterentwicklung aus? Eine Bindung an Apache würde ich schon bevorzugen und mein App nicht als eigenen App-Server wie CherryPy betreiben wollen.

Außerdem: Was muss ich beachten, damit ich keine Threading-Probleme bekomme? Wo könnten sich da Probleme beim gemeinsamen Zugriff auftun? Und wie kann ich optimal Dinge wie das Laden von Daten aus statischen Dateien nur einmal beim Starten der Applikation ausführen und den Kram dauerhaft im Speicher halten lassen?
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 29. September 2006, 19:44

Y0Gi hat geschrieben:Ich möchte WSGI benutzen, aber nicht über CGI. flup bietet ja zahlreiche Gateways, aber welches System ist empfehlenswert? Extra mod_python halte ich für zu überdimensioniert. mod_scgi scheint ein kleines Nischenprodukt zu sein. FastCGI habe ich auch noch nicht benutzt, aber wie schaut es da mit der aktuellen Weiterentwicklung aus?
Nein, eigentlich steht das FastCGI-Protokoll fest und daran wird nicht mehr gerüttelt, daher sind Änderungen mehr oder weniger unnötig. Nötig sind dagegen ab und zu Bugfixes, die mod_fastcgi nicht mehr bietet, mod_fcgid dagegen schon. Und Lighttpd bringt seine eigene Implementation von FastCGI ab Werk mit. Daher würde ich dir zu FastCGI raten, welches ich zum Anbinden von Django über flup benutze.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Freitag 29. September 2006, 20:29

Da habe ich mich vielleicht unklar ausgedrückt. Ich meinte nicht die Weiterentwicklung der Spezifikation selbst, sondern eben der Module, was du ja auch schon angesprochen hast. Also ist mod_fcgid state-of-the-art und auch gängig?

LigHTTPd werde ich mir unter diesem Aspekt nochmal genauer ansehen. Momentan fahre ich den Indianer v2.0 für mehrere Sites, die teilweise auch (noch) mod_rewrite erfordern. Macht es Sinn, beide parallel zu betreiben und wenn ja, wie krieg ich bswp. den LigHTTPd auf etwa Port 8000 dazu, vom Apache als domain.com:80 verkauft zu werden (auch wenn das hier etwas vom Thema abweicht)?
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 29. September 2006, 20:55

Y0Gi hat geschrieben:Da habe ich mich vielleicht unklar ausgedrückt. Ich meinte nicht die Weiterentwicklung der Spezifikation selbst, sondern eben der Module, was du ja auch schon angesprochen hast. Also ist mod_fcgid state-of-the-art und auch gängig?
mod_fcgid soll viele Drawbacks von FastCGI ausbügeln. Aber so wie blackbird meinte keine Probleme mit mod_fastcgi zu haben, genauso habe ich mit mod_fcgid keinerlei Probleme. Das schöne an mod_fcgid ist, dass es zu mod_fastcgi kompatibel ist, somit kann man die FastCGI-Dokumentation meist 1:1 übernehmen.
Was die Gängigkeit angeht: mod_fcgid ist in Debian als libapache2-mod-fcgid verfügbar (und zwar in main, wohingegen libapache2-mod-fastcgi in non-free ist) daher ist anzunehmen dass es durchaus auch produktiv verwendet werden kann.
Y0Gi hat geschrieben:LigHTTPd werde ich mir unter diesem Aspekt nochmal genauer ansehen. Momentan fahre ich den Indianer v2.0 für mehrere Sites, die teilweise auch (noch) mod_rewrite erfordern. Macht es Sinn, beide parallel zu betreiben
Nein, ich denke nicht dass es Sinn macht. Denn das was Lighttpd bietet das tut Apache 2 auch. Vielleicht nicht immer genauso schnell, aber er erledigt seine Arbeit genauso gut.
Y0Gi hat geschrieben:und wenn ja, wie krieg ich bswp. den LigHTTPd auf etwa Port 8000 dazu, vom Apache als domain.com:80 verkauft zu werden (auch wenn das hier etwas vom Thema abweicht)?
Wenn du alle Anfragen an Port 80 an Lighttpd weiterreichst, warum lässt du ihn nicht gleich auf Port 80 laufen?
Aber um deine Frage richtig zu beantworten: dieses Umleiten erreichst du mit mod_rewrite, in dem du die CherryPy Anleitung zu diesem Thema befolgst. In der Tat ist es mit Lighty in dieser hinsicht absolut analog, nur dass du statt dem CherryPy-Server einen Lighttpd auf dem Port hast. Mit den Zeilen

Code: Alles auswählen

RewriteEngine on
RewriteRule ^(.*) http://127.0.0.1:8000/$1 [P]
sollte die Sache erledigt sein.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Freitag 29. September 2006, 21:26

Danke soweit. Es ging mir darum , zumindest übergangsweise beide parallel (dabei den LigHTTPd hinter dem Apache) zu betreiben.
digaf
User
Beiträge: 1
Registriert: Mittwoch 1. November 2006, 07:52

Mittwoch 1. November 2006, 10:59

Hallo,

ich möchte die wscgi application pylons benutzen. Sonst sollte auch der Rest Python basiert sein.

Zur Verfügung, ein SUN Apache Webserver, jedoch keine Chance auf fastcgi oder ähnliches, kein Zugang auf httpd.conf des Webservers, sondern nur mein eigenes .htaccess und ein Login auf einen "loginserver" der im Filesystem mit dem Webserver gemounted ist.

Dort nur cgi. Dort habe ich für mich auch Python installiert.

Meine Frage, kann man z.B. über cgi2scgi.py o.Ä. als cgi Application auf dem Webserver irgendwie pylons auf einem anderen Rechner nutzen? Und zwar so, daß der Flaschenhals cgi nicht wirksam wird, sondern die persistenten Daten auf dem anderen Rechner (z.B. einem Windows PC) stehen und nicht bei jedem cgi Zugriff das ganze Environment neu aufgebaut wird.

Sozusagen einen virtuellen Host aus Sicht von Apache ohne leider die dort unter Apache verfügbaren Mechanismen, sondern nur cgi.

(Die Testlösung mit cgi direkt und Pylons ist erstens unakzeptabel langsam und zweitens nur in Teilbereichen funktionsfähig). Mit dem zu Pylons gehörenden Webserver läuft die Applikation bestens und performant, nur kann der Webserver nur von der lokalen Domäne erreicht werden.

Es wäre prima, wenn ich hier weiterkäme.
Antworten