- 更新日: 2019年12月19日
- 公開日: 2019年12月13日
[Python初心者向け]Bottleの使い方
Python 3大フレームワークの1つ "Bottle"。
今回は、 Bottle の基本情報を抑えて、簡単な Webアプリケーションを作ってみたいと思います。
本稿は、 Python の基礎を習得済みの方を対象としています。予め、ご了承ください。
Python初心者向け_Bottleの使い方
Bottleとは
"Bottle" は、Python製の Webフレームワークで、 「Python で Webサイト」、 「Python で Webアプリ」 と考えた時に一番最初に登場してくるモノ。 Bottle は、 2009年ドイツ人のエンジニア Marcel Hellkampさんが 27歳?の時に開発したモノで、 GitHub上で MIT ライセンスで公開されています。
フレームワークというと "複雑なファイル構造" "たくさんの機能" といったイメージがありますが、こちらの Bottle は必要最低限の機能のみ。 "シンプル"、 "早い" "軽量" に開発されている特徴があります。とはいいましても、 Bottle の動きを制御するメインファイル bottle.py は、 4,427行からなるスゴイプログラム。
また参考までに他の Python Webフレームワークと比較すると、イメージ的には Bottle は "どんぶり" や "ラーメン" といった感じ。 一品料理といいますか、単発的なアプリ開発の利用に長けています。他の Flask は、定食、 Django は フルコース といった感じで、それぞれにメリット・デメリットが。
それでは実際に Bottle をローカル環境で実行してみましょう。
Bottleを扱う様子の動画
本稿でご紹介するプログラムを実行する様子です。本テキストと合わせてご参照ください。
本稿で使用するコード: GitHub
Bottleをインストール
今回は "ファイル操作" と "コマンド操作" 両方が行える Visual Studio Code を使って作業していきます。
まずはテスト用のディレクトリを作成し、仮想環境を構築。それから pip install していきます。
上図のコードを見る
python3 -m venv myenv
source myenv/bin/activate
pip list
pip install --upgrade pip
仮想環境の作成ができたら、 Bottle公式ページにも書いてある pip install
を実行。
上図のコードを見る
pip install bottle
pip list
もう Python の標準ライブラリにした方がいいんじゃないか、というぐらいサクッと入ると思います。
【Anaconda の仮想環境に bottle をインストールする場合】
conda install -c conda-forge bottle
pip install に比べると時間がかかりました。
https://anaconda.org/conda-forge/bottle
BottleでHelloWorld
上図のコードを見る
from bottle import Bottle, run
app = Bottle()
@app.route('/hello')
def hello():
return "Hello World!"
run(app, host='localhost', port=8080)
参考ドキュメント: http://bottlepy.org/docs/dev/tutorial.html#quickstart-hello-world
それでは Bottle の公式ドキュメントで紹介されている Hello World から始めてみましょう。
hello.py という任意の Python ファイルを作成し、ドキュメントに書かれているコードをコピペ。ファイルを保存して、プログラムを実行してみます(下図)。
すると http://localhost:8080 にアクセスしてください、とメッセージが出るのでアクセスしてみると上図のようにエラーが。最初は焦りますが、大丈夫です、 URL を http://localhost:8080/hello に変更してみてください(下図)。
するとプログラムに書いている通り "Hello World" という文字が表示。このような形で Bottle を使う場合は、出力先を明示的に書く必要がありますね。 Bottle は "WSGI" という Webサーバー・ゲートウェイを使っているためこのような形で、 これが Apacheサーバーだったらディレクトリが表示されたりしますよね。
WSGI は、 Bottle 以外の Flask や Django などでも使われていますので、慣れておくとよさそう。
さて参考ドキュメントを進めていくと、次は /hello/<name>
という書き方が。
上図のコードを見る
from bottle import route, run
@route('/')
@route('/hello/<name>')
def greet(name="Stranger"):
return template('Hello {{name}}, how are you?', name=name)
run(host='localhost', port=8080, debug=True)
新しい Pythonファイル name.py を作成し、先ほど同様コードをコピペして実行してみます。
するとまたエラーが、エラー文を見てみますと、
NameError: name 'template' is not defined
どうも "template" がないとのこと。公式ドキュメントのコードをコピペしているだけなのにエラーになるのはチョット焦りますが、下図のように import 部分に "template" を足すとエラーを解決できます。
上図のコードを見る
from bottle import route, run, template
@route('/')
@route('/hello/<name>')
def greet(name="Stranger"):
return template('Hello {{name}}, how are you?', name=name)
run(host='localhost', port=8080, debug=True)
5行目の name='Stranger'
という部分が、表示画面に出力されている様子が確認できます。これは 6行目の return 文で template()
が使用され、 greet()
関数の引数が割り当てられているため。このように template()
と 引数を使うことで、ページ内の文字を "動的" に扱えますね。
そして greet()
関数内の引数は、ルートにも割り当てることができ、
<name> = name = 'Stranger'
という関係に。ユーザー管理画面などでよく URL 内にユーザー名があって、管理画面にユーザー名がある Webサイトってありますよね、それと同じような仕組み。ユーザー管理以外にも、株価や商品を管理したい時にこうした Web構成って扱いやすそうです。
ルート設定が、 /
と /hello/<name>
でかぶっていましたので、下記のように別処理をするようにセットしてみました(下図参照)。
上図のコードを見る
from bottle import route, run, template
@route('/')
def hello():
return "Hello World!"
@route('/hello/<name>')
def greet(name="oshima"):
return template('Hello {{name}}, how are you?', name=name)
run(host='localhost', port=8080, debug=True)
ちなみにプログラムで登場してくる def hello():
や def greet():
などの関数名、これは任意の名称で hello()
でなくても h()
でも動作します。自分で解りやすいように関数名設定しておくといいですね。
Bottleでログイン・プログラム
上図のコードを見る
from bottle import get, post, request
@get('/login')
def login():
return '''
<form action="/login" method="post">
Username: <input name="username" type="text" />
Password: <input name="password" type="password" />
<input value="Login" type="submit" />
</form>
'''
@post('/login')
def do_login():
username = request.forms.get('username')
password = request.forms.get('password')
if check_login(username, password):
return "<p>Your login information was correct.</p>"
else:
return "<p>Login failed.</p>"
run(host='localhost', port=8080, debug=True)
再び参考ドキュメントを進めていくと次は、ログインに関するサンプル。今まで同様に新しく Python ファイルを作成し、コードをコピペ、そして実行。すると今度は run
がないとのこと。
NameError: name 'run' is not defined
上図のコードを見る
from bottle import get, post, request, run
@get('/login')
def login():
return '''
<form action="/login" method="post">
Username: <input name="username" type="text" />
Password: <input name="password" type="password" />
<input value="Login" type="submit" />
</form>
'''
@post('/login')
def do_login():
username = request.forms.get('username')
password = request.forms.get('password')
if check_login(username, password):
return "<p>Your login information was correct.</p>"
else:
return "<p>Login failed.</p>"
run(host='localhost', port=8080, debug=True)
import 文に run を加えて実行すると、今度はエラーなくプログラムが実行できました(上図参照)。そして Username と Password 欄に任意の文字を入力して、ログインボタンを押してみると...
エラーになって、エラー文を確認すると
NameError: name 'check_login' is not defined
これはプログラム 17行目の check_login()
関数が設定されていないためのエラー。 check_login()
は、ログインの入力事項が正しいかどうか確認する関数で、自分でセットする必要が。本来はデータベース内のデータと整合する必要が出てきますが、今回は簡易的に以下のように処理。
上図のコードを見る
from bottle import get, post, request, run
@get('/')
def login():
return '''
<form action="/login" method="post">
Username: <input name="username" type="text" />
Password: <input name="password" type="password" />
<input value="Login" type="submit" />
</form>
'''
@post('/login')
def do_login():
username = request.forms.get('username')
password = request.forms.get('password')
if "username" == username and "password" == password:
return "<p>OKOKOK</p>"
else:
return "<p>❌.</p>"
run(host='localhost', port=8080, debug=True)
【17行目】
if "username" == username and "password" == password:
すると今度は、 ログイン画面で Username と Password に username
、 password
と入力するとログインに成功。 このプログラムは、ユーザー管理をはじめ、Webページにパスワードを設けたい時にも応用できるでしょう。
Bottleで計算プログラムのサンプル
上図のコードを見る
from bottle import get, post, request, run
@get('/')
def circle_area():
return '''
<form action="/calc" method="post">
半径は何cm? <input name="radius" type="text" />
<input value="計算" type="submit" />
</form>
'''
@post('/calc')
def circle_area():
r = request.forms.get('radius')
print(type(r))
calc = int(r) * int(r) * 3.14
return "円の面積:" + str(calc) + "cm2"
run(host='localhost', port=8080, debug=True)
先ほどのログイン・プログラムを応用すると、入力に対してのリアクションを得ることができそう。試しに円の面積を計算してくれるプログラムを作成してみました(上図参照)。
まず円の半径を入力するプログラムが 3〜10行目で、計算および計算結果出力部分が 12〜17行目。入力値の半径は、変数 radius に割り当てられて、 計算ボタンの "submit" を押すと、 action="/calc" method="post"
によって 14行目のプログラムに radius が渡されます。
そして 14行目で radius は 変数 r に代入されて、 16行目で計算。その計算結果は、 17行目で出力という形。
今回は円の面積だけですが、他の計算式なども足すとチョットした演算アプリが作れますね。
Bottleで株価データを取得する例
上図のコードを見る
from bottle import route, run, request
import requests
import json
@route('/')
def hello():
return "こんにちは"
@route('/225')
def greet():
response = requests.get('https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=^N225&interval=5min&apikey=T8ST9ZM5WP7JNMNG')
data = json.loads(response.text)
print(data.keys())
data = data["Time Series (5min)"]
latest_date = sorted(data.keys())[-1]
stock_price = data[latest_date]["4. close"]
return "アメリカ東部時間: " + latest_date + "の 日経225 の最新株価: " + stock_price
run(host='localhost', port=8080, debug=True)
Bottleで入力や演算ができると、 API を使ってデータ取得もできないか、気になりますよね。試しに 日経225 の株価データを取得するプログラムを作成してみました(上図参照)。
APIの取得については、こちらの動画を参照いただくとして、結果的に少々タイムラグがあるものの株価データを取得できました。
こうしたデータを応用すれば、株価上昇ランキングや割安銘柄ランキングなどチョットした Webアプリを作れそうですね。
ポートエラー対策(OSError: [Errno 98] Address already in use)
Bottle のプログラムを実行すると http://localhost:8080
が開くわけですが、プログラムの閉じ方を誤ると、次に Bottle プログラムを実行した時にポートエラーがでます。
- 正しいプログラムの終了ボタン Ctrl + Cボタン
よく間違える終了ボタン Ctrl + Zボタン
ポートエラー文 [Errno 98] Address already in use
ポートエラーについては、違うポート番号を割り当てたりいくつかの解決方法はありますが、 以下のコマンドを実行すると 8080 を強制終了できます。
kill -9 $(lsof -t -i:8080 -sTCP:LISTEN)
\AIエンジニアに必要なスキルが身に付く/
まとめ
Pythonの Bottle、シンプルとは言うけれども、いろいろ使えて楽しいですよね。ただページ数が増えてきたり、データベースが絡んでくるとやや扱いにくいかもしれません。単発的な機能ではなく、複数の機能、プログラムを実行したい場合は、 Flask や Django の方が扱いやすいかもしれないですね。
"Pythonの基礎はマスターしたけれど、その先がない..." "Pythonは社会人に人気って言うけれど、副業には向かないのではないか..." と思われている方、今回の Bottle がヒントになるのではないでしょうか? 単に Bottle を試すだけなら Pythonanywhere などの Webサービスも便利。
「イヤイヤ、 Python の参考書買ったけれども、開いた瞬間に眠くなる...」 「Python自体の設定ができない...」 と 手 と 時間 が止まっている方、学習環境、一度見なおしてみませんか?
一人では難しいならプロ、つまりプログラミング・スクールに頼ってみるというのがスジ、ではないでしょうか? 「イヤイヤ、そんなにお金をかけられない」 「時間がない」 、いろいろあると思いますが、テクノロジーの進化は止まっている私達を待ってくれません、置いていかれます...
今後も安心して仕事や生活に専念していきたいというのなら、ちょっと勇気をだして、やろうとした Python、やり遂げてみませんか? オンラインスクールの CodeCamp では、無料体験を通じて、スクールの価値を体感頂いております。 "無料体験" ご興味ある方は、 公式ページ よりチェックしてみてください。
昨今のプログラミング・ニーズの高まりを受けて、無料体験枠が埋まっている日もあります。予め、ご了承ください。
- この記事を書いた人
- オシママサラ