Bottle: Micro Web Framework

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
tordmor
User
Beiträge: 100
Registriert: Donnerstag 20. November 2008, 10:29
Wohnort: Stuttgart

Defnull hat geschrieben:Es muss eine Möglichkeit geben, die Kodierung der Template-Datei und die Kodierung der Byte String Template Variablen anzugeben.
Was ist mit locale.getpreferredencoding?
http://www.felix-benner.com
BlackJack

@tordmor: Da finde ich fest UTF-8 besser, denn mit UTF-8 kann man "alles" ausdrücken. Wenn man die lokale Kodierung benutzt, dann läuft vielleicht alles auf dem Entwickungsrechner, aber wenn man es dann auf den Webserver hochlädt, benutzt der vielleicht eine andere Kodierung.
tordmor
User
Beiträge: 100
Registriert: Donnerstag 20. November 2008, 10:29
Wohnort: Stuttgart

BlackJack hat geschrieben:@tordmor: Da finde ich fest UTF-8 besser, denn mit UTF-8 kann man "alles" ausdrücken. Wenn man die lokale Kodierung benutzt, dann läuft vielleicht alles auf dem Entwickungsrechner, aber wenn man es dann auf den Webserver hochlädt, benutzt der vielleicht eine andere Kodierung.
Wenn der Rechner eine andere Kodierung hat, sollten die Dateien dort auch anders kodiert sein. Wer verschiedene Kodierungen mischt, muss immer angeben, welche er gerade verwendet. Immer utf-8 klappt nicht, weil nicht jede Bytefolge einen korrekten utf-8 text darstellt und spätestens wenn man includes hat, werden die Pfadnamen falsch dekodiert.
http://www.felix-benner.com
BlackJack

@tordmor: Das ist nicht Dein Ernst oder? Wenn ich etwas entwickelt habe, dann möchte ich das einfach hochladen und nicht erst noch umkodieren. *Ich* möchte bestimmen welche Kodierung ich für meine Daten verwende -- das hat mir der Webserver doch nicht vorzuschreiben. Und wenn man Umlaute in Dateinamen verwendet, dann bettelt man geradezu um Probleme.
tordmor
User
Beiträge: 100
Registriert: Donnerstag 20. November 2008, 10:29
Wohnort: Stuttgart

BlackJack hat geschrieben: *Ich* möchte bestimmen welche Kodierung ich für meine Daten verwende
BlackJack hat geschrieben: Da finde ich fest UTF-8 besser,
Und wie passen die beiden Aussagen zusammen?
http://www.felix-benner.com
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

tordmor hat geschrieben:
BlackJack hat geschrieben: *Ich* möchte bestimmen welche Kodierung ich für meine Daten verwende
BlackJack hat geschrieben: Da finde ich fest UTF-8 besser,
Und wie passen die beiden Aussagen zusammen?
Ganz einfach: Besser der Zwang eines Standard-Encodings (auf das man sich dann aber verlassen kann) als eine "willkürliche" Wahl des Server-OS ;-)

Idealer Weise sollte man das Encoding selber bestimmen können, aber Defnull hat ja oben erläutert, wieso das nicht trivial zu realisieren ist.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Ich bin gerade über Router.match gestolpert. Macht es da nicht mehr Sinn, statt None, ein leerer dict für data zurückzugegen, wenn es keine Daten gibt?

Code: Alles auswählen

r = Router()
r.add('/foo', lambda: 'foo')
r.add('/:bar', lambda bar: bar)

handler, data = r.match('/foo')
handler(**data)
handler, data = r.match('/abc')
handler(**data)
Bisher muss man noch ``data = data if data is not None else dict()`` dazuschreiben.
Zuletzt geändert von jbs am Donnerstag 28. Januar 2010, 20:44, insgesamt 1-mal geändert.
[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]
BlackJack

@tordmor: Ergänzend zu Hyperion's Antwort: Diese Standardkodierung ist sogar die, die ich sowieso gewählt hätte, eben aus dem Grund, dass sie alles abdeckt, was ich so kodieren können möchte. Und noch viel mehr.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

jbs hat geschrieben:Bisher muss man noch ``data = data if data is not None else dict()`` dazuschreiben.

Code: Alles auswählen

data or {}
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Ich probiere gerade Klassenbasiert mit bottle zu arbeiten. Dabei sind Methoden automatisch Teil der URL.

Code: Alles auswählen

@tree_route('/kunde/:name')
class Kunde(TreeRoute):
    
@view('page')
    def _publish(self, out):
        return dict(content=out)
        
    def profil(self):
        return self.name
Der Inhalt von `profil` wird an `_publish` übergeben, der dann für die weitere Ausgabe zuständig ist. Nun stört sich `@view` an dem self, das übergeben wird, da es nur ``**kwargs`` übergibt. Zumindest in diesem Fall wäre das erweitern des wrapper um `*args` IMHO sinnvoll.
[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]
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Dauerbaustelle hat geschrieben:
jbs hat geschrieben:Bisher muss man noch ``data = data if data is not None else dict()`` dazuschreiben.

Code: Alles auswählen

