Erfahrungsbericht: CherryPy und Cheetah

Gute Links und Tutorials könnt ihr hier posten.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo!

Zwei neue Kapitel sind dazu gekommen:

- Was wird von CherryPy bei welchem URL ausgeliefert?
- Bilder und andere statische Dateien

http://halvar.at/python/cherrypy_cheetah/

lg
Gerold
:-)

Edit: Links ausgebessert
Zuletzt geändert von gerold am Dienstag 4. Dezember 2007, 20:46, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Leonidas hat geschrieben:Richtig, deswegen muss man auch den Referer prüfen, ob der POST auch von "deiner" seite kommt und nicht von wo anders. Aber wenn wir das Beispiel von fme nehmen, dann kann dem User kein POST aus einem Link im Profil untergeschoben werden. Und wenn daten per POST kommen, muss man eben Referer prüfen.
Hm das schlechte am Referer prüfen ist das es idiotische "Fi0rW4llz" und ähnliches gibt welche den Referer einfach löschen. Da Frage ich mich ernsthaft warum sie nicht überprüfen ob Referer != Host und ihn nur dann löschen. Wobei ich für mich persönlich denke das jeder der sowas Benutzt selber schuld ist und man ihn ruhig darauf aufmerksam machen soll. Kunden sind da oft anderer Meinung.
Gerold hat geschrieben: Ich halte nicht sehr viel von der Trennung zwischen GET und POST.
GET und POST sind zwei verschiedene Dinge, wieso sollte man sie gleich behandeln? Eine GET Anfrage sollte zum Beispiel keine Nebeneffekte haben.
thelittlebug hat geschrieben:Bei Browsergames ist es sehr beliebt in den Foren oder im IRC mal Nachrichten wie die hier loszulassen: Hier eine Möglichkeit zu cheaten, klicke einfach auf http://www.unsertollesbrowsergame.de/us ... ion=delete
Das schlimme dabei, es geht bei 95% der Browsergames
Die noch böseren Jungs hängen so etwas wie

Code: Alles auswählen

[img]http://example.com/account.php?action=delete[/img]
in ihre Foren Signatur oder Interne Messages ;)

Zu Seiten die so verwundbar waren Zählen (laut Wikipedia) unter anderem Amazon, Google AdWords, und natürlich Digg (Die sich selbst Diggende Story ;) )
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

veers hat geschrieben:GET und POST sind zwei verschiedene Dinge, wieso sollte man sie gleich behandeln? Eine GET Anfrage sollte zum Beispiel keine Nebeneffekte haben.
Hallo veers!

GET und POST sind nur zwei Methoden, innerhalb des HTTP-Protokolls, mit denen Daten über das HTTP-Protokoll zum Server übertragen werden. Das Ergebnis sind Daten, die dem Server bekannt gegeben wurden. Warum soll ich mich als einfacher Webprogrammierer darum kümmern müssen, und unterscheiden, ob die Daten per GET oder per POST an mich gesendet wurden? Mir ist es ja auch egal, ob ich eine Datei per HTTP oder per FTP herunter lade. Wichtig ist im Endeffekt nur, dass ich die Datei danach zur Verfügung habe.

Also ganz habe ich es noch nicht verstanden, warum ich zwischen GET und POST unterscheiden sollte.

Ob ich jetzt als böser Junge den URL

Code: Alles auswählen

http://example.com/account.php?action=delete
verbreite, oder einen URL, der auf eine Seite zeigt, die automatisch per JavaScript ein "Submit" eines Formulars auslöst, macht doch fast keinen Unterschied mehr, oder doch? Da finde ich GET sogar noch besser, da man hier schon am URL erkennt, dass etwas passiert, was ich evt. nicht will.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

gerold hat geschrieben:Also ganz habe ich es noch nicht verstanden, warum ich zwischen GET und POST unterscheiden sollte.
Ich bin der Meinung man muß bei einem Client-Request nicht zwischen GET und POST auf dem Server unterscheiden. Da sehe ich eigentlich keine Notwendigkeit.

