Bottle.py (1)

Pomyślałem sobie, że napiszę o Bottle i o tym, jak zwyczajnie ułatwia życie. Niewiele programów zostało napisanych z myślą o ułatwianiu życia, ale mamy szczęśliwie kilka wyjątków.

Czym się różni wróbelek? Tym, że ma jedną nóżkę bardziej.

W Pythonie frameworki webowe piszą się same. Ludzie tworzą ich pełno, czasem nawet do najbardziej trywialnych zastosowań, jak na przykład tylko i wyłącznie do wysyłania plików na serwer. Pierwszy raz zainteresowałem się nimi bardziej dzięki prelekcji https://www.youtube.com/watch?v=AYjPIMe0BhA. O niektórych z nich wiedziałem, ale kilka było nowością.

Co było ważne dla mnie? Tylko kilka rzeczy:

  • prostota instalacji i minimalna ilość zależności,
  • swoboda kodzenia bez konieczności tworzenia wielu plików i katalogów,
  • musi działać idealnie w Pythonie 3,
  • dokumentacja w archiwum do ściągnięcia, najlepiej w pdf (najczęściej pracuję bez dostępu do internetu).

Bottle spełnia wszystko idealnie: nie ma żadnych zależności i jest po prostu plikiem bottle.py, który trzeba skopiować do katalogu z programem (co bardzo lubię), ewentualnie zainstalować pipem. Dokumentację można ściągnąć jako jeden duży plik pdf.

Do czego to jest?

Jeżeli kiedykolwiek miałe(a)ś stronę na www.republika.pl z dwoma megabajtami na twoje dane w darmowym pakiecie, a menu składało się z apletów javy, możesz pamiętać, że rzeczy wpisywane w pasek adresu przeglądarki rzeczywiście znajdowały się w podanym katalogu na serwerze. HTML działa tak do dzisiaj i nie ma w tym nic złego.

Wyobraźcie sobie jednak, że łącza na stronie nie mają nic wspólnego z plikami na dysku. Co zyskujemy? Ano to, że możemy mieć klasycznie działające podstrony, lub podstrony, które wywołują jakieś funkcje, na przykład sprawdzają ciasteczka, albo włączają subprocesy, albo kasują pliki z dysku, a zaraz potem przekierowują użytkownika na „normalną” stronę z kodem HTML dla przeglądarki. Nie ma tu granic możliwości i za to lubię programowanie.

No to zaczynamy.

Najpierw zajmiemy się przygotowaniem „środowiska programistycznego” i programem Witaj Świecie.

mkdir bottle
cd bottle
wget https://github.com/bottlepy/bottle/raw/master/bottle.py

I skoro instalację mamy za sobą, jedziemy z kodem. Jestem trochę leniwy, więc na początku zajmiemy się przykładowym kodem ze strony głównej Bottle.

from bottle import route, run, template

@route('/hello/<name>')
def index(name):
    return template('Hello {{name}}!', name=name)

run(host='localhost', port=8080)

Bottle składa się z wielu niezależnie od siebie działających funkcji, które zwykle hurtowo importujemy zaraz na początku. Najważniejsze są dla nas właśnie te trzy:

  • route to właśnie podstrony wywołujące funkcje,
  • run to wbudowany miniserwer www,
  • template to szablony stron, czyli html z bardzo prostą obsługą pythonowych zmiennych, warunków, pętli oraz kilku innych rzeczy.

@route(‚/hello/<name>’) to właśnie tego typu podstrona. Oznacza to, że możesz wpisać w pasku przeglądarki twojastrona.pl/hello, żeby skrypt wywołał funkcję i coś zrobił. <name> to parametr fukcji, który trzeba wpisać w pasek adresu, albo zawrzeć w łączu z innego miejsca.

def index(name): to zwykła, pytonowa funkcja.  Można ją nazwać wszystko jedno jak, może pobierać parametry i nie ma co do tego żadnych ograniczeń. W tym przypadku funkcja index wymaga podania parametru, który ustawia sobie pod zmienną name. Jak jej to podać, skoro mamy tylko przeglądarkę? Ano tak: http://localhost:8080/hello/lukasz. 🙂

return template(‚Hello {{name}}!’, name=name)… Tutaj zaczyna się magia. Co zwraca funkcja hello? Jest to szablon strony. ‚Hello {{name}}’ jest po prostu kodem HTML (no, prawie) ze zmienną name ukrytą w nawiasach, żeby można było ją jakoś odróżnić od tagów tabel, czy akapitów.

Dalej jest name=name. Masło maślane, przecież wiadomo. Lewa strona równania to jednak zmienna używana przez szablon strony (który może być osobnym plikiem), a prawa zmienną z kodu Pythona, który właśnie robimy. Nie ma jednak żadnego powodu, żeby nie nazywać ich tak samo. Kod Pythona oraz szablony to osobne przestrzenie nazw, więc łatwiej napisać i potem pamiętać jedną nazwę zmiennej.

Tyle na początek. Następnym razem weźmiemy się za przygotowanie ładnego inaczej (nie jestem stylarzem) kodu html, w który opakujemy nasz pythonowy kod.

Stronka z bottle.py

Potrzebowałem małej strony internetowej do włączania i wyłączania programu w Javie. Okazało się, że wyszło z tego nieco więcej, a wszystko dzięki Pythonowi i Bottle.

Python dobrze się rymuje z html, to wiemy: Django, Flask, Cherrypy, nawet stare Plone daje radę. Przez lata narobiło się wiele mniejszych skryptów, pozwalających na przesyłanie plików, albo wyświetlanie stron. Bottle.py jest czymś więcej: ma szablony stron, obsługuje ciasteczka, przekierowania, itd… a wszystko to w jednym pliku, który wystarczy skopiować do katalogu z programem. Jako, że nie mam wielkiego doświadczenia z pythonowymi stronami internetowymi, wybrałem na początek to, co najprostsze.

W sieci można znaleźć wiele przykładowych Hello World, ale było to dla mnie za mało. Zapraszam więc na githuba: https://github.com/seem8/astech. W kilku kolejnych wpisach rozłożę programik na części i wyjaśnię jak działa.