Bottle: Micro Web Framework

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Benutzeravatar
noisefloor
User
Beiträge: 3875
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@MrNiceTry: Beschäftige dich mal mit dem Grundprinzip von CGI. :-) Das heißt vereinfacht gesagt nichts anderes als das der Webserver ein Skript ausführt. Mit den Rechten des Webservers. Und auf der IP und dem Port, auf dem der Webserver läuft. Den in Bottle integrierten Server brauchst du gar nicht.

Wenn da mit FastCGI zu schwierig ist, kannst du auch erstmal "normales" CGI nehmen. Dann brauchst du in lighttpd nur .py Dateien registrieren (ist in der Doku von lighthttpd erklärt) und den Bottle-Skript an CGI binden (ist in der Bottle Dokue erklärt).

Gruß, noisefloor
uKev
User
Beiträge: 15
Registriert: Mittwoch 9. Dezember 2009, 13:43

MrNiceTry hat geschrieben:Kann Bottle seine Rechte abgeben?
Oder kann man das mit Bottle machen?

Irgend etwas muß es doch geben Bottle zu benutzen, oder ?
Nein, das kann Bottle in der "offiziellen" Version nicht. Ich habe einen Patch dazu geschrieben, der genau das ermöglicht [1], weil ich die selben Anforderungen hatte. (Möglichst leicht, nicht besonders performant auf Port 80 laufend). Der Patch wurde nicht übernommen und mein Repository ist nicht gepflegt. Ich würde dir davon abraten einfach die dortige Bottle Version zu übernehmen. Du könntest aber den Patch auf die aktuelle Bottle Version portieren. Für mehr Infos gibt es einen Thread [2] dazu.

Wenn man möglichst leichtgewichtig und performant sein will, kann man statt dem WSGIRefServer den Tornado Adapter benutzen, dann ist die ganze Geschichte auch multithreaded. Damit funktioniert mein Patch aber (noch) nicht.

Alternativ kann ich dir cherokee empfehlen, den kann man ohne Einarbeitungszeit innerhalb weniger Minuten über ein Webfrontend konfigurieren und ist sehr leichtgewichtig, aber trotzdem vielseitig (uwsgi und fastCGI fähig). Das Webfrontend startet man nur zum Zweck der Konfiguration und wird anschließend beendet. Es gibt dort Assistenten für die gängigsten Aufgaben. Alles ziemlich selbsterklärend, aber halt doch wieder ein eigener Server vor dem Python-Prozess, wie bei nginx, Apache, lighttpd.

Ansonsten, wenn es ohne den Patch auskommen soll und ohne vorgeschalteten "ausgewachsenen" Webserver, habe ich sehr gute Erfahrungen mit Pound gemacht. Der macht nichts anderes als auf Port 80 zu laufen, die Anfragen entgegenzunehmen und lokal an Port 8080 (oder einen beliebigen anderen unpriviligierten Port) weiter zu reichen. Nennt sich dann http-proxy / load balancer. Da hast du dann zusätzlich zum Bottle Python Prozess noch <1 MiB im Speicher. Wenn du dann noch Bottle mit Tornado nutzt, hast du eine superschnelle und leichtgewichtige Kombi. Pound gibts im Ubuntu Repo und Tornado sind nur ein paar .py Dateien, die du in das Verzeichnis mit der bottly.py wirfst.



[1] http://github.com/uKev/bottle/commit/5c ... b3156db759
[2] http://www.python-forum.de/viewtopic.php?t=21221
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

uKev hat geschrieben:Alternativ kann ich dir cherokee empfehlen, den kann man ohne Einarbeitungszeit innerhalb weniger Minuten über ein Webfrontend konfigurieren und ist sehr leichtgewichtig, aber trotzdem vielseitig (uwsgi und fastCGI fähig). Das Webfrontend startet man nur zum Zweck der Konfiguration und wird anschließend beendet. Es gibt dort Assistenten für die gängigsten Aufgaben. Alles ziemlich selbsterklärend, aber halt doch wieder ein eigener Server vor dem Python-Prozess, wie bei nginx, Apache, lighttpd.
Das Problem ist, dass im Gegensatz zu Apaches mod_fastcgi/mod_fcgid sich Cherokee nicht um die FastCGI-Prozessverwaltung kümmert. Somit muss man immer selbst drauf achten dass der Prozess immer läuft. Bei Apache wird der FastCGI-Prozess mitverwaltet, so dass man dieses Problem nicht hat und Apache sich darum kümmert ihn zu starten bevor ein Request fehlschlägt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
uKev
User
Beiträge: 15
Registriert: Mittwoch 9. Dezember 2009, 13:43