Allerdings sollte man bei Navigation/Formulare gezielt POST oder GET benutzten. Aktionen, die irgendwelche Daten verändern, sollten IMHO niemals mit GET dem Client angeboten werden. Wobei das manchmal viel einfacher zu Programmieren ist, weil man kein HTML-Formular bauen muß, sondern einfach nur ein Link anbieten muß.

Der User sollte aber IMHO jede URL gefahrlos als Bookmark speichern können.

Mit djangos URL Mapper sind GET Geschichten eh in der Ursprünglichen Form ausgestorben. Dort wird die URL ...?view=123 z.B. zu .../view/123/ oder .../view/123.html
Das sieht auch hübscher aus ;)

Siehe auch http://www.w3.org/Provider/Style/URI

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

jens hat geschrieben:Allerdings sollte man bei Navigation/Formulare gezielt POST oder GET benutzten.
Hallo!

- Navigationslinks mit GET
- Formulare mit POST
- Serverseitig keine Unterscheidung

Das ist genau meine Meinung.

Falls jetzt jemand nicht weiß, was ich mit Navigationslinks meine:

Code: Alles auswählen

<a href="http://example.com/artikelliste.html?from_id=100&to_id=199">Next 100 Articles</a>
EDIT:
@veers:

Nach langem Nachdenken: :-) Das Verhindern von solchen URLs:

Code: Alles auswählen

http://example.com/account.php?action=delete
könnte den Vorteil bringen, dass diejenigen, die nichts von GET und POST wissen, nicht so viel Schaden anrichten können. Wobei ich glaube, dass man jegliche Änderung auf einer Website nur dann zulassen sollte, wenn der Benutzer authentifiziert ist.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

POST sollte man für alles verwenden, was Daten auf dem Server ändert - Ausnahmen können Logfile-Einträge, Sessions und Zugriffsstatistiken sein.

Nicht ohne Grund fragen Browser auch nach, ob man bei einem erneuten Laden einer Seite die Daten auch erneut absenden möchte.

Ein Schutz ist das dennoch nicht. Templates und Controller sollte man aber schon so gestalten, dass Erstgenanntes berücksichtigt wird. Über RESTful Dispatching oder (etwas unschöner) über einfache Abfrage von REQUEST_METHOD lässt sich das auch forcieren.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

gerold hat geschrieben: Genshi war ziemlich weit oben in meiner Rangliste. Ich konnte mich nur nicht in die Umgekehrte Reihenfolge der Code-Wiederverwendung eindenken. Mit TAL/METAL ruft man von jeder TAL-Seite aus das Makro der Hauptseite auf und füllt "Slots" mit den geänderten Daten. Bei Genshi scheint es genau umgekehrt zu funktionieren. Man arbeitet ständig mit der Hauptvorlage und ändert die Incluces je nach anzuzeigender Seite. Zumindest wurde es mir in den paar Stunden, die ich Genshi gewidmet hatte, so vermittelt.

Ich habe auf die Schnelle kein gutes Beispiel gefunden und da es sich, wie oben schon erwähnt, (für mich) ungewohnt anfühlte, habe ich es nicht mehr weiter bedacht. Dann kommt noch dazu, dass ich mindestens schon fünf Designern/Grafikern/Freunden TAL/METAL beibringen wollt und nicht ein einziger ist mir darauf eingestiegen. (mir wäre es mit Genshi wohl kaum besser ergangen) Nur ein Kollege von mir (ein Administrator) kommt damit klar. Er hilft mir jetzt öfter mal bei Zope-Websites. Als ich letztens einem meiner Kollegen Cheetah zeigte, war alles nach ein paar Minuten klar. Sogar ``#for`` und ``#if`` wurde sofort verstanden. Ich musste nichts erklären. Es erklärte sich (fast) alles von selbst. Das ist wahrscheinlich der Grund dafür gewesen, warum ich bei Cheetah geblieben bin.
Was Include-Mechanismen oder Macros angeht bin ich persönlich mit dem TAL/TALES/METAL-Gespann (genutzt über das SimpleTAL-Paket) ins Straucheln gekommen und konnte mich nicht einfach in die Möglichkeiten der Wiederverwendung hineindenken. Dass sowas anderen nicht einfach beizubringen ist, kann ich mir gut vorstellen.

