Seite 11 von 30

Verfasst: Donnerstag 1. Oktober 2009, 15:02
von stuhlbein
Defnull hat geschrieben:
stuhlbein hat geschrieben:Update durchgeführt, aber leider derselbe fehler =/
Versuch mal bitte bottle.debug(True) um komplette Stack Traces zu bekommen. Das grenzt den Fehler besser ein. Kann es sein, das in deinem Template ein Fehler ist? Kannst du mit dein Template mal schicken?
Am template kann es garnicht liegen, es steht nämlich nur "hello, world!" drin =þ

Aber hier der komplette Traceback:

Code: Alles auswählen

Traceback (most recent call last):
  File "build/bdist.linux-i686/egg/bottle.py", line 222, in __call__
    output = handler(**args)
  File "/home/nil/html/cgi/go.py", line 25, in index
    return template('index')
  File "build/bdist.linux-i686/egg/bottle.py", line 650, in template
    TEMPLATES[template] = template_adapter.find(template)
  File "build/bdist.linux-i686/egg/bottle.py", line 566, in find
    if os.path.isfile(path % name):
TypeError: not all arguments converted during string formatting
defnull hat geschrieben:
stuhlbein hat geschrieben:Ich find in der gesamten Doku keine möglichkeit eigene HTTP-Header abzusenden, sprich, sowas wie "Location: http://foo.bar/baz.html?p=moo" - Ist das einfach nur gut versteckt, oder gibts das (noch) garnicht? ^^
Stimmt, das ist noch undokumentiert. Aber es geht:

Code: Alles auswählen

  bottle.response.header['Location'] = "http://foo.bar/"
  bottle.response.status = 307
  # oder besser:
  bottle.redirect("http://foo.bar/")
Cool, danke =D

Verfasst: Donnerstag 1. Oktober 2009, 15:05
von Defnull
Laut Traceback ist das noch die alte, fehlerhafte Version. template_adapter.find() sollte nicht mehr vor kommen.

easy_install -U bottle

Verfasst: Donnerstag 1. Oktober 2009, 15:41
von jbs
Um mal ein wenig klug zu scheissen (schreibt sich das so?):
pep 257 hat geschrieben:The docstring is a phrase ending in a period. It prescribes the function or method's effect as a command ("Do this", "Return that"), not as a description; e.g. don't write "Returns the pathname ...".
Ich hab das in den Bottle Docstrings jedoch entdeckt :)


Alternativ könnte man den github Bucktracker zum Verwalten der fehlenden Funktionen verwenden, oder nicht?

Verfasst: Donnerstag 1. Oktober 2009, 16:38
von Dauerbaustelle
pep 257 hat geschrieben:The docstring is a phrase ending in a period. It prescribes the function or method's effect as a command ("Do this", "Return that"), not as a description; e.g. don't write "Returns the pathname ...".
Finde ich nicht gut. Vor allem wenn man mit APIs zu tun hat, ist die beschreibende Form ("returns") imho angebrachter, da mit der "return"-Form suggeriert wird, dass man Einfluss auf die Schnittstelle hätte.

Verfasst: Donnerstag 1. Oktober 2009, 16:40
von Dav1d
Defnull es funktioniert ;), zwar mit schwierigkeiten aber es geht :), so wie in der Doku beschriben

Code: Alles auswählen

from bottle import route, default_app
from google.appengine.ext.webapp import util 

@route('/')
def hello():
    return "Hello World!"

util.run_wsgi_app(default_app())


Verfasst: Donnerstag 1. Oktober 2009, 16:50
von stuhlbein
Defnull hat geschrieben:Laut Traceback ist das noch die alte, fehlerhafte Version. template_adapter.find() sollte nicht mehr vor kommen.

easy_install -U bottle
Ich bin mir nicht sicher ob du verstanden hast, dass ich das bereits tat:

Code: Alles auswählen

bottle 0.6.2 is already the active version in easy-install.pth
Mir ist auch aufgefallen, dass die %s's in bottle.TEMPLATE_PATH nichtmehr vorhanden sind... soll das so sein?
Jedenfalls findet bottle einfach die index.tpl nicht...

Verfasst: Freitag 2. Oktober 2009, 16:18
von Dav1d
Ich hab ein großer Problem mit den Templates,

