{ geekBlog }

a geeky blog about things

Reinvent the Wheel: Webframeworks (Teil 2)

am 9. Januar 2019 von cp

Als nächstes schauen wir uns GET-Paramter an und verwenden eine Python-Library, welche einem nahezu beliebig viele Aufgaben abnimmt, welche beim Erstellen einer eigenen Webanwendung anfällt: Werkzeug

Fangen wir direkt mit einem Beispiel an, bei welchem wir die Parameter aus der Umgebungsvariabel QUERY_STRING auslesen:

from werkzeug.serving import run_simple


def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html; charset=utf-8')])

    body = '<html><head><title>Reinvent web frameworks part 2 - 1st example</title></head><body>\n'
    qs = environ.get('QUERY_STRING', '')
    body += f'<pre>{qs}</pre>\n'
    body += '</body></html>\n'

    return [body.encode('utf-8')]


if __name__ == '__main__':
    run_simple('localhost', 8000, application)

Ruft man das Ganze nun mit folgendem Query auf:

http://localhost:8000/?foo=äöü&ä=ß

Erhält man (wenn man Glück hat) irgendwas kryptisches wie:

foo=%C3%A4%C3%B6%C3%BC&%C3%A4=%C3%9F

Oder schlimmeres.


Wenn man mag kann man sich nun selber um das Dekodieren kümmern oder auf eine Library verlassen. Im konkreten Fall würde ich eine Library präferieren, da uns dies in der Frage wie Webframeworks funktionieren weiterbringt. Wen es dennoch interessiert kann sich die beiden verwendeten Funktionen aus dem folgenden Beispiel anschauen.

Zuerst wird mit get_query_string zugesehen, dass das was man vom Browser erhält auch ASCII ist und andernfalls decodiert wird. In url_decode passiert dann die restliche Magie, welche aus den URL-Kodierten Zeichen UTF-8 macht und dafür sorgt, dass wir ein Dictionary zurückbekommen, in dem alle Werte stehen.

from werkzeug.serving import run_simple
from werkzeug.urls import url_decode
from werkzeug.wsgi import get_query_string


def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html; charset=utf-8')])

    body = '<html><head><title>Reinvent web frameworks part 2 - 2nd example</title><body><table>\n'
    for key, val in url_decode(get_query_string(environ)).lists():
        body += f'<tr><td>{key}</td><td>{val}</td></tr>\n'
    body += '</table></body></html>\n'

    return [body.encode('utf-8')]


if __name__ == '__main__':
    run_simple('localhost', 8000, application)