Mit dem Genshi-inspirierenden Kid erging es mir nicht besser, im Gegenteil. Auch der Umstieg von Kid auf Genshi erforderte wieder etwas Grübelei - allerdings haben die Migration-Docs das start vereinfacht.

Letztlich ist der wohl gängigste Ansatz mit Genshi, so nehme ich an, der, dass man in den Templates der einzelnen Seiten die spezifischen Inhalte wie Titel oder Body als Funktionen über py:def festlegt. Am Ende wird dann das Layout-Template per XInclude eingebunden, in welchem diese Funktionen aufgerufen werden.
Das scheint nicht der einzige mögliche Weg zu sein und auch in meinen Augen auch irgendwie nicht der "rundeste". Nach mehreren Experimenten zu alternativen, noch geradliniegeren(?) Vorgehen bin ich aber dabei geblieben. Und spätestens wenn man eine einfache Vorlage für die einzelnen Seitentemplates geschaffen hat und diese nur kopiert, kommt man damit auch gar nicht mehr in Kontakt.

Umgekehrt kann man wiederverwendbare Elemente (ebenfalls über Funktionen oder aber py:match) in einem separaten Template definieren, das allerdings im Template einer spezifischen Seite *oben* auf dem selben Wege einbinden und dann die vordefinierten Funktionen dort aufrufen.


Bei Text-Template-Engines wie Cheetah eine ist stört mich nachwievor, dass man if-Konstrukte je nach Fall auch schon mal doppelt ausführen muss, je nachdem ob man für etwas umschließende Tags ein-/ausblenden möchte oder nicht. Und das bedeutet für mich klar erschwerte Wartbarkeit und Lesbarkeit. Da haben Attribut-basierte Template-Sprachen natürlich die Nase vorn, während sie woanders Grenzen haben. Aber gut, da brauchen wir nicht wieder die Diskussion lostreten.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

gerold hat geschrieben:Wobei ich glaube, dass man jegliche Änderung auf einer Website nur dann zulassen sollte, wenn der Benutzer authentifiziert ist.
Das ist ja gerade das Problem beim CSRF, du bist authentifiziert, und ich bin in der Lage von aussehn Befehle im Scope deiner Session auszuführen.

Und wieso man unterscheiden sollte:
Ein weiterer Grund sind Prefetcher, die Laden einfach mal alles herunter was per GET erreichbar ist um das Browser schneller zu machen. Fasterfox macht sowas z.bsp.
Schlussendlich, ich machs so weil es der Standard so vorsieht. Ob das einen Webentwickler nun Interessieren sollte oder nicht ist eine andere Frage. Ich persönlich denke ja. Viele andere Leute anscheinend nein. Die Frage erinnert mich etwas an die Diskussion zu Validem HTML und zur verwendung von CSS.
gerold hat geschrieben:Da finde ich GET sogar noch besser, da man hier schon am URL erkennt, dass etwas passiert, was ich evt. nicht will.
Redirect ;)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

veers hat geschrieben:
gerold hat geschrieben:Da finde ich GET sogar noch besser, da man hier schon am URL erkennt, dass etwas passiert, was ich evt. nicht will.
Redirect ;)
Erwischt! :twisted:
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Zuletzt geändert von gerold am Dienstag 4. Dezember 2007, 20:47, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
snatch
User
Beiträge: 25
Registriert: Sonntag 20. August 2006, 01:49

Hallo Gerold,
dein Tutorial ist wirklich gut und ich habe dadurch wieder einiges gelernt.
Trotzdem habe ich noch ein paar Fragen.

In der INI Datei hast du reale Ordner für css und images festgelegt. Das ist logisch, aber was ist mit Ordnern wie "my1stsubdir" o. "my2ndsubdir"?
Ich habe es bisher nämlich so verstanden das die Ordnerstruktur aus der URL auf Klassen und Funktionen zurück zu führen ist und nicht auf reale Ordner.
Ist es in dem Fall möglich über die URL auf diese realen Ordner zuzugreifen oder passiert das gar nicht über die URL?
Wie und wofür nutzt du die realen Ordner?