Template:

Code: Alles auswählen

%items = ['Halo', 'f']
<h1>Hello {{username}}</h1>
<p>How are you?</p>
Ausgabe:

Code: Alles auswählen

Error 500: Internal Server Error

Sorry, the requested URL "/template/hello/MyUser" caused an error.
Unhandled Exception: SyntaxError('invalid syntax', ('./hello_template.tpl', 1, 22, "items = ['Halo', 'f']\r\n")) 
Liegts an mir oder an Google?, ich habs schon mit einem von deinen Templates von der Bottle-Page versucht, sobald ein %Python-Code drinen ist, gehts nicht mehr

Verfasst: Freitag 2. Oktober 2009, 19:22
von nemomuk
So, habe mich dem Modified Since Problem angenommen und die "parse_date" Funktion etwas verschönert. Das Problem mit dem Abstürzen ist damit behoben. Bitte auf die "import"s in den Funktionen achten.
http://paste.pocoo.org/show/142546/

Verfasst: Freitag 2. Oktober 2009, 19:47
von stuhlbein
SchneiderWeisse hat geschrieben:So, habe mich dem Modified Since Problem angenommen und die "parse_date" Funktion etwas verschönert. Das Problem mit dem Abstürzen ist damit behoben. Bitte auf die "import"s in den Funktionen achten.
http://paste.pocoo.org/show/142546/
Hast du den code eigentlich auch mal getestet? Spätestens dann wäre dir nämlich der tippfehler in zeile 15 aufgefallen. Und du importierst zweimal dieselbe funktion aus dem datetime modul, wieso packst du diese Imports nicht einfach an den kopf des diffs (ja, auch das ist valider code)?

Verfasst: Freitag 2. Oktober 2009, 21:28
von nemomuk
<ironie>Ja, du bist ja ein ganz ein schlaues Kerlchen, Gratulation!</ironie>
Der Fehler in Zeile 15 ist anscheinend ein Tippfehler, der korrigiert werden muss, allerdings ist dieser auch im aktuellen Bottle Release (also nicht von mir, wobei das nichts zur Sache tut von wem dieser ist).
Zu den imports: Ich wollte eventuelle Konflikte vermeiden und habe diese extra in die Funktionen gepackt. Dass diese später da rausgeholt werden versteht sich im Normalfall von selbst (nicht um sonst habe ich explizit auf die imports hingewiesen) - das kann defnull allerdings besser entscheiden.

Nebenbei: datetime.datetime ist keine Funktion.

Verfasst: Freitag 2. Oktober 2009, 21:34
von Defnull
In release 0.6.2 ist echt der Wurm drin. Bitte etwas Geduld, aber vielleicht schaffe ich heute Abend noch alles zu korrigieren.

Verfasst: Freitag 2. Oktober 2009, 21:49
von nemomuk
Ich würde gerne mit Github arbeiten, das würde es sehr wahrscheinlich leichter für uns beide machen. Momentan funktioniert aber das Mercurial Plugin für Git nicht.

Verfasst: Freitag 2. Oktober 2009, 22:56
von Defnull
SchneiderWeisse hat geschrieben:So, habe mich dem Modified Since Problem angenommen und die "parse_date" Funktion etwas verschönert. Das Problem mit dem Abstürzen ist damit behoben. Bitte auf die "import"s in den Funktionen achten.
http://paste.pocoo.org/show/142546/
Das mit email.utils.parsedate_tz ist eine gute Idee, die habe ich übernommen. Ich arbeite aber lieber mit Epoch als mit datetime Objekten. Inzwischen liefert parse_date die Sekunden seit UTC Epoch (1970) zurück, genau wie es time.time() und os.stat().st_mtime tun. Das spart mir auch den Import von datetime.

Warum bei dir gleich der komplette Interpreter ab stürzt, weis ich übrigens immer noch nicht. Alle Exceptions werden von Bottle ab gefangen. Ein 'Absturtz' von Python kann ich mir daher nur mit einem Fehler in einem Python C-Modul erklären. Die größte Änderung in deiner Version ist, das du das time-Modul raus geworfen hast. Verursacht das bei dir die Abstürze?

