Markdown hat etwa den selben Funktionsumfang wie Creole, bietet allerdings standardmäßig keine Syntax für Wiki-Links (ein Umstand, den ich bewusst verschwiegen habe). Mir gefällt es schon aus dem Grund besser, dass TextMate einen Edit- und Preview-Modus dafür hat.
Ich konnte in 5min eigentlich nur Code zeigen und nicht erklären, warum er so und nicht anders aussieht oder ihn entsprechend herleiten. Das finde ich eigentlich nicht so gut. Deswegen wäre länger IMHO besser gewesen.
Mein Code enthält zudem (mindestens) einen Fehler. Das richtige Escapen von HTML und URLs und das korrekte Kodieren und Dekodieren von Strings in Bytes für die Templates ist auch ein Thema, das mehr Zeit bräuchte, da es mit das Schwierigste ist, wo man eigentlich Hilfe vom Rahmenwerk haben will.
Schließlich wäre es gerade für die Vergleichbarkeit nett, Sessions und/oder eine Benutzerverwaltung zu sehen. Da muss man dann auf einmal mehr eigenes Rahmenwerk bauen, als der Wiki eigentlich Code hat :)
Und zum Stopfen: Man merkt da vielleicht, dass mir die Worte fehlten. Aber zu diesem Zeitpunkt hatte ich das ganze gefühlt schon ein Dutzend Male durchgezogen (insgesamt haben mich die 5min etwa 2h Arbeit gekostet) und so fiel dann die Klappe.
Stefan
Bottle: Micro Web Framework
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Unicode Support für SimpleTemplate ist übrigens in der Mache. Dazu wollte ich mich eh nochmal aus lassen, da ich die Problematik ziemlich kompliziert finde und es meiner Meinung nach keine Perfekte Lösung gibt. Vielleicht habt ihr ja Meinungen und Vorschläge dazu. Folgendes ist der Plan:sma hat geschrieben: Mein Code enthält zudem (mindestens) einen Fehler. Das richtige Escapen von HTML und URLs und das korrekte Kodieren und Dekodieren von Strings in Bytes für die Templates ist auch ein Thema, das mehr Zeit bräuchte, da es mit das Schwierigste ist, wo man eigentlich Hilfe vom Rahmenwerk haben will.
SimpleTemplate soll intern mit Unicode arbeiten. Bekommt es Bytes statt Unicode als Quellcode-Input, wird self.encoding (Voreinstellung: utf8) verwendet, um den Kram zu dekodieren. Kommt in den ersten zwei Zeilen der Eingabe ein PEP263 String vor (...coding=latin9...) wird self.encoding entsprechend abgeändert und der Rest der Daten mit dem neuen encoding dekodiert. Templates verhalten sich demnach ähnlich wie normale Python Skripte, was das encoding angeht. Das hat den großen Vorteil, das der App-Entwickler nicht wissen muss, mit welcher Kodierung der Template-Designer seine Templates gespeichert hatte und Templates damit austauschbar und universal einsetzbar werden.
Wird das Template mit Daten gefüllt, funktioniert das genau umgekehrt: Byte Input wird automatisch mit utf8 in Unicode umgewandelt, es sei denn es wird etwas anderes konfiguriert. Leider gibt es keine Möglichkeit, die PEP263 des aufrufenden Programms zur Laufzeit aus zu lesen. Empfohlen wird aber eh, nach Möglichkeit nur Unicode in die Templates zu stopfen.
Am Schluss wirft das Template einen großen Unicode-String aus, der sich recht fix in einem Rutsch in Bytes umwandeln lässt. Das macht Bottle ja schon länger automatisch.
Dieses Konzept ist für Python 3 oder eine Unicode-lastige Python 2 Umgebung optimiert. Sobald Bytes in das Template gestopft werden, wird die Geschichte langsamer, da sie erst einzeln in Unicode umgewandelt werden müssen.
Ein anderer Ansatz wäre, wie bisher die Templates intern als Bytes zu behandeln und den Input in Bytes umzuwandeln. Das spart in python2 Umgebungen ne menge umkodiererei (da die meisten Strings eh Bytes sind) macht aber große Probleme, wenn das Template-Encoding nicht mit dem Laufzeit-Encoding oder dem Output-Encoding überein stimmt.
Der dritte Ansatz wäre, native Strings zu verwenden. Also Bytes unter 2.x und Unicode unter 3.x. Das ist allerdings die Entwickler-Hölle und wäre mir viel zu Bug-Anfällig. Ich weigere mich, so nen Krampf zu programmieren

