Python3 Bottleフレームワーク入門(その1)- 基礎編サーバ起動
2017年8月23日Python Bottle Framework, トピックス
Python Bottleフレームワーク
Python Bottleフレームワークとは、Pythonのフレームワークの中でも小さいフレームワークの中ではメジャーなものです。いちばん有名なDjangoはPythonの中では最もよく使われるフレームワークで至れりつくせりのフルスタックフレームワークですが、マイクロフレームワークと呼ばれるBottleフレームワークは1ファイルで動く極小の軽快に動作するフレームワークです。個人的には最初Flaskを頻繁に使っていましたが、Bottleの方がモジュールの呼び出し方がわかりやすく書けることのほうが多いので今ではちょっとした調べ物や実験はBottleで書くようになりました。学習コストと使用感はFlaskもBottleもさほど変わらないと思います。ライブラリーはFlaskのほうが多いのですが足りないものを自分で作る喜びもありますからそういう意味でBottleが好きです。
マイクロフレームワークを使用する意義は、本格的な複数エンジニアでの開発というよりは一人で開発するケース、もしくはPythonの学習用、大きなシステム開発のモジュールプログラムのプロトタイプ開発用として利用するのが良いと思います。
Bottleの必要性
- 大規模なフレームワークで高度なモジュール開発するとモジュール単体のバグが見えにくい。bottleで単体テストしてから載せるとベター。
- 大規模なフレームワークで高度な改造をしようとすると自分自身できちんとMVCのプログラム的深い理解が必要。至れりつくせりの環境ではコードを書く機会が減るため理解が薄くなりがち。
- ちょっとした数画面程度のユーテリティを作るのに最適。
Bottleのインストール
pythonが導入されpipコマンドが既に導入されているとみなし下記を実行してください。
1 |
$ pip3 install bottle |
Bottle + Pythonだけで簡単な起動テスト
BottleとPythonのみで簡単にコンテンツからWEBサーバの起動までを数行で記述できます。下記はBottle Frameworkで案内されている最初の起動について書かれたものです。ちなみにrun関数はBottleフレームワークのWEBサーバを起動するコマンドです。
1 2 3 4 5 6 7 |
from bottle import route, run, template @route('/hello/<name>') def index(name): return template('<b>Hello {{name}}</b>!', name=name) run(host='localhost', port=8080) |
記述したプログラムをindex.pyと保存してpythonでプログラムを実行するとWEBサーバが起動します。
1 |
$ python3 index.py |
でも、これだとローカル端末からでなければブラウザアクセスができません。SSHターミナルで確認するならばcurlを使うことである程度は確認できます。
1 |
$ curl http://localhost:8080/hello/James |
では、他の端末でWEBブラウザを開いてアクセスするにはどうしたらよいかですがrun関数のhostパラメータの記述を変更することでどの端末からでもアクセスできるようにできます。”0.0.0.0″はインターネット上全くマスクしていない開放状態であるためどこからでもアクセスができます。つまり全てのNICでリッスンしますという意味になります。サーバのホストのIPを設定するやり方もありますがその場合はサーバにNICのIPを特定で一つ指定します。複数枚NICが使われてどのNICからカミングしてきたパケットもアクセスするなら0.0.0.0を指定します。Listen Bindアドレスと思って頂ければわかりやすいかもしれません。
1 2 3 4 5 6 7 |
from bottle import route, run, template @route('/hello/<name>') def index(name): return template('<b>Hello {{name}}</b>!', name=name) run(host='0.0.0.0', port=8080) |
ブラウザーからは、「http://192.168.1.100/hello/James」などとコンテンツを設置しているサーバーのIPアドレスを指定します。ブラウザーには「Hello James!」と表示されるはずです。
もし、表示されない場合は大きく2つ原因が考えられます。Firewallが8080番ポートを許可していない。SELinuxがEnableになってる場合などです。この場合はFirewallで8080ポートを許可してください。またSELinuxを一時的にOFFして試してみてください。
今度は単なるスクリプト記述からメインルーチンを呼んで起動してみましょう。
1 2 3 4 5 6 7 8 9 10 |
from bottle import Bottle,route,run,template app=Bottle() #ボトルのインスタンス作成 @app.route('/hello/<name>') #ルーティング処理 def index(name): return template('<b>Hello {{name}}</b>!', name=name) if __name__ == "__main__": run(app=app,host="0.0.0.0", quiet=False, reloader=True) |
先ほどと少し記述の仕方が変わりました。app変数にBottleのクラスを呼んでインスタンスを作っています。 このようにすると後々Bottleの挙動をパラメータで変更できたりします。それに従って部分的に呼び出し方も 変わっています。run関数のapp=appはappパラメータにBottleのインスタンスを代入しています。インスタンスで利用する場合はこのようにappパラメータでrun関数に教えて上げる必要があります。また最下行から2番めで「if __name__ == “__main__”:」の箇所はpythonでいうところのmainルーチンの宣言です。reloader=Trueはプログラミングコードを書き換えると通常はBottleWEBサーバの再起動が必要だがこれを指定するとコードを修正すると自動で再読込を行ってくれるスイッチになります。
Bottleのルーティング
フレームワークでルーティングと言うのはブラウザで入力するURLを指しています。ドメインの後に続くURIパスを検知して実行するプログラムが起動するようにBottleの仕組みは用意されています。つまり@app.route(URIパス)が動作のきっかけを作りブラウザのURIと合致した場合、その後に続く関数が実行される作りになっています。今回の例ではダイナミックルーティングという方法で/helloの後に名前を付加すると名前の部分の変数が関数の引数に渡されてtemplate関数に処理されてホームページ上に表示される様になっています。尚template関数はBottleのデフォルトのテンプレートエンジンです。
Bottleの最も簡単なレンダリング方法
前回は表示でtemplate関数を使っていましたがもっと簡単な方法があります。 @viewデコレータを使う方法です。そして合わせてこれを使う場合に用意しておきたいのが標準外のテンプレートエンジンです。Bottleではいくつかのテンプレートエンジンが使えるようになっています。ここでは独断と偏見でMakoテンプレートエンジンを使ってみます。(※pip install Makoでインストールしてください。)では次のプログラム例を見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from bottle import mako_view as view from bottle import Bottle,route,run,template app=Bottle() @app.route('/hello/:names') @view('hello') def index(names): return {'name':names} if __name__ == "__main__": run(app=app,host="0.0.0.0",port='8080') |
黄色反転箇所に注目します。 1行目のmako_viewを読み出して別名viewとして利用できるようにしています。 また実際に6行目から9行目にかけて/hello/[名前]で入力されたURLの処理をindex関数で行い最終的にreturnで受取りmako_viewデコレータへ渡しています。この際に注意が必要なことは変数を辞書形式でテンプレートエンジンへ戻す必要があるということです。Viewで渡った雛形テンプレート側では辞書の要素名で参照されるため注意しましょう。
makoテンプレートエンジンを使う場合の注意
先程のプログラムの表示はmakoテンプレートを使用していましたが、実際にそのテンプレートをどのように置くべきか説明したいと思います。デフォルト設置パスはBottleでviewデコレータを使う場合、viewsディレクトリが指定されています。 ディレクトリを作成しそこへ指定したファイルベース名+拡張子をつけて保存します。拡張子はtplとかhtmlなどが良いでしょう。例えば@views(‘hello’)ならhello.htmlとしてベースディレクトリ配下のviewsディレクトリの中へ保存します。
先程実行したプログラムで使用したテンプレート
makoのテンプレートの書き方はよく見かけるような記述なので過去にテンプレートエンジンやMVC使った事がある方ならすぐに馴染むことでしょう。
◯ views/hello.html
1 2 3 4 |
<%inherit file="layout/base.html"/> <%block name="header"> <p>Hello, <strong>${name}</strong></p> </%block> |
◯ views/layout/base.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <title>TEST</title> </head> <body> <div class="container"> <div class="head"> <%block name="header"/> </div> </div> </body> </html> |
makoテンプレートエンジンの文法についてはこちらを参照ください。makoは現在でも活発に更新が行われているテンプレートエンジンなのでおすすめです。
mako template- Python Bottle Framework入門 全13回
- 1.基礎編サーバ起動
- 2.リクエストメソッド
- 3.ORM Peewee (MySQL)
- 4.ORM Peewee CRUD
- 5.Cookie And Session
- 6.Abort and Redirect
- 7.マルチスレッドWEBサーバ
- 8.デーモン化
- 9.Json
- 10.WSGI on SSL
- 11.Apache連携起動(外部WSGI) SSL接続
- 12.Apache連携起動(ReverseProxy)SSL接続
- 13.hprox連携起動(ReverseProxy)SSL接続&HTTP2対応