Verfasst: Freitag 2. Oktober 2009, 23:18
von Defnull
Dav1d hat geschrieben:Ich hab ein großer Problem mit den Templates,
Liegts an mir oder an Google?, ich habs schon mit einem von deinen Templates von der Bottle-Page versucht, sobald ein %Python-Code drinen ist, gehts nicht mehr
Das kann ich hier leider nicht reproduzieren. Der Fehler kommt, weil im übersetzten Template ein Syntax Fehler ist. Da dein Template richtig aus sieht, muss beim übersetzen was schief gegangen sein. Du kannst dir mit folgendem Code den übersetzten Template-Quelltext aus geben lassen. Vielleicht hilft das weiter.

Code: Alles auswählen

from bottle import SimpleTemplate
tpl = """%items = ['Halo', 'f']
<h1>Hello {{username}}</h1>
<p>How are you?</p>"""
print SimpleTemplate('fake').translate(tpl)
Das ergibt bei mir:

Code: Alles auswählen

items = ['Halo', 'f']
_stdout.extend(['<h1>Hello ', str(username), '</h1>\n'])
_stdout.append('<p>How are you?</p>')

und das ist völlig korrekt.

Verfasst: Freitag 2. Oktober 2009, 23:21
von Defnull
stuhlbein hat geschrieben:
Defnull hat geschrieben:Laut Traceback ist das noch die alte, fehlerhafte Version. template_adapter.find() sollte nicht mehr vor kommen.

easy_install -U bottle
Ich bin mir nicht sicher ob du verstanden hast, dass ich das bereits tat:

Code: Alles auswählen

bottle 0.6.2 is already the active version in easy-install.pth
Mir ist auch aufgefallen, dass die %s's in bottle.TEMPLATE_PATH nichtmehr vorhanden sind... soll das so sein?
Jedenfalls findet bottle einfach die index.tpl nicht...
PyPi hatte etwa 10 Minuten lang eine defekten Release. Genau den scheinst du dir gezogen zu haben. Ich werde heute Abend (nach ausgiebigen Tests) eine neue Version veröffentlichen. Alternativ kannst du auch deine Version manuell löschen (easy_install hat dummer weise keine uninstall-Funktion) und den Release neu ziehen.

Ich werde demnächst deutlich mehr testen müssen, bevor ich einen Release raus schicke... Bottle wird inzwischen von zu vielen Leuten benutzt, als das ich mir sowas wie 0.6.2 noch öfters erlauben könnte. Sorry dafür.

Verfasst: Samstag 3. Oktober 2009, 00:12
von nemomuk
Irgendwas hat in der parse_date Funktion anscheinend nicht funktioniert. Was ist mir unerklärlich, Python ist ganz ohne irgendwas abgestürzt. Aber jetzt gehts ja.

Verfasst: Samstag 3. Oktober 2009, 00:45
von Defnull
So, neuer Release ist draußen. Etwas gezwungen, da 0.6.2 echt kaputt war. Hoffentlich konnte ich die meisten Löcher stopfen. Ein Trost-Feature gibt es aber: Template Dekoratoren!!!

Code: Alles auswählen

# Templates
# Lets return a template named "test_template.tpl"
# and fill the placeholder "test" with the string "Hello World"
@bottle.route('/template')
def template():
  return bottle.template('test_tempate', test='Hello World')

# View decorator
# This example does the same, as the above
@bottle.route('/view')
@bottle.view('test_template')
def view():
  return dict(test='Hello World')

# JSON trick
# The @route decorator can be applied more than once, so we can use this trick:
# A dict-returning handler is first bound to "/json/trick". Thanks to the
# autojson feature, the dict will be returned as a JSON response. Then we apply
# a template decorator and bind this decorated version of the handler to another
# route ("/html/trick"). A call to the new route will return a template, filled
# with the same data as the json route would return.
@bottle.route('/html/trick')  # Returns a template (html)
@bottle.view('test_template') # Only affects the routes above
@bottle.route('/json/trick')  # Returns JSON thanks to autojson
def json_trick():
  return dict(test='Hello World')
Sie sind aber noch nicht durch Tests ab gedeckt und noch undokumentiert, also Vorsicht ;)