Zusammenfassend kann man sagen: Welche Variante schneller ist, hängt davon ab, ob die Templates hauptsächlich mit Bytes oder mit Unicode gefüttert werden. Einen klaren Gewinner gibt es nicht. Die Unicode-Variante macht auf mich aber einen saubereren und flexibleren Eindruck, weswegen ich mich dafür entschieden habe. Und spätestens mit Python 3.x ist Unicode eh die erste Wahl.
Spricht denn etwas gegen das nach-synchronisieren? Ich würde das Getippe mit einer provisorischen Audio-Spur aufzeichnen und dann das ganze nochmal in Ruhe nach sprechen. Oder wirkt das dann nicht mehr live genug?sma hat geschrieben: Und zum Stopfen: Man merkt da vielleicht, dass mir die Worte fehlten. Aber zu diesem Zeitpunkt hatte ich das ganze gefühlt schon ein Dutzend Male durchgezogen (insgesamt haben mich die 5min etwa 2h Arbeit gekostet) und so fiel dann die Klappe.
Bottle: Micro Web Framework + Development Blog
Unicode-lastiges (und UTF-8 kodiertes) Python 2 oder Python 3 finde ich gut. Mit nackten Bytes zu arbeiten (so wie es ja PHP macht) und dann zu hoffen, es wird schon passen, finde ich nicht gut. Es sollte eine bewusste Entscheidung sein, so wie es Django auch macht: Strings müssen immer echte Strings sein, also unter Python 2.x `unicode`-Objekte.
Das Nachsynchronisieren finde ich noch schwerer als es beim ersten Mal gleich richtig zu machen. Das habe ich einmal versucht und komme nie hin. Da müsste ich schon exakt aufschreiben und dann in richtiger Geschwindigkeit vorlesen, was ich sagen will. Daher bleibe ich lieber bei dem vielleicht nicht ganz so perfekten "live" gesprochenen Screencast.
Stefan
Das Nachsynchronisieren finde ich noch schwerer als es beim ersten Mal gleich richtig zu machen. Das habe ich einmal versucht und komme nie hin. Da müsste ich schon exakt aufschreiben und dann in richtiger Geschwindigkeit vorlesen, was ich sagen will. Daher bleibe ich lieber bei dem vielleicht nicht ganz so perfekten "live" gesprochenen Screencast.
Stefan
Hallo Defnull.
Bottle ist Klasse. Läuft einwandfrei mit den OnboardServer.
Probleme habe ich mit der Installation unter Apache.
Ich hab mich an Dein Tutorial bei Paws gehalten.
Von Außen aufgerufen wird aber nur "Index of /todo" angezeigt.
Bottle ist Klasse. Läuft einwandfrei mit den OnboardServer.
Probleme habe ich mit der Installation unter Apache.
Ich hab mich an Dein Tutorial bei Paws gehalten.
Von Außen aufgerufen wird aber nur "Index of /todo" angezeigt.
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Ohne die Apache Konfiguration kann ich dir da nicht helfen. Anscheinend merkt dein Apache gar nicht, das die URL von Bottle gehandhabt werden soll. Es ist also kein Bottle, sondern erst einmal ein Apache-Problem.
Bottle: Micro Web Framework + Development Blog
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Es gibt übrigens nen neues Feature im git: Auto Routes 
Der @route() Dekorator kann nun auch ohne Parameter aufgerufen werden und generiert dann eine sinnvolle Route anhand der Funktions-Signatur (Funktions-Name und Argument-Namen). Damit spart man sich ne Menge Tipparbeit
Bei Argumenten mit Default-Wert werden sogar mehrere alternative Routen erstellt.
Beispiele:

Der @route() Dekorator kann nun auch ohne Parameter aufgerufen werden und generiert dann eine sinnvolle Route anhand der Funktions-Signatur (Funktions-Name und Argument-Namen). Damit spart man sich ne Menge Tipparbeit

