はじめに
Rasperry pi で IoT を作りたいと思っていたんですが、web 系・ソフト系の知識があまりないので困っていました。
Web アプリケーションを Python で実現する場合は Django や Zope, Pyramid などのフレームワークが使用されていますが、これらは多くの機能を備えている反面、自分のような初心者にはレベルが高すぎます。
そこで、Bottle という Python の軽量フレームワークを勉強することにしました。
フレームワークが1つのファイルに収まっているため、初心者が勉強するのにはうってつけらしいです。
◎今回の目的
まずは PC 環境で Bottle を使用して、Bottle の基本的な使い方について学ぶ。
ログインフォームつきのサーバを立てるところまでの備忘録
◎環境
WSL Ubuntu 18.04.3 LTS
概要
- Bottle 導入
1.1.bottle.py
のダウンロード
1.2. 動作確認 - ルーティング
2.1. 静的ルーティング
2.2. 動的ルーティング - HTTP について
3.1. HTTP とは
3.2. HTTP のリクエストメソッド - Bottle におけるメソッド対応
4.1. GET メソッド
4.2. GET 以外のメソッド - Request オブジェクト
- ログインフォームを作ってみる
1. Bottle 導入
1.1. bottle.py
のダウンロード
まずは適当に作業用のディレクトリを作成する。
$ mkdir bottle_test
$ cd bottle_test
以下のコマンドを実行して bottle.py
をダウンロードする。
※ Bottle は単一の python ファイルなので、pip install bottle
でも wget
でも変わらない。
$ wget http://bottlepy.org/bottle.py
1.2. 動作確認
Hello world で動作確認してみる。
bottle.py
と同じ階層(上記では bottle_test )に以下の index.py
を作成する。
# -*- coding:utf-8 -*-
from bottle import route, run
@route('/hello')
def hello():
return "Hello world!"
run(host='localhost', port=8080, debug=True)
これを実行すると、web サーバが立ち上がる。
$ python3 index.py
ブラウザで http://localhost:8080/hello へアクセスすると、 Hello world!
と表示されるはず。(ctrl + c
で終了)
これで、bottle の動作を確認することができた。
2. ルーティング
Bottle では、クライアント(ブラウザ)からリクエストされた URL に python の関数を紐づけることができる。これをルーティングという。
例えば、下記のようなコードを使うと、http://xxxxx/hoge
という URL がリクエストされると、関数 hogehoge() が実行されて、view フォルダ内部にある index.tpl (中身は HTML ) がクライアント(ブラウザ)に送信される。
@route('/hoge')
def hogehoge():
return template('view/index')
2.1. 静的ルーティング
実際に、ルーティング機能と html の組み合わせを試してみる。
先ほどの bottle_test/index.py
を以下のように書き換えて保存し、さらに bottle_test/view/index.tpl
を作成する。
# -*- coding:utf-8 -*-
from bottle import route, run, template
@route('/hello')
def hello():
return template('view/index')
run(host='localhost', port=8080, debug=True)
<html>
<head>
</head>
<body>
<p>Hello!</p>
</body>
</html>
この状態で、index.py
を実行し、実行中の PC のブラウザで http://localhost:8080/hello にアクセスすると、"Hello!" と表示されるはず。
※ちなみに run
関数は Bottle フレームワークの WEB サーバを起動するコマンド。host = '0.0.0.0'
に変更して実行すれば、同じネットワーク内の端末からもアクセスできるようになる。その場合アクセスする URL は http://PCのIPアドレス:8080/hello
となる。うまく接続できない場合、Firewallが8080番ポートを許可していないことなどが原因だと考えられる。
ファイアウォールの設定でポート番号の通信を許可するには
$ python3 index.py
今試したものは、 静的ルーティング
と呼ばれる。
2.2. 動的ルーティング
HTTP ではブラウザがリクエストする URL の末尾にパラメータを加えることができるが、Bottle ではそれを関数の引数としてとることができる。(HTTP については次章を参照)
先ほどの bottle_test/index.py
と bottle_test/view/index.tpl
を以下のように書き換えて保存する。
# -*- coding:utf-8 -*-
from bottle import route, run, template
@route('/hello')
@route('/hello/<name>')
def hello(name = '知らない人'):
return template('view/index', nm = name)
run(host='localhost', port=8080, debug=True)
<html>
<head>
</head>
<body>
<p>Hello!{{nm}}</p>
</body>
</html>
以下の表に示すように、URL の末尾につけるパラメータによって表示結果が変わる。
URL の末尾のパラメータが関数の引数として取られ、tpl ファイル中の {{nm}} が引数に置換されたものがブラウザに表示される。
関数の変数に初期値を設定することで、末尾にパラメータがない場合の動作も指定できる。
リクエストする URL | 表示結果 |
---|---|
http://localhost:8080/hello | Hello!知らない人 |
http://localhost:8080/hello/tanaka | Hello!tanaka |
http://localhost:8080/hello/12345 | Hello!12345 |
3. HTTP について
ここからの内容には HTTP に関する知識が必要だったため、少しだけ勉強した。軽くまとめる。
3.1. HTTP とは
Hypertext Transfer Protocol(ハイパーテキスト・トランスファー・プロトコル、略称 HTTP)とは、WebブラウザがWebサーバと通信する際に主として使用する通信プロトコルであり、インターネット・プロトコル・スイートのメンバである。HTMLなどのテキストによって記述されたWebページ等のコンテンツの送受信に用いられる。 Wikipedia
HTTP は、サーバ・クライアントによるリクエスト・レスポンス通信を行う。クライアント(ブラウザ)がデータのリクエストを送信すると、リクエストを受けた Web サーバがレスポンスとしてデータを返す形式のこと。
3.2. HTTP のリクエストメソッド
クライアント側(ブラウザ)がサーバ側に送信するリクエストメソッドは数種類あるが、ここではよく使われる 5 つのメソッドについてまとめる。
詳しくは Web 初心者のための HTTP
① GET
URI のデータを取得するリクエストメソッドで、HTML、画像などのデータを取得するときに使用される。
簡単に言ってしまえば「このページを送信してくれ」というリクエストのこと。
また、GET メソッドで指定した URI の後ろに ? + 文字列 をつけることで、リクエスト時にサーバ側にパラメータを送信することもできる。(例: http://localhost:8080/index.html?hoge=hoge
)
② POST
クライアント側からサーバ側にデータを送信するメソッド。
GET メソッドでは URI の末尾にパラメータを書くことでサーバにパラメータを送信するが、こちらはHTML のフォームからパラメータを送信する。
こちらは送ることができるデータのバイト数に制限はない。
重要度の高いデータを暗号化して送信することもできる。
③ HEAD
URI のヘッダデータのみを取得するメソッド。
GET メソッドはデータの本体も同時に取得してしまうが、HEAD メソッドではデータのヘッダ部分(データの更新日時やデータサイズ)のみを取得することができる。
④ PUT
URI の内容を作成・置換するメソッド。
指定したリソースが存在しなければ新規作成し、指定したリソースが存在したら更新する。
PUT で作成するリソースの URI はクライアント側(ブラウザ)が決定する。
⑤ DELETE
URI の内容を削除するメソッド。
4. Bottle におけるメソッド対応
4.1. GET メソッド
@route
デコレータにオプションを渡さずに使った場合は、GET メソッドのアクセスに対する処理として扱われる。(2. ルーティング
に記載したソースコードは全て GET メソッドのアクセスへの処理を記述している)
# GETメソッドで /hoge にアクセスされたときに hogehoge() を実行する
@route('/hoge') # もしくは @get('/hoge')
def hogehoge():
return template('<b>Hello World</b>!')
4.2. GET 以外のメソッド
GET 以外のメソッドに対応する場合、以下の2通りの記述方法がある。
以下に、 POST メソッドを例にした書き方を示す。
① @route
デコレータにオプションを渡す
# 方法その1: @route デコレータにオプションを渡す
# POSTメソッドで /hoge にアクセスされたときに hogehoge() を実行する
from bottle import route, run, template
@route('/hoge', method = 'POST')
def hogehoge():
return template('<b>Hello World</b>!')
② メソッドに対応したデコレータを使う
# 方法その2: メソッドに対応したデコレータを使う
# POSTメソッドで /hoge にアクセスされたときに hogehoge() を実行する
from bottle import post, run, template
@post('/hoge')
def hogehoge():
return template('<b>Hello World</b>!')
一覧
メソッド | 方法① | 方法② |
---|---|---|
GET | @route('/hoge') |
@get('/hoge') |
POST | @route('/hoge', method = 'POST') |
@post('/hoge') |
PUT | @route('/hoge', method='PUT') |
@put('/hoge') |
DELETE | @route('/hoge', method='DELETE') |
@delete('/hoga') |
5. Request オブジェクト
bottle.request
を使用すると、現在処理しているリクエストにアクセスできる。
from bottle import request
-
request.query
: GET メソッドでクライアントから送信されたパラメータ(クエリパラメータ) -
request.forms
: POST / PUT メソッドでクライアントから送信されたフォームパラメータ -
request.url
: アクセスされた URL -
request.files.get('name')
: 添付ファイル
詳細はBottleのRequest/Responseオブジェクトをマスター
6. ログインフォームを作ってみる
ここまでの知識を使って、ログインフォームを作ってみる。
bottle_test/index.py
と bottle_test/view/index.tpl
を以下のように書き換えて保存する。
# -*- coding:utf-8 -*-
from bottle import get, post, request, run, template
def check(password): # ログイン判定
if password == "abc":
return True
else:
return False
@get('/login') # GET メソッドで /login にアクセスしたときの処理
def login_form():
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 login():
#POSTされた情報にアクセス
name = request.forms.get('username')
pasw = request.forms.get('password')
# 判定
if check(pasw):
return template('view/index', nm = name)
else:
return "<p>Login failed.</p>"
run(host='localhost', port=8080, debug=True)
<html>
<head>
</head>
<body>
<p>Hello!{{nm}}</p>
</body>
</html>
index.py
を実行する。
$ python3 index.py
この状態でブラウザから http://localhost:8080/login にアクセスすると、ログイン画面が表示される。
適当な Username と設定したパスワード( abc )を入力して Login
を押すと、 Hello!<入力したUsername>
と表示されるはず。
参考にさせていただいたサイト
インストール・動作確認・route の使い方 : Pythonの軽量Webフレームワーク「Bottle」
Bottle の基本的な使い方 : Python の軽量 Web サーバ Bottle の使い方
Bottle 詳細 : Python で一番小さい WEB フレームワーク bottle.py
HTTP について : Web 初心者のための HTTP
Bottle で画像ファイルのリンク生成 : PythonのBottleフレームワークで静的ファイルのリンク生成
Bottle の Request/Response : BottleのRequest/Responseオブジェクトをマスター