
| Název školy: | Vyšší odborná škola a Střední průmyslová škola, Božetěchova 3 |
| Autor: | Ing. Marek Nožka |
| Anotace: | web framework Bottle.py |
| Vzdělávací oblast: | Informační a komunikační technologie |
| Předmět: | Počítačové sítě a komunikační technika (PSK) |
| Tematická oblast: | Operační systém Linux/Unix |
| Výsledky vzdělávání: | Žák vytvoří jednoduchou webovou aplikaci pomocí Bottle.py |
| Klíčová slova: | Linux, Unix, Apache, Python, Bottle.py, web framework |
| Druh učebního materiálu: | Online vzdělávací materiál |
| Typ vzdělávání: | Střední vzdělávání, 4. ročník, technické lyceum |
| Ověřeno: | VOŠ a SPŠE Olomouc; Třída: 4L |
| Zdroj: | Vlastní poznámky, Vilém Vychodil: Linux Příručka českého uživatele |
Webové aplikace napsané v Pythonu mají sklon „vlastnit“ celý adresář (nebo i celou doménu). Přiřazování konkrétních URL určitému kódu je tedy o něco pružnější a je obvykle spravováno tzv. routingem1.
Někdy se ale přece jen hodí mít některé části webu umístěny ve statických souborech. Typickým příkladem můžou být obrázky nebo CSS. V těchto případech použijeme následující kód.
from bottle import static_file
@route('/static/<filename>')
def server_static(filename):
return static_file(filename, root='/path/to/your/static/files')
`--> stáhnout
nebo lépe:
@route('/static/<filepath:path>')
def server_static(filepath):
return static_file(filepath, root='/path/to/your/static/files')
`--> stáhnout
Funkce static_file() je obecně doporučovanou cestou pro předávání statický
souborů. Funkce
může automaticky odhadnout MIME
daného souboru. Ale můžeme to i přímo určit.
from bottle import static_file
@route('/images/<filename:re:.*\.png>')
def send_image(filename):
return static_file(filename, root='/path/to/image/files', mimetype='image/png')
@route('/static/<filename:path>')
def send_static(filename):
return static_file(filename, root='/path/to/static/files')
`--> stáhnout
Prohlížeče většinu souboru jejichž typ znají zobrazí. Je to například PDF nebo JPEG. Dialog pro stažení lze vynutit pomocí parametru
download. Ten může obsahuje jméno souboru. Pokud se rozhodneme ho nechat
stejné jako na serveru stačí hodnotu nastavit na True.
@route('/download/<filename:path>')
def download(filename):
return static_file(filename, root='/path/to/static/files', download=filename)
`--> stáhnout
Vytvářet stránku vždy přímo v obslužné funkci by bylo hodně nepohodlné. Proto Bottle přichází s jednoduchým šablonovacím systémem. Pokud ale tento vestavěný šablonovací systém nedostačuje je možné použít robustnější řešení jako je mako, jinja2 nebo cheetah.
Bottle šablony hledá v adresáři ./views/ (respektive v seznamu
bottle.TEMPLATE_PATH).
Šablona může vypadat například takto:
%if name == 'World':
<h1>Hello {{name}}!</h1>
<p>This is a test.</p>
%else:
<h1>Hello {{name.title()}}!</h1>
<p>How are you?</p>
%end
`--> stáhnout
A následující kód slouží pro použití šablony.
@route('/hello')
@route('/hello/<name>')
def hello(name='World'):
return template('hello_template', name=name)
`--> stáhnout
Alternativní způsob rendrování šablony je decorator @view. Obslužná funkce
potom musí vracet dict s proměnnými a jejich hodnotami.
@route('/hello')
@route('/hello/<name>')
@view('hello_template')
def hello(name='World'):
return dict(name=name)
`--> stáhnout
Pokud se něco pokazí Bottle automaticky zobrazí chybovou stránky. Chybovou stránku si ale můžeme pro konkrétní HTTP status code vytvořit sami.
Například status 404 říká, že dokument nelze nalézt:
from bottle import error
@error(404)
def error404(error):
return 'Nic tu není, jdi pryč'
`--> stáhnout
Pokud z nějakého důvodu chceme chybový stav programově vyvolat poslouží nám k
tomu funkce abort().
from bottle import route, abort
@route('/restricted')
def restricted():
abort(401, "Promiň, ale sem nesmíš.")
`--> stáhnout
@error(404)
def notFound(error):
r='<h1>'+error.status+'</h1>'
r+='<p>Sorry. Tady nic není</p><hr />'
r+='<p>'+error.body+'</p>'
return r
@route('/nic')
def nic():
abort(404,'bbbbeeeeeeeeeee')
`--> stáhnout
Vyzkoušejte si rozdíl v chování pro adresu /nic a /nejakablbost_nmfioewkwfjweioq
Funkce redirect() vyvolá status 303 See Other a přesměruje požadavek na
jinou stránku.
from bottle import redirect
@route('/spatna/url')
def wrong():
redirect("/spravna/url")
`--> stáhnout
Všechny HTTP hlavičky zaslané klientem (např. Referer, Agent or Accept-Language)
jsou dostupné
ve slovníkovém objektu request.headers.
@get('/req')
def req():
r='<pre>'
for k in request.headers.keys() :
r += k+':'+request.headers[k]+'\n'
r+='</pre>'
return r
`--> stáhnout
Pokud chceme zasáhnou do HTTP hlavičky,
kterou naše aplikace odesílá, použijeme objekt Response.
@route('/wiki/<page>')
def wiki(page):
response.set_header('Content-Language', 'en')
...
`--> stáhnout
Pokud má hlavička obsahovat více stejnojmenných polí použijeme kromě
metody .set_header() také metodu add_header.().
....
response.set_header('Set-Cookie', 'name=value')
response.add_header('Set-Cookie', 'name2=value2')
....
`--> stáhnout
Změna výchozího kódování se děje pomocí pole Content-Type. Výchozí hodnotu:
Content-Type: text/html; charset=UTF-8
... je možné změnit pomocí Response.content_type nebo přímo pomocí
Response.charset:
from bottle import response
@route('/iso')
def get_iso():
response.charset = 'ISO-8859-15'
return u'This will be sent with ISO-8859-15 encoding.'
@route('/latin9')
def get_latin():
response.content_type = 'text/html; charset=latin9'
return u'ISO-8859-15 is also known as latin9.'
`--> stáhnout
Některé informace se WSGI/CGI programu předávájí pomocí
proměnných prostředí. Je to například REQUEST_METHOD nebo REMOTE_ADDR.
@route('/my_ip')
def show_ip():
ip = request.environ.get('REMOTE_ADDR')
# or ip = request.get('REMOTE_ADDR')
# or ip = request['REMOTE_ADDR']
return template("Your IP is: {{ip}}", ip=ip)
`--> stáhnout
nebo
@get('/env')
def env():
r='<pre>'
for k in request.environ.keys() :
r += '<strong>'+k+'</strong>:'+str(request.environ[k])+'\n\n'
r+='</pre>'
return r
`--> stáhnout
Cookie je pojmenovaný kus textu uložené ve webovém prohlížeče. Cookie si
můžeme vyžádat přes request.get_cookie() a nastavit nové cookies pomocí
response.set_cookie():
@route('/hello')
def hello_again():
if request.get_cookie("visited"):
return "Vítej zpět! Je jezké, že jsi zase přišel"
else:
response.set_cookie("visited", "yes")
return "Nazdar! Vítam tě tu."
`--> stáhnout
Metoda response.set_cookie() přijímá řadu dalších pojmenovaných argumentů,
které řídí život a chování souborů cookie. Některé z nejběžnějších nastavení
jsou popsány v následující tabulce:
max_age |
Platnost cookie v sekundách. (default: None) |
expires |
Expirace: datetime objekt nebo UNIX timestamp. (default: None) |
domain |
Doména pro kterou cookie platí (default: aktuální doména). |
path |
Limituje cookie pro určitou cestu (default: /). |
secure |
Limituje cookie pro HTTPS spojení (default: off). |
httponly |
Zabrání Jabascriptu na straně klienta ve čtení cookie (default: off). |
Pokud není nastaven expires ani max_age, cookie vyprší na konci relace
prohlížeče.
Dále byste měli vzít v úvahu:
Více o routingu se dozvíte v oficiální dokumentaci na http://bottlepy.org/docs/dev/tutorial.html#request-routing a http://bottlepy.org/docs/dev/routing.html ↩