Beispiele:
Code: Alles auswählen
#'/a'
@route()
def a(): pass
#'/b/:x/:y'
@route()
def b(x, y): pass
#'/c/:x' and '/c/:x/:y'
@route()
def c(x, y=5): pass
#'/d' and '/d/:x' and '/d/:x/:y'
@route()
def d(x=5, y=6): pass
#/some/deep/path/:id
@route()
def some__deep__path(id): pass
Bottle: Micro Web Framework + Development Blog
-
- User
- Beiträge: 996
- Registriert: Mittwoch 9. Januar 2008, 13:48
Ah, sehr schoen, da wollte ich auch mal was zu submitten, aber der Code wurde dann ziemlich unterirdisch, drum liegt das jetzt tot im "archive"-Ordner ;)Defnull hat geschrieben:Es gibt übrigens nen neues Feature im git: Auto Routes :D
Vielleicht wäre es besser, einen seperaten `@autoroute`-Decorator einzuführen und diesen dann ganz ohne Klammern aufrufen zu können. Das Modul [mod]contextlib[/mod] zeigt mit `@contextmanager` IMHO ganz gut, wie man das unter Zuhilfenahme von `@wraps` machen kann. (bzw in der Doku zu functools.wraps wrid das ja auch schon gezeigt)
Wenn dann nach einer Weile deutlich wird, dass das Autoroute-Verhalten der bevorzugte Weg für die Bottle-Nutzer ist, könntest du das ja evtl später zum Standardverhalten für @route machen (also ohne Klammern) und die alte Syntax zu "variant_route", oder was auch immer, machen.
Hihi, "Autoroute" war übrigens mal ein Routenplaner, den ich Anfang/Mitte der 90er auf meinem ersten Rechner hatte.
EDIT: Das `some__deep__path`-Beispiel/Verhalten fände ich mit jeweils einem Unterstrich gelungener.
Wenn dann nach einer Weile deutlich wird, dass das Autoroute-Verhalten der bevorzugte Weg für die Bottle-Nutzer ist, könntest du das ja evtl später zum Standardverhalten für @route machen (also ohne Klammern) und die alte Syntax zu "variant_route", oder was auch immer, machen.
Hihi, "Autoroute" war übrigens mal ein Routenplaner, den ich Anfang/Mitte der 90er auf meinem ersten Rechner hatte.

