Pythonの軽量Webフレームワークbottleを使ってみる

インストール

pip でインストール。

takatoh@apostrophe $ pip install bottle
Collecting bottle
/usr/local/lib/python2.7/dist-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
  Downloading bottle-0.12.10-py2-none-any.whl (88kB)
    100% |████████████████████████████████| 90kB 3.6MB/s 
Installing collected packages: bottle
Exception:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/pip/basecommand.py", line 211, in main
    status = self.run(options, args)
  File "/usr/local/lib/python2.7/dist-packages/pip/commands/install.py", line 311, in run
    root=options.root_path,
  File "/usr/local/lib/python2.7/dist-packages/pip/req/req_set.py", line 646, in install
    **kwargs
  File "/usr/local/lib/python2.7/dist-packages/pip/req/req_install.py", line 803, in install
    self.move_wheel_files(self.source_dir, root=root)
  File "/usr/local/lib/python2.7/dist-packages/pip/req/req_install.py", line 998, in move_wheel_files
    isolated=self.isolated,
  File "/usr/local/lib/python2.7/dist-packages/pip/wheel.py", line 339, in move_wheel_files
    clobber(source, lib_dir, True)
  File "/usr/local/lib/python2.7/dist-packages/pip/wheel.py", line 317, in clobber
    shutil.copyfile(srcfile, destfile)
  File "/usr/lib/python2.7/shutil.py", line 83, in copyfile
    with open(dst, 'wb') as fdst:
IOError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/bottle.py'
You are using pip version 7.1.2, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

って、えー、なんかいきなりエラーが出るじゃん。pip をアップグレードしろ、といってるみたいなので、そうしてみる。

takatoh@apostrophe $ pip install --upgrade pip
/usr/local/lib/python2.7/dist-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
Collecting pip
  Downloading pip-9.0.1-py2.py3-none-any.whl (1.3MB)
    100% |████████████████████████████████| 1.3MB 451kB/s 
Installing collected packages: pip
  Found existing installation: pip 7.1.2
    Uninstalling pip-7.1.2:
Exception:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/pip/basecommand.py", line 211, in main
    status = self.run(options, args)
  File "/usr/local/lib/python2.7/dist-packages/pip/commands/install.py", line 311, in run
    root=options.root_path,
  File "/usr/local/lib/python2.7/dist-packages/pip/req/req_set.py", line 640, in install
    requirement.uninstall(auto_confirm=True)
  File "/usr/local/lib/python2.7/dist-packages/pip/req/req_install.py", line 716, in uninstall
    paths_to_remove.remove(auto_confirm)
  File "/usr/local/lib/python2.7/dist-packages/pip/req/req_uninstall.py", line 125, in remove
    renames(path, new_path)
  File "/usr/local/lib/python2.7/dist-packages/pip/utils/__init__.py", line 315, in renames
    shutil.move(old, new)
  File "/usr/lib/python2.7/shutil.py", line 303, in move
    os.unlink(src)
OSError: [Errno 13] Permission denied: '/usr/bin/pip'
You are using pip version 7.1.2, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

ダメじゃん。同じようなエラーが出る。
ググってみると↓このページを見つけた。

 cf. bottle超初歩入門 – Qiita

なんか、pip でインストールしようとするのが間違いみたいなことが書いてある。bottle はファイル1つでできているので、それをダウンロードして、スクリプトと同じディレクトリに置くのが簡単らしい。

https://raw.githubusercontent.com/bottlepy/bottle/master/bottle.py

takatoh@apostrophe $ wget https://raw.githubusercontent.com/bottlepy/bottle/master/bottle.py

これで bottle.py がダウンロードできた。なんか釈然としないけど今のところはよしとする。

Hello, world!

まず初めは、定石通り Hello, world。

from bottle import route, run

@route('/hello')
def hello():
    return "Hello, world!"

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

bottle から routerun をインポート。route デコレータでルーティングを行い、run 関数でサーバを走らせる、ってことのようだ。
これで http://localhost:8080/hello にブラウザでアクセスすると、ちゃんと「Hello, world!」と表示された。

パス中にパラメータ

URL のパス中にパラメータを入れることができる。下の < > で囲んであるところがそれ。

from bottle import route, run

@route('/hello/')
def hello_with_name(name):
    return "Hello, " + name + "!"

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

例えば、http://localhost:8080/hello/Andy にアクセスすると「Hello, Andy!」と返ってくる。

リダイレクト

redirect 関数を使う。

from bottle import route, redirect, run

@route('/')
def index():
    redirect('/hello')

@route('/hello')
def hello():
    return "Hello, world!"

run(host='localhost', port='8080', debug=True, reloader=True)

ついでに、run 関数の引数に reloader=True を指定した。これによって、サーバを起動したままでもファイルを書き換えると自動的にリロードしてくれるようになる。

Not found

abort 関数。ステータスコードとメッセージを指定できる。

from bottle import route, redirect, abort, run

@route('/')
def index():
    redirect('/hello')

@route('/hello')
def hello():
    abort(404, "Not Found.")

run(host='localhost', port='8080', debug=True, reloader=True)

この例では、http://localhost:8080/ にアクセスすると /hello にリダイレクトされて、Not found になる。

リファラと接続元IPアドレス

request オブジェクトからリクエストの情報が取れる。リファラは request.headers.get('Referer')

# encoding: utf-8

from bottle import route, request, run

@route('/')
def index():
    return "<a href="\&quot;./ref\&quot;">Link</a>"

@route('/ref')
def ref():
    referer = request.headers.get('Referer')
    return referer

run(host='localhost', port='8080', debug=True, reloader=True)

一方、IPアドレスは request.environ.get('REMOTE_ADDR')

# encoding: utf-8

from bottle import route, request, run

@route('/my_ip')
def my_ip():
    ip = request.environ.get('REMOTE_ADDR')
    return ip

run(host='localhost', port='8080', debug=True, reloader=True)

テンプレート

bottle から template をインポートすることで、簡易なテンプレートエンジンが使えるようになる。

# encoding: utf-8

from bottle import route, request, template, run

@route('/')
def index():
    return "<a href="\&quot;./ref\&quot;">Link</a>"

@route('/ref')
def ref():
    ip = request.environ.get('REMOTE_ADDR')
    referer = request.headers.get('Referer') or ''
    return template("Your IP is {{ip}}, referer is {{referer}}.", ip=ip, referer=referer)

run(host='localhost', port='8080', debug=True, reloader=True)

静的ファイル

static_file 関数を使う。

# encoding: utf-8

from bottle import route, static_file, run

@route('/')
def static(file_path):
    return static_file(file_path, root='./storage', download=True)

run(host='localhost', port='8080', degug=True, reloader=True)

引数に download=True を指定すると、ブラウザで開くのではなくダウンロードするようになる。

ふう、今日のところはここまで。

[追記]

Windows 10 では、pip で普通にインストールできた。なんでだ?

[追記2]

sudo をつけたら、pip のアップグレードも bottle のインストールもうまくいった。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください