Bottle: Micro Web Framework

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

snafu: Toll, nich? :D Bin voll stolz drauf. Aber Archlinux war diesmal schneller ;)

Dav1d: Der Routing-Syntax ':filename' matcht auf alles außer '/'. Wenn du Unterverzeichnisse mit einbinden willst, musst du so was hier einbauen:

Code: Alles auswählen

@bottle.route('/static/:filename#.*#')
def static_file(filename):
    bottle.send_file(filename, root='/path/to/static/files')
Bottle: Micro Web Framework + Development Blog
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

OK Danke, ich werds morgen probieren jetzt geh ich erst mal "bowl'n"
the more they change the more they stay the same
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Sehr schön es funktioniert einwandfrei :). Danke

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

from bottle import route, run, template, send_file

@route('/')
def index():
    return template('test', navi={'Main' : ['Test', 'Let\'s see', 'I do not know'], 'Bla' : ['asd', 'asdddd', 'ert']}, content='asd ')

@route('/data/:filename#.*#')
def static_file(filename):
    send_file(filename, root='C:/Python26/code/projekte/workspace/reader/webpanel/data') 

run() 
the more they change the more they stay the same
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Cool, damit wäre endlich bestätigt, das send_file auch unter Windows funktioniert. Das konnte ich selbst nämlich noch nie testen ;)
Bottle: Micro Web Framework + Development Blog
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Kann Bottle eigentlich auch mit Raw Post Data umgehen? Ich arbeite mit einer Javascript Bibliothekt, die XML Anfragen an den Server mittels Raw Post sendet. Wegen der XMLHttpRequest Sicherheitsbeschränkungen muss ich einen Proxy dazwischenschalten. Den setze ich gerade (mit PHP) um, und mir stellt sich die Frage, inwieweit ich die Prozessierung der Daten mittels Bottle weiterverarbeiten kann.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Die GitHub Version erlaubt den Zugriff über bottle.request.body
Bottle: Micro Web Framework + Development Blog
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Danke ...
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Hmpf, Geograf, bleib bei deinen Leisten. Ich muss schon wieder was fragen:

Es geht immer noch um den Post Request: Ich benutze dynamische Routen, um den Post Request zu verarbeiten. Jetzt scheint es mir so, als ob dem dyn. Teil direkt der Inhalt des Post Requests angehängt wird. Denn ein Teil der Fehlermeldung (ein 404), die ich bekomme lautet
The requested URL /ogc/service/strassederroemerHTTP/1.1 was not found on this server.
und die Route in Bottle lautet
/ogc/service/:name
Normalerweise sollte das nur strassederroemer sein. Es scheint mir also so, als ob der erste Header vom Post Request bis zum Zeilenumbruch an den dynamsischen Teil der URL angehängt wird. Liege ich da richtig? Wenn ja, kann ich überhaupt dynamische Routen benutzen?

Hier mal meine passende Routenfunktion:

Code: Alles auswählen

@bottle.route('/wms/:name')
@bottle.route('/service/:name')
def ogc(name):
    """
    Standard OWS Anfrage Route.
    
    """
    try:
        (bottle.response.header['Content-Type'],
            content)  = ogc_request(map_files[name])
        return content
    except KeyError:
        bottle.abort(404)
und die Funktion ogc_request

Code: Alles auswählen

def ogc_request(map_file):
    """
    Behandelt den OWS Request und übergibt ihn an das mapscript Objekt
    Der Output wird gepuffert und nach content und content_type getrennt
    zurückgegeben.
    
    """
    ows_request = mapscript.OWSRequest()
   
    if bottle.request.method == 'POST':
        pass
        # TODO 
    elif bottle.request.method == 'GET':
        for key, value in bottle.request.params.items():
            ows_request.setParameter(key, value)
    else:
        logging.debug('not able to identify request method')
        bottle.abort(500, 'Request method not identifiable')
        
    # outputbuffer starten
    mapscript.msIO_installStdoutToBuffer()
    
    try:
        ows_map = mapscript.mapObj(map_file)
    except IOError:
        bottle.abort(404, 'Mapfile not found')
    
    try:
        ows_map.OWSDispatch(ows_request)
    except:
        bottle.abort(400, 'Error while dispatching OWS request')
    
    content_type = mapscript.msIO_stripStdoutBufferContentType()
    content = mapscript.msIO_getStdoutBufferBytes()

    return (content_type, content)
Vielen Dank

Frank
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

frabron hat geschrieben:Ich benutze dynamische Routen, um den Post Request zu verarbeiten. Jetzt scheint es mir so, als ob dem dyn. Teil direkt der Inhalt des Post Requests angehängt wird.
Natürlich nicht. Für die Route wird das verwendet, was der WSGI Gateway in die environ['PATH_INFO'] Variable schreibt. Wenn da Mist drin steht, liegt das entweder am WSGI Gateway, an einem eventuell vorgeschalteten externen HTTP Server, am Client oder an einer Middleware.

Die Fehlermeldung "... was not found on this server." stammt übrigens nicht von Bottle. Dieser Wortlaut kommt in Bottle nicht vor.
Bottle: Micro Web Framework + Development Blog
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

frabron hat geschrieben:
The requested URL /ogc/service/strassederroemerHTTP/1.1 was not found on this server.
An der URL hängt wirklich ohne durch ein Leerzeichen getrennt ein HTTP/1.1 dran? Da erzeugt ein Client aber eine echt kaputte HTTP-Anfrage. Das kann doch kein normaler Browser sein. Identifiziere den Client und repariere ihn. Und wieso akzeptiert da ein Server ein GET, dem dann ja das Protokoll fehlen würde... oder ich glaube, er fasst das als ein HTTP/0.9-Request auf, würde dann aber in der folgenden Zeile keinen HTTP-Header erwarten. Wie auch immer, ein Client, der kein korrektes HTTP spricht, kann keine korrekte Antwort von Bottle oder sonst wem erwarten.

Stefan
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Danke für die Antworten soweit. Das hilft mir denke ich schon mal weiter. Den "Client" hab ich selber verbrochen. Das ist ein PHP Skript, das als Proxy für Ajax Requests dienen soll. Bisher waren das halt immer nur GET Anfragen, die sich leicht weiterleiten liessen.
"... was not found on this server." stammt übrigens nicht von Bottle
ist evt. schon mal eine Spur.

Danke nochmals

Frank

So:

Ein Leerzeichen im Proxy Skript und "method='POST'" in Bottle weiter klappts auch mit dem Nachbarn, bzw. mit dem Post Request
zoxzox3
User
Beiträge: 14
Registriert: Dienstag 26. Januar 2010, 18:21

error in bottle.jinja2_template
code:

Code: Alles auswählen

# coding: utf-8
from bottle import jinja2_template as template
print template('test1')
test1.tpl (utf-8 ru chars)

Code: Alles auswählen

Тест строка
error:

Code: Alles auswählen

>python test1.py 
Traceback (most recent call last):
  File "test1.py", line 5, in <module>
    print template('test1')
  File "/usr/local/lib/python2.6/dist-packages/bottle-0.6.4-py2.6.egg/bottle.py", line 974, in jinja2_template
    return template(tpl_name, **kargs)
  File "/usr/local/lib/python2.6/dist-packages/bottle-0.6.4-py2.6.egg/bottle.py", line 955, in template
    TEMPLATES[tpl] = template_adapter(name=tpl, lookup=lookup)
  File "/usr/local/lib/python2.6/dist-packages/bottle-0.6.4-py2.6.egg/bottle.py", line 758, in __init__
    self.prepare()
  File "/usr/local/lib/python2.6/dist-packages/bottle-0.6.4-py2.6.egg/bottle.py", line 834, in prepare
    self.tpl = self.env.get_template(self.filename)
  File "/usr/local/lib/python2.6/dist-packages/Jinja2-2.2.1-py2.6.egg/jinja2/environment.py", line 552, in get_template
    template = self.loader.load(self, name, self.make_globals(globals))
  File "/usr/local/lib/python2.6/dist-packages/Jinja2-2.2.1-py2.6.egg/jinja2/loaders.py", line 108, in load
    code = environment.compile(source, name, filename)
  File "/usr/local/lib/python2.6/dist-packages/Jinja2-2.2.1-py2.6.egg/jinja2/environment.py", line 435, in compile
    source = self._parse(source, name, filename)
  File "/usr/local/lib/python2.6/dist-packages/Jinja2-2.2.1-py2.6.egg/jinja2/environment.py", line 378, in _parse
    return Parser(self, source, name, filename).parse()
  File "/usr/local/lib/python2.6/dist-packages/Jinja2-2.2.1-py2.6.egg/jinja2/parser.py", line 30, in __init__
    self.stream = environment._tokenize(source, name, filename, state)
  File "/usr/local/lib/python2.6/dist-packages/Jinja2-2.2.1-py2.6.egg/jinja2/environment.py", line 409, in _tokenize
    source = self.preprocess(source, name, filename)
  File "/usr/local/lib/python2.6/dist-packages/Jinja2-2.2.1-py2.6.egg/jinja2/environment.py", line 403, in preprocess
    self.extensions.itervalues(), unicode(source))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)