Meine zweite Frage ist, wie und ob es möglich ist CherryPy hinter einem Apache oder Lighttpd Server zu nutzen?
Die Frage stellt sich mir weil CherryPy ja wie aus deinem Tutorial zu entnehemen ist einen eigenen Server auf macht.

Du hast bisher immer alle Klassen in einer Datei dargestellt. Natürlich ist es in einem Tutorial einfacher für die Darstellung oder ist das so Standart bei CherryPy das alles in einer Datei gespeichert wird?

mfg snatch
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo snatch!
snatch hat geschrieben:In der INI Datei hast du reale Ordner für css und images festgelegt. Das ist logisch, aber was ist mit Ordnern wie "my1stsubdir" o. "my2ndsubdir"? Ich habe es bisher nämlich so verstanden das die Ordnerstruktur aus der URL auf Klassen und Funktionen zurück zu führen ist und nicht auf reale Ordner. Ist es in dem Fall möglich über die URL auf diese realen Ordner zuzugreifen oder passiert das gar nicht über die URL?
Wie und wofür nutzt du die realen Ordner?
Wenn ich z.B. Bilder in einer HTML-Seite verwende, die nur in diese eine Seite gehören, dann speichere ich die Bilder dieser HTML-Seite in den gleichen Ordner, in dem auch die HTML-Seite gespeichert ist. Ich habe mir angewöhnt, den meisten HTML-Seiten einen eigenen Ordner im Dateisystem zu gönnen. So habe ich immer eine abgeschlossene Einheit für sich. Eine HTML-Seite mit allen zugehörigen Bildern. Will ich diese Seite los werden, dann lösche ich diesen Ordner mit all seinen Bildern. Möchte ich die HTML-Seite unter einem anderen URL zur Verfügung stellen, dann verschiebe ich den Ordner mit all seinen Bildern.

Genau diese, schon vielfach bewährte Arbeitsweise will ich mir nicht durch einen Web-Applikationsserver durcheinander bringen lassen. Natürlich ist CherryPy so ausgelegt, dass es den URL aus dem Tree -- den Klassen und Methoden unterhalb des Root-Objekts -- zusammensetzt. Aber auch dann, wenn ich in CherryPy eine Methode habe, die für z.B. die Kontaktseite zuständig ist, dann wird es bei mir im Dateisystem immer auch einen logisch zugehörigen Ordner geben, in dem alle Bilder für diese Kontaktseite gespeichert sind.

Dann gibt es noch einen Grund für die realen Ordner im Dateisystem. In meinem Erfahrungsbericht arbeite ich mit Cheetah-Templates. Und ich habe die CherryPy-Anwendung so umgeschrieben, dass immer dann wenn zu einem URL keine zugehörige Methode gefunden werden kann, die Anwendung im zum URL gehörenden Ordner im Dateisystem nach einer Cheetah-Template sucht und diese anzeigt.
So ist es möglich, den größten Teil der Website aus einzelnen Cheetah-Templates zu erstellen, ohne auch nur eine einzige Zeile Code der CherryPy-Anwendung ändern zu müssen. Man erstellt einfach einen neuen Ordner und legt dort die Cheetah-Templates und die Bilder rein. Fertig!
snatch hat geschrieben:wie und ob es möglich ist CherryPy hinter einem Apache oder Lighttpd Server zu nutzen?
CherryPy basiert auf WSGI und das ist ein Standard der es ermöglicht, die Anwendung entweder als eigenständigen Server oder auch hinter einem Apachen oder Lighttpd laufen zu lassen.
- http://www.cherrypy.org/wiki/WSGI
- http://projects.amor.org/misc/wiki/ModPythonGateway
- http://code.google.com/p/modwsgi/wiki/I ... thCherryPy
snatch hat geschrieben:Du hast bisher immer alle Klassen in einer Datei dargestellt. Natürlich ist es in einem Tutorial einfacher für die Darstellung oder ist das so Standart bei CherryPy das alles in einer Datei gespeichert wird?
Mehrere Dateien zu benutzen, bringt nur dann einen Vorteil, wenn du mit anderen Python-Modulen interagieren musst. Wenn das nicht der Fall ist, dann verkompliziert jede zusätzliche Datei dein Programm ohne weiteren Zusatznutzen.
Jede Klasse einfach so in eine eigene Datei zu speichern bringt keine Vorteile. Also mache ich es auch nicht. Es ist in Python nicht üblich, Programme komplizierter zu machen als sie sein müssten. ;-)

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gerold hat geschrieben:
snatch hat geschrieben:wie und ob es möglich ist CherryPy hinter einem Apache oder Lighttpd Server zu nutzen?
CherryPy basiert auf WSGI und das ist ein Standard der es ermöglicht, die Anwendung entweder als eigenständigen Server oder auch hinter einem Apachen oder Lighttpd laufen zu lassen.
- http://www.cherrypy.org/wiki/WSGI
- http://projects.amor.org/misc/wiki/ModPythonGateway
- http://code.google.com/p/modwsgi/wiki/I ... thCherryPy
Wobei mod_wsgi ähnliche Designfehler wie mod_python hat, zumindest der 'embedded mode'. Den Interpreter im Apache-Prozess (oder überhaupt im HTTPd-Prozess) laufen lassen ist Aufgrund der Eigenschaften des Python-Interpreters nicht anzuraten. Letztendlich bleibt der 'daemon mode', der zwar weniger Setup benötigt als FastCGI/SCGI, aber im Gegensatz zu diesen fest an Apache gekoppelt ist. Besser als mod_python ist es schon und vielleicht wird es ja besser betreut als Apaches FastCGI Module. Ansonsten sollte man erstmal abwägen, was man benötigt.

