Bottle/Tutoriál
Bottle/Tutoriál
Tutoriál k pythonímu frameworku Bottle. Necháme se zpočátku inspirovat tutoriálem http://bottlepy.org/docs/dev/tutorial.html
Začněme experimentovat s jednosouborovou instalací:
01-nazdarek
editovat#!/usr/bin/python3
from bottle import route, run
@route('/nazdar')
def hello():
return "Nazdárek náš milý světe!"
run(host='localhost', port=8080, debug=True)
To co je v závorce za @route je cesta v URL, kam se má daná stránka umístit.
Dobře si povšimneme, že do webové stránky nepíšeme příkazem print, ale to, co chceme zobrazit, musíme dát do příkazu return.
Soubor uložíme do stejného adresáře pod jménem 01-nazdarek.py, přidělíme příslušná práva a spustíme:
chmod u+x 01-nazdarek.py
./01-nazdarek.py
Bottle v0.13-dev server starting up (using WSGIRefServer())... Listening on http://localhost:8080/ Hit Ctrl-C to quit.
Podíváme se na http://localhost:8080/nazdar a vidíme:
Nazdárek náš milý světe!
02-semtam
editovatWebová sajtna má zpravidla více stránek. Demonstrujeme si web, který má dvě stránky, umístěné na URL:
#!/usr/bin/env python3
from bottle import route, run
@route('/')
def root():
return "Tak jsme tady. Jdi <a href=\"tam\">tam!</a>"
@route('/tam')
def tam():
return "Tak tam jsme a jdeme zase <a href=\"/\">zpátky</a>..."
run(host='localhost', port=8080, debug=True)
Všimneme si, že jak se proklikáváme tam a zase zpátky, server nám za příkazovou řádkou, ze které jsme skript pustili, hlásí:
127.0.0.1 - - [02/Oct/2015 04:46:50] "GET / HTTP/1.1" 200 41 127.0.0.1 - - [02/Oct/2015 04:46:51] "GET /tam HTTP/1.1" 200 41 127.0.0.1 - - [02/Oct/2015 04:46:54] "GET / HTTP/1.1" 200 41 127.0.0.1 - - [02/Oct/2015 04:47:59] "GET /tam HTTP/1.1" 200 41
03-dyn_cesty.py
editovatJako dynamické cesty se označují cesty v URL, které nemusí být předem dané, ale program jména v cestě vyhodnotí a podle toho vytvoří stránku:
#!/usr/bin/env python3
from bottle import route, run
@route('/')
def root():
return """
<ol>
<li><a href="jedna">jedna</a></li>
<li><a href="dva">dva</a></li>
<li><a href="tři">tři</a></li>
<ol>
"""
@route('/<jmenostranky>')
def stranka(jmenostranky):
return "Tak jsme na stránce <i>", jmenostranky, "</i> a jdeme zase <a href=\"/\">zpátky</a>..."
run(host='localhost', port=8080, debug=True)
04-error.py
editovatOšetření chyb:
#!/usr/bin/env python3
from bottle import error, run
@error(404)
def error404(err):
return 'Chybka č. 404 se vloudila!<br>Čiliže stránka tady žádná není :-('
run(host='localhost', port=8080, debug=True)
05-templ
editovatŠablony (templates) umožňují stránky v HTML kódu, zahrnujícím základní elementy jazyka Python (například větvení):
#!/usr/bin/python3
from bottle import route, run, template
@route('/nazdar')
@route('/nazdar/<name>')
def hello(name='NIKDO'):
return template('nazdar1', name=name)
run(host='localhost', port=8080, debug=True)
Do podadresáře ./view (tento defaultní název podadresáře pro šablony můžeme změnit nastavením seznamu bottle.TEMPLATE_PATH) umístíme soubor šablony nazdar1.tpl
<h2>Nazdar!</h2>
%if name == 'NIKDO':
<p>Nevím, jak se jmenuješ.</p>
<p>Ty nikdo nejsi?</p>
%else:
<p>Ty jsi {{name.title()}}?</p>
<p>Jak se máš?</p>
%end
Potom z adresy http://localhost:8080/nazdar dostaneme odpověď:
zatímco z adresy např. http://localhost:8080/nazdar/čenda dostaneme:
06-view
editovatStejného výsledku jako výše můžeme (namísto volání funkce template) dosáhnout pomocí @view:
#!/usr/bin/env python3
from bottle import route, view, run
@route('/nazdar')
@route('/nazdar/<name>')
@view('nazdar1')
def hello(name='NIKDO'):
return dict(name=name)
run(host='localhost', port=8080, debug=True)
07-SimpleTemplate
editovatŠablony jsou renderovány strojem, zvaným SimpleTemplate podle několika základních pravidel:
Inline
editovat{{...}} Do dvojitých složených závorek můžeme vložit jakýkoliv pythoní kód, jehož výstupem je řetězec znaků, který bude vložen na stránku (např. proměnná, výraz atd.)
Speciální znaky HTML kódu jsou přitom automaticky escapovány; pokuď si toho nepřejeme, vložíme před začátek kódu vykřičník: {{!...}}
Embeded
editovatVložený jednořádkový kód uvozujeme znakem %, víceřádkový kód uzavřeme do <% ... %>
Kód je psaný podle všech pravidel Pythonu se dvěma výjimkami:
- Indentace (zarovnání) je ignorována
- Konce bloků, které by normálně byly vyznačeny zarovnáním, musí být explicitně vyznačeny klíčovým slovem % end
Funkce
editovatKaždá šablona může využívat zvláštní funkce:
- include(sub_template, **variables) – umožní vložit další šablonu
- rebase(name, **variables) – tuto šablonu označí tak, aby mohla být později vložena do jiné šablony
- defined(name) – vrátí logické ANO, pokud šablona s takovým názvem existuje
- get(name, default=None) – vrátí proměnnou anebo defaultní hodnotu
- setdefault(name, default) – pokud taková proměnná není definovaná, nastaví její defaultní hodnotu
Podrobnější popis SimpleTemplate je na http://bottlepy.org/docs/dev/stpl.html
Jako příklad si napíšeme prográmek, který nám zobrazí násobilku:
#!/usr/bin/env python3
from bottle import route, view, run
@route('/mul')
def mul():
return "<h2>Násobilka<h2>Vlož číslo za lomítko do URL"
@route('/mul/<number>')
@view('multiply')
def mul(number):
return dict(numb=number)
run(host='localhost', port=8080, debug=True)
Šablona multiply.tpl:
<h1>Násobilka {{numb}}</h1>
<table>
<%
n = int(numb)
for q in range(1, 10+1):
%>
{{!'<tr align="right"> <td>{:2}</td> <td> × </td> <td>{:2}</td> <td> = </td> <td>{:3}</td> </tr>'.format(q, n, q*n)}}
% end
</table>
Pro zobrazení např. násobilky 3 jdeme na odkaz http://localhost:8080/mul/3
Formátování v Pythonu zde pro zobrazení webové stránky sice nemá žádný význam, ale výrazně nám zpřehlední vygenerovaný HTML kód:
<h1>Násobilka 3</h1>
<table>
<tr align="right"> <td> 1</td> <td> × </td> <td> 3</td> <td> = </td> <td> 3</td> </tr>
<tr align="right"> <td> 2</td> <td> × </td> <td> 3</td> <td> = </td> <td> 6</td> </tr>
<tr align="right"> <td> 3</td> <td> × </td> <td> 3</td> <td> = </td> <td> 9</td> </tr>
<tr align="right"> <td> 4</td> <td> × </td> <td> 3</td> <td> = </td> <td> 12</td> </tr>
<tr align="right"> <td> 5</td> <td> × </td> <td> 3</td> <td> = </td> <td> 15</td> </tr>
<tr align="right"> <td> 6</td> <td> × </td> <td> 3</td> <td> = </td> <td> 18</td> </tr>
<tr align="right"> <td> 7</td> <td> × </td> <td> 3</td> <td> = </td> <td> 21</td> </tr>
<tr align="right"> <td> 8</td> <td> × </td> <td> 3</td> <td> = </td> <td> 24</td> </tr>
<tr align="right"> <td> 9</td> <td> × </td> <td> 3</td> <td> = </td> <td> 27</td> </tr>
<tr align="right"> <td>10</td> <td> × </td> <td> 3</td> <td> = </td> <td> 30</td> </tr>
</table>
Zobrazený výsledek bude pak vypadat asi takhle:
08-SQLite
editovatMicroframework lze rozšiřovat různými pluginy – jejich aktuální seznam je zde: List of available Plugins. Použití si ukážeme na příkladu pluginu pro manipulaci s databází SQLite:
Nejdřív si nainstalujeme řádkový interface k SQLite a příslušný plugin do Bottle:
sudo apt-get install sqlite3 sudo pip3 install bottle-sqlite
Pozor ale na Bottle/Problém/verze pluginu!
Potom si v řádkovém interface vytvořím a naplním nějakou databázi (samozřejmě i toto lze dělat z Bottle, ale pro jednoduchost si tu databázi teď připravíme předem):
$ sqlite3 test.db SQLite version 3.8.2 2013-12-06 14:53:30 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> create table seznam (id INTEGER, name, number INTEGER); sqlite> insert into seznam values (1, 'Adam', 101); sqlite> insert into seznam values (2, 'Božena', 202); sqlite> insert into seznam values (3, 'Cyril', 303); sqlite> insert into seznam values (4, 'David', 404); sqlite> select * from seznam; 1|Adam|101 2|Božena|202 3|Cyril|303 4|David|404 sqlite>
Tím se nám do souboru test.db uložila jednoduchá databáze například telefonních linek, kterou se teď pokusíme pomocí Bottle zobrazit na Webu:
#!/usr/bin/env python3
from bottle import route, install, template, run
from bottle_sqlite import SQLitePlugin
install(SQLitePlugin(dbfile='./test.db'))
@route('/')
#def show():
def show(db):
c = db.execute('SELECT * FROM seznam')
rows = []
while True:
row = c.fetchone()
if not row:
break
rows.append(row)
return template ('seznam1', rows=rows)
run(host='localhost', port=8080, debug=True)
Ještě si musíme v podadresáři views vytvořit šablonu seznam1.tpl
<h1>Seznam</h1>
<table>
<%
for row in rows:
%>
{{!'<tr> <td align="right">{:2}</td> <td align="left">{:10}</td> <td align="right">{:5}</td> </tr>'.format(row['id'], row['name'], row['number'])}}
% end
</table>
Po spuštění programu ./08-SQLite.pyobdržíme hlášku:
Bottle v0.12.8 server starting up (using WSGIRefServer())... Listening on http://localhost:8080/ Hit Ctrl-C to quit.
a na URL http://localhost:8080/ uvidíme:
Seznam
1 | Adam | 101 |
2 | Božena | 202 |
3 | Cyril | 303 |
4 | David | 404 |
Podíváme-li se na zdrojový kód stránky, uvidíme:
<h1>Seznam</h1>
<table>
<tr> <td align="right"> 1</td> <td align="left">Adam </td> <td align="right"> 101</td> </tr>
<tr> <td align="right"> 2</td> <td align="left">Božena </td> <td align="right"> 202</td> </tr>
<tr> <td align="right"> 3</td> <td align="left">Cyril </td> <td align="right"> 303</td> </tr>
<tr> <td align="right"> 4</td> <td align="left">David </td> <td align="right"> 404</td> </tr>
</table>
Tak to má být!