EDIT: Das `some__deep__path`-Beispiel/Verhalten fände ich mit jeweils einem Unterstrich gelungener.
Habe folgende Meldung im error.log des apache2:Defnull hat geschrieben:Ohne die Apache Konfiguration kann ich dir da nicht helfen. Anscheinend merkt dein Apache gar nicht, das die URL von Bottle gehandhabt werden soll. Es ist also kein Bottle, sondern erst einmal ein Apache-Problem.
mod_wsgi (pid=16024): Target WSGI script '/var/www/todo/adapter.wsgi' cannot be loaded as Python module.
Exception occurred within WSGI script '/var/www/todo/adapter.wsgi'.
"/var/www/todo/adapter.wsgi", line 9, in <module>
application = default_app()
name 'default_app' is not defined
Was für Conf-Dateien brauchst Du um weiter helfen zu können ?
Warum doppelte Unterstriche bei "foo/bar" und Autorouting? Ich halte es für extrem unwahrscheinlich, das jemand einen "_" in einer URL haben will (meist sind es "-" wie es sich nach der Lisp-Tradition auch gehört) und reicht dann nicht "foo_bar" als Name für "foo/bar"?
Und wie würde man zwischen verschiedenen HTTP-Methoden unterscheiden?
Stefan
Und wie würde man zwischen verschiedenen HTTP-Methoden unterscheiden?
Stefan
Ich würde vorschlagen einen autoroute Dekorator einzuführen, damit dekorierte Funktionen kümmern sich um alle HTTP-Methoden.
autoroute("post"), autoroute("get") oder autoroute.post, autoroute.getsma hat geschrieben:Und wie würde man zwischen verschiedenen HTTP-Methoden unterscheiden?
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Ich persönlich verwende lieber Unterstriche als Bindestriche in URLs, wenn es darum geht, Leerstellen zu markieren. (Auch wenn Leerstellen in URLs möglich sind, das %20 ist hässlich). Außerdem wird in Python der Unterstrich oft in längeren Funktionsnamen verwende. Diese ungefragt in '/' zu übersetzen halte ich für unintuitiv und fehlerträchtig. Die Doppel-Unterstriche sind da expliziter, finde ich.sma hat geschrieben:Warum doppelte Unterstriche bei "foo/bar" und Autorouting? Ich halte es für extrem unwahrscheinlich, das jemand einen "_" in einer URL haben will (meist sind es "-" wie es sich nach der Lisp-Tradition auch gehört) und reicht dann nicht "foo_bar" als Name für "foo/bar"?
@post() oder @route(method='POST') oder @route(None, 'POST'). Man muss einfach den ersten Parameter frei lassen.sma hat geschrieben:Und wie würde man zwischen verschiedenen HTTP-Methoden unterscheiden?
Gegen die Idee mit dem extra-dekorator für autorouten habe ich mich bewusst entschieden, da autorouten früher oder später zum Standard werden sollen. Der bisher übliche Route-String ist dann nichts weiter als ein optionaler Konfigurationsparameter, genau wie 'GET' der Standard ist und mit method='POST' überschrieben werden kann. Ansonsten tun implizite und explizite Routen ja exakt das selbe.DasIch hat geschrieben:Ich würde vorschlagen einen autoroute Dekorator einzuführen, damit dekorierte Funktionen kümmern sich um alle HTTP-Methoden.
Allerdings plane ich, das @route, @get, ... auch ohne Klammern funktionieren und statt eines einzelnen Route-Strings auch eine Liste übergeben werden darf. Ich hatte auch die Idee, den docstring nach zusätzlichen Routen zu durchsuchen, aber da bin ich mir noch unschlüssig.
Im Endeffekt soll der @route Dekorator noch um einiges mächtiger und intelligenter werden. Schließlich ist das eine der wichtigsten Funktionen von Bottle.
PS: Alle HTTP Methoden abzufangen geht übrigens schon länger mit dem method='ANY' Schlüssel.
Zuletzt geändert von Defnull am Samstag 20. Februar 2010, 13:44, insgesamt 1-mal geändert.
Bottle: Micro Web Framework + Development Blog
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Na da steht der Fehler doch schon: default_app() ist nicht definiert. Hast du die Funktion richtig importiert?MrNiceTry hat geschrieben: Habe folgende Meldung im error.log des apache2:
mod_wsgi (pid=16024): Target WSGI script '/var/www/todo/adapter.wsgi' cannot be loaded as Python module.
Exception occurred within WSGI script '/var/www/todo/adapter.wsgi'.
"/var/www/todo/adapter.wsgi", line 9, in <module>
application = default_app()
name 'default_app' is not defined
Bottle: Micro Web Framework + Development Blog
Wie wäre es denn mit einer Konfiguration der Slashes durch sowas wie:
Code: Alles auswählen
import bottle
bottle.Router.slash = '_'
#oder
@route(slash='__'):
def a__b():
return ''
[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]
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Ich habe mich da streng an Dein Tutorial gehalten.Defnull hat geschrieben:Na da steht der Fehler doch schon: default_app() ist nicht definiert. Hast du die Funktion richtig importiert?MrNiceTry hat geschrieben: Habe folgende Meldung im error.log des apache2:
mod_wsgi (pid=16024): Target WSGI script '/var/www/todo/adapter.wsgi' cannot be loaded as Python module.
Exception occurred within WSGI script '/var/www/todo/adapter.wsgi'.
"/var/www/todo/adapter.wsgi", line 9, in <module>
application = default_app()
name 'default_app' is not defined
Dort wird in der todo.py wie folgt importiert:
Code: Alles auswählen
# only needed when you run Bottle on mod_wsgi
from bottle import default_app
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Das kann ja irgendwie nicht sein. Wenn du default_app in adapter.wsgi importierst, muss es auch definiert sein, sonst hätte es schon viel früher einen ImportError gegeben.
Edit: Du musst default_app natürlich auch in adapter.wsgi importieren (wie im Tutorial angegeben) und nicht nur in todo.py.
Edit: Du musst default_app natürlich auch in adapter.wsgi importieren (wie im Tutorial angegeben) und nicht nur in todo.py.
Bottle: Micro Web Framework + Development Blog
Defnull hat geschrieben:Das kann ja irgendwie nicht sein. Wenn du default_app in adapter.wsgi importierst, muss es auch definiert sein, sonst hätte es schon viel früher einen ImportError gegeben.
adapter.wsgi
(original aus Deinem Tutorial unter http://bottle.paws.de/page/tutorial)
Code: Alles auswählen
import sys
sys.path = ['/var/www/todo/'] + sys.path
import todo
import os
os.chdir(os.path.dirname(__file__))
application = default_app()
Defnull hat geschrieben:Das kann ja irgendwie nicht sein. Wenn du default_app in adapter.wsgi importierst, muss es auch definiert sein, sonst hätte es schon viel früher einen ImportError gegeben.
Edit: Du musst default_app natürlich auch in adapter.wsgi importieren (wie im Tutorial angegeben) und nicht nur in todo.py.
Ich habe den Import von default_app() in adapter.wsgi vorverlegt, bzw. dort nochmals eingetragen.
Das funktioniert jetzt.
Sorry, ich hab jetzt nochmals gesucht.
Aber die Stelle, wo das im Tutorial steht, kann ich nicht finden.
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Dann schau dir mal den Code-Schnipsel direkt über dem von dir zitierten Code-Beispiel an. Da steht ne lange import-reihe inklusive default_appMrNiceTry hat geschrieben: Sorry, ich hab jetzt nochmals gesucht.
Aber die Stelle, wo das im Tutorial steht, kann ich nicht finden.
Bottle: Micro Web Framework + Development Blog