PythonのWebフレームワーク Bottleをロリポップサーバ(ロリポプラン)で動かしてみる


BottleというPythonの軽量Webフレームワークを、ローカルとロリポップサーバ(ロリポプラン、sshは使えません…)で動かしてみました。ロリポップサーバ上で動かす際には、環境に合わす修正が必要でした。

## サンプル
タイトルページで、「名前」を入力し「好きな麺類」を選択、GETメソッドで渡したパラメータを、結果出力ページで表示するという簡単なものです。
![タイトルページ.png](https://qiita-image-store.s3.amazonaws.com/0/31217/0253e083-d07f-19b4-ae5e-c37e9e65b68d.png "タイトルページ.png")
![結果出力のページ.png](https://qiita-image-store.s3.amazonaws.com/0/31217/c8111b73-9965-77ad-7464-6ae8137f1083.png "結果出力のページ.png")


## まずはローカル
### ファイル構成
今回はプロジェクト名を```bottle_study```としました。

```ファイル構成、ローカル
bottle_study
- views/
  |  title.tpl   # / で呼ばれるテンプレートファイル
  |  show.tpl    # /show で呼ばれるテンプレートファイル
  bottle.py      # Bottle本体
  index.py       # ディスパッチャ
```
###手順
1. bottle.pyの取得
2. index.pyの作成
3. views/title.tplの作成
4. views/show.tplの作成
5. ビルトインサーバの実行

###1. bottle.py
Bottle本体である```bottle.py```は、プロジェクトディレクトリの直下に```wget```で取得します。

```bottle.pyの取得手順
$ mkdir bottle_study
$ pwd
(各自の環境による)/bottle_study
$ wget http://bottlepy.org/bottle.py
$ ls
bottle.py
```

###2. index.py
今回はすべての処理をindex.pyに書きました。
最下行で、ビルドインサーバを実行しています。

```index.py
#!/usr/local/bin/python
# -*- coding: utf-8 -*-

from bottle import route, run, template, request


# localhost:8080
@route('/')
def title():
    # views/title.tplを呼ぶ
    return template('title')


# localhost:8080/show
@route('/show', method='GET')
def men():
    # GETパラメータの取得(username, men)
    username = request.query.username
    men = request.query.men

    # Controller部 =======================================
    if (username == ""):
        username = "名無しさん"

    if men in {"ramen"}:
        menname = "ラーメン"
    elif men in {"soba"}:
        menname = "そば"
    elif men in {"udon"}:
        menname = "うどん"
    else:
        menname = "Error!!"

    # View部 =============================================
    # views/show.tplを呼ぶ
    return template('show', name=username, men=menname)


# ビルドインサーバの実行
run(host='localhost', port=8080, debug=True, reloader=True)
```

###3. views/title.tpl
タイトルページです。
Bottleはデフォルトで、viewsディレクトリ以下のファイルを読み込みます。

```views/title.tpl
<!DOCTYPE html>
<html lang=ja>
  <head>
    <meta charset="UTF-8">
    <title>タイトルページ</title>
  </head>

  <body>
    <h1>タイトルページ</h1>

    <form method="GET" action="/show">
    <p>お名前は？：<br>
    <input type="text" name="username"></p>

    <p> 好きな麺類は何ですか？</p>
    <form>
    <select name="men">
      <option value="ramen">ラーメン</option>
      <option value="soba">そば</option>
      <option value="udon">うどん</option>
    </select>
    <input type="submit" value="送信する">
    </form>
  </body>

</html>
```

###4. views/show.tpl
タイトルページからパラメータを受けて、結果出力するページです。
GETメソッドのパラメータは、変数で受け取ります。(nameとmen)

```views/show.tpl
<!DOCTYPE html>
<html lang=ja>
  <head>
    <meta charset="UTF-8">
    <title>結果出力のページ</title>
  </head>

  <body>
    <h1>結果出力のページ</h1>
    <p>ようこそ {{name}} さん！！</br>
    今度一緒に、{{men}} を食べに行きましょう！<p>
    <a href="/">return to HOME</a>
    </p>
  </body>

</html>
```

###5. ビルドインサーバの実行

python index.pyすることで、ビルドインサーバで実行できます。
ブラウザで```localhost:8080```とすると、タイトルページが開きます。

```ビルドインサーバの実行手順
$ pwd
(各自の環境による)/bottle_study
$ ls
bottle.py	index.py	view/
$ python index.py
```

----
## 次はレンタルサーバで動かす

次はロリポップサーバのロリポプランで動かしてみます。これがどんなものかというと

* CGIが使えて、ディレクトリ毎に.htaccessによる設定が可能
* 2系のpythonは使える(2.7.3, 2014/04/13現在)
* sshは使えませんので、サーバ上でコンパイルをして環境を構築することはできない
* データベースは1つだけ使える(Wordpressで使っちゃってます…)
* でも利用料は、250円/月(税抜)とリーズナブル

ということで、制限は多いのですが、1ファイルだけなbottleなら動くかなと試してみました。

### ファイル構成
ロリポップサーバのファイル構成です。
今回、レンタルサーバ版のサンプルのルートページは「http://(ロリポップサーバのページ)/bottle_study/index.cgi」とするので、ドキュメントルートの下に、プロジェクトディレクトリの「bottle_study」配置しました。

```ファイル構成、ロリポップサーバ
ドキュメントルート
| .htaccess   # 今回追加
- bottle_study
  - views/
    | title.tpl   # 変更なし
    | show.tpl    # 変更なし (return to HOMEのパスを/ → /bottle_studyにする)
  | bottle.py      # 変更なし
  | index.cgi      # index.py → index.cgi、要修正
```

### 修正した点
1. index.py (Pythonの実行パス、サーバ種指定、拡張子をcgi、パーミッションを700に)
2. .htaccessで、ルートディレクトリに戻ってきてしまったパスを、```bottle_study/index.cgi/show```にリダイレクトする


###1.index.cgi(index.py→)
以下の4点を修正しました。

* Pythonの実行パスを#!/usr/bin/python2.7に
* ビルドインサーバで実行していた所を、cgiサーバとして動かすようにする
* 拡張子をpy→cgiに修正
* パーミッションは700に(ロリポップの場合)

```index.cgi(ローカル版との差分のみ)
#!/usr/bin/python2.7

…

run(server='cgi')

```

###2..htaccess
* ドキュメントルートに.htaccessを作成
* パーミッションは704に(ロリポップサーバの場合)

タイトルページから結果表示のページに遷移する際、期待する結果表示のページのURLは、

```期待する結果表示ページのURL
http://(ロリポップサーバのページ)/bottle_study/index.cgi/show?username=yamjack&men=ramen
```
となるのですが、このままだと

```実際の結果表示ページのURL
http://(ロリポップサーバのページ)/show?username=yamjack&men=ramen
```

とドキュメントルートのページに戻ってしまうようで、ページが見つかりませんとなってしまいます。
これをドキュメントルートの```.htaccess```でリダイレクトして期待するページに遷移するようにします。

```.htaccess
RewriteEngine on
RewriteRule ^show(.*)$ http://(ロリポップサーバのページ)/bottle_study/index.cgi/show$1

```
.htaccessは、最終行に改行のみの行を入れるのと、ロリポップサーバの場合は、パーミッションを704にするのを忘れないようにします。

-
これで、ローカルの時と同じ動きをするようになりました。
私が作るのものは、今のところは個人の勉強用なので、「人に見せたい！」と思うものが作れるようになるまでは、この環境でアレコレと試してみます！