Leonidas hat geschrieben: Das Problem ist, dass [...] sich Cherokee nicht um die FastCGI-Prozessverwaltung kümmert. Somit muss man immer selbst drauf achten dass der Prozess immer läuft. [...]
Äh, nicht ganz, das ist nur die halbe Wahrheit. Cherokee kennt zwei Modi: Entfernter Host und lokaler Interpreter. Der erste Modi entspricht deiner Beschreibung, ist aber eigentlich für entfernte Server gedacht. Wenn man lokaler Interpreter auswählt, gibt man den Befehl an, der ausgeführt werden soll, wenn der Prozess nicht läuft. Cherokee kümmert sich also um alles selbstständig. Läuft bei mir schon ne ganze weile sehr zuverlässig mit FastCGI.

Ich zitiere mal aus der Doku[1]:
Interpreter: command to spawn a new source in case it were not accessible[...]
Note that you will have to manually launch the spawner if you use a Remote host as Information source instead of a Local interpreter.
Das gilt so ziemlich für alle Arten von Interpreter Anbindung, egal ob fastCGI, uwsgi, scgi... in der Doku[1] findest du sogar Screenshots, die die Konfiguration am Beispiel von scgi und Django zeigen.

[1] http://www.cherokee-project.com/doc/coo ... jango.html
MrNiceTry
User
Beiträge: 80
Registriert: Samstag 7. November 2009, 10:32

Hallo,

nach einigen Überlegungen bezüglich der Ansteuerung von Bottle (auch hier im Forum - Danke) habe ich mich jetzt für die klassische Variante mit Apache und WSGI entschieden.

Aber auch das bringt mir im Moment Probleme.

Ubuntu 10.4 Server
Apache
mod-wsgi

In: /var/www/todo
todo.py
bottle.py
adapter.wsgi - alles nach Bottle-Anleitung. (so glaube ich)

Folgender Fehler:

Code: Alles auswählen

[Fri Oct 08 21:32:32 2010] [notice] Apache/2.2.14 (Ubuntu) mod_wsgi/2.8 Python/2.6.5 configured -- resuming normal operations
[Fri Oct 08 21:32:47 2010] [error] [client xx.xxx.116.91] mod_wsgi (pid=12237): Target WSGI script '/var/www/todo/adapter.wsgi' cannot be loaded as Python module.
[Fri Oct 08 21:32:47 2010] [error] [client xxx.xxx.116.91] mod_wsgi (pid=12237): Exception occurred processing WSGI script '/var/www/todo/adapter.wsgi'.
[Fri Oct 08 21:32:47 2010] [error] [client xxx.xxx.116.91] Traceback (most recent call last):
[Fri Oct 08 21:32:47 2010] [error] [client xxx.xxx.116.91]   File "/var/www/todo/adapter.wsgi", line 1, in <module>
[Fri Oct 08 21:32:47 2010] [error] [client xxx.xxx.116.91]     import sys, os, bottle
[Fri Oct 08 21:32:47 2010] [error] [client xxx.xxx.116.91] ImportError: No module named bottle
adapter.wsgi (nach Anleitung)

Code: Alles auswählen

import sys, os, bottle

sys.path = ['/var/www/todo/'] + sys.path
os.chdir(os.path.dirname(__file__))

import todo # This loads your application

application = bottle.default_app()


bottle.py ist im gleichen Verzeichnis: /var/www/todo/bottle.py


Danke für jede Unterstützung.

MrNiceTry
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Du solltest natürlich erst in das richtige Verzeichnis wechseln und dann importieren.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
MrNiceTry
User
Beiträge: 80
Registriert: Samstag 7. November 2009, 10:32

Was meinst Du mit "Du solltest natürlich erst in das richtige Verzeichnis wechseln".