Achja, CherryPy kann man auch sicherlich noch durch mod_proxy laufen lassen, vor WSGI war das recht populär, denke ich.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
snatch
User
Beiträge: 25
Registriert: Sonntag 20. August 2006, 01:49

Der Zugriff auf reale Ordner ist dann aber nicht über die URL möglich, oder? Ich verstehe das doch richtig das du die realen Unterordner nur in Functionen also im Code an sich benutzt, es wäre dann also nicht möglich das man über die URL in einen realen Unterordner kommt, oder?

Das du eine Funktion geschrieben hast die eine URL überprüft und dann guckt ob ein Ordner oder eine Datei mit dem Namen verfügbar ist, habe ich wahrgenommen, aber wie ist das wenn man keine Funktion dafür schreibt? Ich gehe davon aus das man dann einen Error bekommt das die jeweilige Funktion nicht vorhanden ist. Oder denke ich da Falsch?

Dann noch eine Sache zu den Classen. Du hast schon recht das man Code so einfach wie möglich machen sollte, aber ich finde wenn man Module auf verschiedene Klassen und somit auch auf verschiedene Dateien aufteilt, hat man ein besser übersicht. Möglich ist es ja immer noch in der Root Klasse die anderen Klassen aus anderen Dateien zu importieren.

mfg snatch
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

snatch hat geschrieben:wie ist das wenn man keine Funktion dafür schreibt? Ich gehe davon aus das man dann einen Error bekommt das die jeweilige Funktion nicht vorhanden ist.
Hallo snatch!

Probiere es doch aus. :P

mfg
Gerold
:-)

PS: Nein, wenn man das im Quellcode nicht vorsieht oder einen Ordner nicht ohne Einschränkung mit "tools.staticdir.on" markiert, dann kommt man nicht von außen auf den realen Ordner zu.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Hallo Gerold!

Erstmal danke, für den schönen Bericht über eine der schönsten Bibliotheken fürs Web.

Ich arbeite mit CherryPy auch schon seit dem Release der Version 2.2 und bin immer überzeugter.

Wenn man sich nicht zu viel in den Kern hacken muss, ist es eine wunderbare Sache, gehts weit unter die Haube muss man schauen, ob halt Bibliotheken, wie Werkzeug, Colubrid oder Paste nicht besser währen.

Wobei auch hier CherryPy mit den `tools` sehr starke Anpassungen erlaubt.


Was mich allerdings interessiert, ist die Möglichkeit eines eigenen Dispatchers, für meine Applikation, da ich gerne meine Applikationen etwas anders aufbauen möchte, als mir der aktuelle es zulässt. (ohne hässliches Hacken von diesem)