Verfasst: Samstag 3. Oktober 2009, 16:12
von stuhlbein
SchneiderWeisse hat geschrieben:<ironie>Ja, du bist ja ein ganz ein schlaues Kerlchen, Gratulation!</ironie>
Der Fehler in Zeile 15 ist anscheinend ein Tippfehler, der korrigiert werden muss, allerdings ist dieser auch im aktuellen Bottle Release (also nicht von mir, wobei das nichts zur Sache tut von wem dieser ist).
Zu den imports: Ich wollte eventuelle Konflikte vermeiden und habe diese extra in die Funktionen gepackt. Dass diese später da rausgeholt werden versteht sich im Normalfall von selbst (nicht um sonst habe ich explizit auf die imports hingewiesen) - das kann defnull allerdings besser entscheiden.

Nebenbei: datetime.datetime ist keine Funktion.
Ich weiss nicht wieso du dich aufregst, ich hab dich ja nur drauf hingewiesen ;)

Anyway: Das problem mit den Templates hab ich nach wie vor nicht lösen können. Meine momentane Daten-struktur sieht so aus:

Code: Alles auswählen

    /                 = webroot
    |-- home.ws       = WSGI skript, wird als `http://127.0/home.ws/<...>` ausgeführt
    |-- /views        = templates Ordner
    |--+-- index.tpl  = das besagte template
       |-- foobar.tpl = ein weiteres template

home.ws:

Code: Alles auswählen

import sys
import bottle
from bottle import route, template
bottle.debug(True)

@route('/')
@route('/index.html')
def index():
    return template('index')

application = bottle.default_app()
Und nachwievor kommt der Fehler, "Template (index) not found.", obwohl die Datei existiert, und vom Webserver lesbar ist.
Ohne templates ist das ganze nicht sehr brauchbar... =/

Verfasst: Samstag 3. Oktober 2009, 16:44
von Defnull
Ahh, du nutzt mod_wsgi?

Unter Apache-mod_wsgi ändert sich das Arbeitsverzeichnis (./) und die relativen Pfade in bottle.TEMPLATE_PATH zeigen plötzlich ins Leere. Mögliche Workarounds sind:

Code: Alles auswählen

os.chdir(os.path.dirname(__FILE__))
# oder
bottle.TEMPLATE_PATH += [os.path.join(os.path.dirname(__FILE__),'views')]
Leider gibt es dafür keine Patentlösung, da Bottle schlicht nicht weis, von welchem Modul es auf gerufen wird. Ich finde die Lösung mit os.chdir() am saubersten.

Verfasst: Samstag 3. Oktober 2009, 17:14
von stuhlbein
Defnull hat geschrieben:Ahh, du nutzt mod_wsgi?

Unter Apache-mod_wsgi ändert sich das Arbeitsverzeichnis (./) und die relativen Pfade in bottle.TEMPLATE_PATH zeigen plötzlich ins Leere. Mögliche Workarounds sind:

Code: Alles auswählen

os.chdir(os.path.dirname(__FILE__))
# oder
bottle.TEMPLATE_PATH += [os.path.join(os.path.dirname(__FILE__),'views')]
Leider gibt es dafür keine Patentlösung, da Bottle schlicht nicht weis, von welchem Modul es auf gerufen wird. Ich finde die Lösung mit os.chdir() am saubersten.
Ich hab beides ausprobiert, leider ohne erfolg, und mit selber fehlermeldung...

EDIT:
mit absolutem pfad geht es, aber warum weder das ändern von bottle.TEMPLATE_PATH noch os.chdir() funktionieren, kann ich auch nicht wirklich sagen.

hier das nun veränderte skript:

Code: Alles auswählen

import sys
import os
import bottle
from bottle import route, template, view
bottle.debug(True)
os.chdir(os.path.dirname(__file__))
bottle.TEMPLATE_PATH += [os.path.join(os.path.dirname(__file__),'views')]

@route('/')
@route('/index.html')
def index():
    return template(os.path.join(os.path.dirname(__file__),'views/index.tpl'))

application = bottle.default_app()
EDIT2:
ich hab einen unschönen, aber funktionierenden workaround gefunden =)

Code: Alles auswählen

tpl = lambda s: template(os.path.join(os.path.dirname(__file__),'views/%s.tpl' % s))
Ist aber halt eher unschön =/