data or {}
`data` enthält die Daten in Form eines dict. Wenn es keinen Daten gibt, dann finde ich ein leeres dict besser als None.
[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]
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Zum Router: Ich habe ursprünglich None zurück geben lassen, weil ich es für schneller hielt, als erst ein dict zu erzeugen, das eh nicht benutzt wird. In der Tat ist "if None: pass" etwa 4,5 mal schneller als "if dict(): pass". Was ich nicht beachtet habe, ist das die zweite Variante hauptsächlich durch den dict() Funktionsaufruf gebremst wird und nicht durch die Erzeugung der Datenstruktur. "if {}: pass" unterscheidet sich nur noch unwesentlich von der None-Variante; die Vereinheitlichung macht also Sinn. Hier ist der Patch:

http://github.com/defnull/bottle/commit ... 9210d48307

Den @view() Dekorator habe ich ebenfalls angepasst. Dabei konnte ich auch gleich mal etwas mit functools rum spielen und ein paar Code Zeilen einsparen.

http://github.com/defnull/bottle/commit ... 96c51a4057

Einige TemplateAdapter API Änderung sind in Arbeit. Unter Anderem werden die Template-Lookups etwas intelligenter und Endungen, die von *.tpl abweichen, werden dann auch funktionieren. Es ist allerdings echt ein Krampf, wenn man sich die Adapter mal anschaut. Kein Template-System gleicht den anderen. Jeder macht sein Ding. Die APIs sind völlig verschieden und teilweise auch konzeptionell völlig inkompatibel. Aber genau dazu sind Adapter ja da: Das Ganze zu vereinheitlichen.
Bottle: Micro Web Framework + Development Blog
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Ah, hab dir einen pull-request aufgehalst :oops:
Wie kann ich denn mein Fork auf die aktuelle Version bringen?

Sollte es nicht @functools.wraps heißen (+@)?
[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]
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

jbs hat geschrieben:Ah, hab dir einen pull-request aufgehalst :oops:
Wie kann ich denn mein Fork auf die aktuelle Version bringen?
Wenn du deine eigenen Änderungen behalten willst "git rebase". Aber Vorsicht, das verändert deine History, was ekelige Nebenwirkungen haben kann (doku unbedingt vorher lesen)
jbs hat geschrieben:Sollte es nicht @functools.wraps heißen (+@)?
Ja, sollte es. Ich glaub, den Bug hätte ich nie bemerkt ;) Danke
Bottle: Micro Web Framework + Development Blog
zoxzox3
User
Beiträge: 14
Registriert: Dienstag 26. Januar 2010, 18:21

File Uploads don't work.

Code: Alles auswählen

from bottle import run, route, request, debug

@route('/')
def main():
    return """<html><body>
<form action="/upload" method="post" enctype="multipart/form-data">
  <input name="datafile" type="file" />
  <input type=submit value="OK" />
</form>
</body></html>"""

@route('/upload', method='POST')
def do_upload():
    df = request.POST.get('datafile')
    return df.read()

debug(True)
run(host='', port=8080, reloader=True)
result:

Code: Alles auswählen

Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/bottle-0.6.4-py2.6.egg/bottle.py", line 309, in __call__
    output = handler(**args)
  File "/src/test1.py", line 16, in do_upload
    return df.read()
  File "/usr/lib/python2.6/cgi.py", line 522, in __getattr__
    raise AttributeError, name
AttributeError: read
: python2.6
zoxzox3
User
Beiträge: 14
Registriert: Dienstag 26. Januar 2010, 18:21

Code: Alles auswählen

@route('/upload', method='POST')
def do_upload():
    df = request.POST.get('datafile')
    return df.value
this work, but loaded datafile in memory
zoxzox3
User
Beiträge: 14
Registriert: Dienstag 26. Januar 2010, 18:21

variant for loaded

Code: Alles auswählen

@route('/upload', method='POST')
def do_upload():
    df = request.POST.get('datafile')
    open('uploads/111.txt','wb').write( df.file.read() )
    redirect('/',302)
:)
zoxzox3
User
Beiträge: 14
Registriert: Dienstag 26. Januar 2010, 18:21

wiki by bottle in 23 minuten
http://lega.selfip.com/page/23 (video 33Mb, Host ist nicht verfügbar, in der Nacht)
:)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

zoxzox3 hat geschrieben:wiki by bottle in 23 minuten
http://lega.selfip.com/page/23 (video 33Mb, Host ist nicht verfügbar, in der Nacht)
:)
Ich würds ja mirrorn, aber der Host ist nicht verfügbar ;)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
zoxzox3
User
Beiträge: 14
Registriert: Dienstag 26. Januar 2010, 18:21

error redirect

Kunde öffnet die Seite "domen.com", es apache-Proxy, der leitet die Anfragen an "host_local", die web_bottle.
Funktion bottle.redirect('/'), gesetzt location = 'host_local/', und richtig location = 'domen.com/'

diff

Code: Alles auswählen

Index: bottle.py
===================================================================
--- bottle.py	(revision )
+++ bottle.py	(working copy)
@@ -755,10 +755,12 @@
     raise HTTPError(code, text)
 
 
-def redirect(url, code=303):
+def redirect(url, code=303, absoluteurl=True):
     """ Aborts execution and causes a 303 redirect """
-    scriptname = request.environ.get('SCRIPT_NAME', '').rstrip('/') + '/'
-    location = urljoin(request.url, urljoin(scriptname, url))
+    if absoluteurl:
+        scriptname = request.environ.get('SCRIPT_NAME', '').rstrip('/') + '/'
+        location = urljoin(request.url, urljoin(scriptname, url))
+    else: location = url
     raise HTTPResponse("", status=code, header=dict(Location=location))
  
Antworten