Kennst du dazu gute Dokumentationen/Beispiele.

Zur Zeit habe ich nur die halbwegs gute Dokumentation aus dem Quellcode gelesen und gehe einfach mal davon aus, das man nur `cherrypy.request.handler` auf ein `callable object` setzen muss und die Konfigurationsmöglichkeiten mit einbezieht, sofern dies in der entsprechenden API vorgesehen ist (ich erinnere an `handler._cp_config`).

Kennst du da noch etwas anderes?

MfG EnTeQuAk
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

EnTeQuAk hat geschrieben:Was mich allerdings interessiert, ist die Möglichkeit eines eigenen Dispatchers, für meine Applikation, da ich gerne meine Applikationen etwas anders aufbauen möchte, als mir der aktuelle es zulässt.
Hallo EnTeQuAk!

Damit habe ich mich noch nicht befasst. Vielleicht findest du hier etwas:
- http://www.cherrypy.org/search?q=dispatcher&wiki=on
- http://www.cherrypy.org/wiki/ConfigAPI# ... thonsyntax
- http://www.cherrypy.org/wiki/WSGI
- http://www.cherrypy.org/wiki/CherryPySpec

Ich weiß nur, dass man sich selber einen Dispatcher bauen und diesen über die Config zuweisen kann.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Ok, der Link zur CherryPySpec hat mir dann doch weitergeholfen, da ist einiges drinne, was sonst nirgentwo dokumentiert ist.


Wen es interessiert, einen halbwegs konformen Dispatcher mit Werkzeugs (http://werkzeug.pocoo.org) URL Ruting einzusetzen, der schaue sich den folgenden Code an:

Code: Alles auswählen

#-*- coding: utf-8 -*-

import cherrypy
from werkzeug import routing

from wwws.views import all_views
from wwws.urls import url_map


class WWWSDispatcher(object):
    """
    Because we don't use the default
    dispatcher this will be the real
    internal application.
    """

    def __init__(self):
        self.url_map = url_map
        self._views = all_views.copy()

    def get_view(self, endpoint):
        return self._views[endpoint]

    def __call__(self, path_info):
        req = cherrypy.request
        print dir(req)
        url_adapter = self.url_map.bind_to_environ(req.wsgi_environ)

        try:
            endpoint, args = url_adapter.match(path_info)
        except routing.NotFound:
            req.handler = cherrypy.NotFound()
        except routing.RequestRedirect, e:
            req.handler = cherrypy.HTTPRedirect()
        else:
            view = cherrypy.dispatch.LateParamPageHandler(
                self.get_view(endpoint))
            req.handler = view

        #: set the request config
        req.config = cherrypy.config.copy()

        #: It's not needed from cherrypy but we also return
        #: the page handler object.
        return req.handler
Nun, da ich also kein richtiges 'root' Objekt verwende sondern verteilte `Views`, habe ich mir überlegt, was brauche ich dann ein Application-Objekt, das an cherrypy.tree.mount übergeben wird. Keine Ahnung, aber ich brauchte zumindest eines, das so aussieht:

Code: Alles auswählen


class Application(object):
    _cp_conf = {'request.dispatcher': WWWSDispatcher(),
                'tools.trailing_slash.on': False,
                'tools.wsgiapp.on': True,
               }
Das muss reichen und so funktioniert es auch.

Für Fragen stehe ich gerne offen, da ich nun halbwegs Ahnung davon habe :)


MFG EnTeQuAk
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Du kannst auch __doc__ im IRC auf #python.de fragen, ob er dir den Code überlässt, der Routes in CherryPy integriert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Wenn du das gleiche meinst, wie ich, ist es sogar im Kern implementiert:
http://cherrypy.org/browser/trunk/cherr ... ch.py#L227

Inzwischen habe ich noch einige aktualisierungen angebracht. Die sind aber eher trivial und dienen der einhaltung der `CherryPySpec`. Ist ja auch nicht gerade ohne, die erstmal durchzuarbeiten :)

MfG EnTeQuAk
Antworten