zoxzox3
User
Beiträge: 14
Registriert: Dienstag 26. Januar 2010, 18:21

zoxzox3 hat geschrieben:error in bottle.jinja2_template
and mako not work

this work code:

Code: Alles auswählen

from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('views'))
print env.get_template('test1.tpl').render()
zoxzox3
User
Beiträge: 14
Registriert: Dienstag 26. Januar 2010, 18:21

zoxzox3 hat geschrieben:error in bottle.jinja2_template
error find:

Bottle 0.6.4:

Code: Alles auswählen

class Jinja2Template(BaseTemplate):
    def loader(self, name):
        if not name.endswith(".tpl"):
            for path in self.lookup:
                fpath = os.path.join(path, name+'.tpl')
                if os.path.isfile(fpath):
                    name = fpath
                    break
        f = open(name)
        try: return f.read()
        finally: f.close()
for read file, need decode from utf8 to unicode, line 847:

Code: Alles auswählen

        try: return f.read().decode('utf-8')
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Thanks for the bug report. I patched the guthub version.
http://github.com/defnull/bottle/commit ... 8bb9fa84c6
Bottle: Micro Web Framework + Development Blog
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Ich hätte nicht gedacht, das so ein Paypal-Spenden-Button wirklich etwas bringt, aber Bottle hat gerade seine erste Spende bekommen :D Ich freu mich wie ein Schneekönig ^_^
Bottle: Micro Web Framework + Development Blog
BlackJack

Gratulation! :-) Und, hast Du jetzt ausgesorgt und kannst Dich auf einer eigenen Südseeinsel zur Ruhe setzen!? :-D
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Nach Abzug der Paypal-Gebühren und Umrechnung in Euro bleiben etwa 6,50€ übrig ;) Der Dollar ist halt gerade nicht so prall. Aber darum geht es ja auch gar nicht, sondern: Jemand schenkt mit 10$ weil er meine Software toll findet :D *freu*
Bottle: Micro Web Framework + Development Blog
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Defnull hat geschrieben:Thanks for the bug report. I patched the guthub version.
http://github.com/defnull/bottle/commit ... 8bb9fa84c6
Wäre es nicht sinnvoll, das Encoding frei wählbar zu machen? Oder gilt per Konvention bei Dir, dass alle Templates utf-8 codiert sein müssen?
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Es ist keine perfekte Lösung, aber für eine Bessere brauche ich mehr Zeit. Die Sache ist nämlich gar nicht mal so einfach und wird API Änderungen mit sich bringen.

SimpleTemplate arbeitet intern mit Bytes; Alle anderen Systeme arbeiten mit Unicode. Früher oder später werden ich SimpleTemplate wohl auch auf Unicode umstellen müssen, da es spätestens mit Python 3 die einzig sinnvolle Lösung sein wird. In diesem Zuge wird sich die API für die Template-Adapter etwas ändern. Es muss eine Möglichkeit geben, die Kodierung der Template-Datei und die Kodierung der Byte String Template Variablen anzugeben. Die Frage der Output-Kodierung ist bereits durch Bottles eigene Unicode Unterstützung gelöst.

Andererseits finde ich es unsinnig, Templates erst in Unicode umzuwandeln, alle Variablen (die bei Python 2.x meistens Byte Strings sind) ebenfalls anzupassen, um anschließend alles wieder in Bytes zu konvertieren. Wenn Input- und Output-Kodierung identisch sind (meistens der Fall: utf8), kann man sich ne Menge Arbeit sparen, wenn die Templates intern als Byte-Strings verarbeitet werden. Dann müssen nämlich nur die relativ seltenen Unicode Input Variablen konvertiert werden.

Daher werde ich SimpleTemplate mal für Unicode implementieren und das mit dem Original vergleichen, bevor ich mich endgültig entscheide.

Bis dahin ist utf-8 ein sinnvoller Standard.
Bottle: Micro Web Framework + Development Blog
Antworten