Es ist alles im gleichen Verzeichnis: /var/www/todo
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Na schau dir mal deinen Code an. Du wechselt ja mit os.chdir in dein Verzeichnis. Nur vorher versuchst du bottle zu importieren - und das kann er einfach nicht finden. Importierst du bottle nach dem os.chdir, sollte es eigentlich klappen.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
MrNiceTry
User
Beiträge: 80
Registriert: Samstag 7. November 2009, 10:32

Danke.

Habe wie folgt geändert:

Code: Alles auswählen

import sys, os

sys.path = ['/var/www/todo/'] + sys.path
os.chdir(os.path.dirname(__file__))

import bottle

import todo # This loads your application

application = bottle.default_app()

Funktioniert.
Sieht zumindest so aus. Bin morgen sicher.


Danke nochmal und gute Nacht.


MrNiceTry
MrNiceTry
User
Beiträge: 80
Registriert: Samstag 7. November 2009, 10:32

Wie muß ein Decorator aussehen, der mir ALLE Unterverzeichnisse durchreicht.
Also in jeder Tiefe.

Danke

MrNiceTry
Benutzeravatar
noisefloor
User
Beiträge: 3875
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

du meinst, dass z.B.

/meine_app
/meine_app/foo
/mein_app/foo/bar/irgend/was

alle von der gleichen Route abgefangen werden?

Das sollte mit einer RegEx funktionieren.

Code: Alles auswählen

@bottle.route('/meine_app')
@bottle.route('/meine_app/:#.*#')
def meine_funktion():
    ...
Gruß, noisefloor
MrNiceTry
User
Beiträge: 80
Registriert: Samstag 7. November 2009, 10:32

(Wie) kann man ermitteln, wie Python/Bottle aufgerufen worden ist ?

Erfolgte der Aufruf von der Konsole oder durch Apache/WSGI ?


Danke.

MrNiceTry
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Es läuft immer ein WSGI-Server; wenn du Bottle-Anwendungen "aus der Konsole" startest, dann wird eben ein WSGI-Server in der Konsole gestartet :-)
MrNiceTry
User
Beiträge: 80
Registriert: Samstag 7. November 2009, 10:32

Ja, aber meine Frage ist: Kann man ermitteln WIE Python/Bottle gestartet wurde.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

MrNiceTry hat geschrieben:Ja, aber meine Frage ist: Kann man ermitteln WIE Python/Bottle gestartet wurde.
Wozu? Vielleicht hilft es uns, Dein eigentliches Problem zu verstehen...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
MrNiceTry
User
Beiträge: 80
Registriert: Samstag 7. November 2009, 10:32

Meine Anwendung soll sich anders verhalten, wenn sie vom Apache aufgerufen wird, als wenn der Aufruf manuell von der Konsole gemacht wird.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

MrNiceTry hat geschrieben:Meine Anwendung soll sich anders verhalten, wenn sie vom Apache aufgerufen wird, als wenn der Aufruf manuell von der Konsole gemacht wird.
Naja das ist schon klar, aber inwiefern denn? Sind es inhaltlich wirklich andere Dinge oder geht es eher in Richtung Debug-Modus an / aus?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
MrNiceTry
User
Beiträge: 80
Registriert: Samstag 7. November 2009, 10:32

Sorry,

aber was soll das an meiner Frage ändern?

Ich kann gerne den Sinn und die Struktur meiner Anwendung erläutern.

Aber meine Frage ist doch einfach und klar formuliert, oder?

"Kann man ermitteln WIE die (Bottle-)Anwendung aufgerufen wurde."
(Entschuldigung. Aber falls das nicht klar verständlich ist, lasst es mich bitte wissen!)
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Sind zum Beispiel Port oder Host unterschiedlich für die beiden Server? Dann könntest du dir einfach das `environ` angucken.
MrNiceTry
User
Beiträge: 80
Registriert: Samstag 7. November 2009, 10:32

'environ' hat mich nicht weiter gebracht.

Über host und port kann ich das nicht differenzieren. Die können durchaus gleich sein.
Irgendwie kann ich das schon rausfinden. Ich könnte z.B. Startparameter verwenden.

Ich hatte nur gehofft, es gäbe eine elegantere Methode, möglicherweise aus dem System oder aus Python die Info zu bekommen.


MrNiceTry
Antworten