Python（Bottle）で爆速！WebAPI開発

# 概要
とあるWebアプリ開発時に、別サーバーのWebAPIを呼ぶ必要が出てきました。
開発時には擬似環境が必要となるとのことで、簡単なWebAPIを爆速で構築したメモです。

# 環境

* 言語
Python 3.7.5
理由：Windowsのexeインストーラーがあったから

* Webフレームワーク
**Django**: 大規模向け、機能豊富
**Flask**: 中小規模向け、そこそこの機能、WSGI準拠
**Bottle**: 小規模向け、軽量、WSGI準拠
上記の特性から今回はスピード感ありそうなBottleを採用しました。

* サーバー
Windows Server
Apache 2.4.37 VC15

# Pythonのインストール

下記サイトからインストーラーをダウンロードし、インストーラーを起動
https://www.python.jp/install/windows/install_py3.html

インストール時のオプションで「全てのユーザーにインストール」と「環境変数へパスを追加」みたいなのにチェック入れる。
（チェックを入れないと、OSのログオンユーザーのフォルダにインストールされ、環境変数も自分で設定しないといけません。）

インストーラーが完了したら、コマンドプロンプトで

```
python --version
```

バージョンが出てくればインストール完了。

# 必要なパッケージのインストール

続いて、コマンドプロンプト(管理者権限で実行)で下記コマンドたちを実行する。

Bottleのインストール

```
pip install bottle
```

DBはPostgreSQLを使用しました。
DB接続にはpycopg2を使用します。

```
pip install psycopg2
```

# Hello Worldする

動作することを確認します。
index.pyを作成し、以下の通り編集します。

```python:index.py
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)
```

これだけです・・・やばくないですか・・・

コマンドプロンプトで`python index.py`を実行するとlocalhostで起動します。
そしてブラウザで http://localhost:8080/hello/tsumasakky にアクセスすると
画面にHello tsumasakky!と表示され、成功です。

# Webサーバー構築
## Apacheのインストール

https://www.apachelounge.com/download/VC15/ 
このあたりからダウンロード。 

解凍してでてきた"Apache24"を、サーバーのC直下にコピー 

## WSGIのセットアップ

以下のサイトからファイルをダウンロード
https://www.lfd.uci.edu/~gohlke/pythonlibs/#mod_wsgi

ファイル名ですが、

Apache 2.4 VC "15" 
Python"37" 
Windows "64"bit 

なので、「mod_wsgi-4.6.8+ap24vc15-cp37-cp37m-win_amd64.whl」
をダウンロードしました。環境に合わせてダウンロードしてください。

コマンドプロンプトでインストールします。（ダウンロードしたファイルの場所を指定）

```
pip insatll mod_wsgi-4.6.8+ap24vc15-cp37-cp37m-win_amd64.whl
```

## httpd.confの編集
まず、mod_wsgiの設定を取得するため、コマンドプロンプトで以下のコマンドを実行。

`mod_wsgi-express module-config`

すると、以下のように表示されます。 

```
LoadFile "c:/program files/python37/python37.dll"  
LoadModule wsgi_module "c:/program files/python37/lib/site-packages/mod_wsgi/server/mod_wsgi.cp37-win_amd64.pyd"  
WSGIPythonHome "c:/program files/python37"  
```

表示された設定をコピーし、Apacheのhttpd.confに追記する。（Load Moduleの最後くらいに）
さらに、このあと作成するアダプターへのルーティングを追記する。
```config:httpd.conf
WSGIScriptAlias /api C:\Apache24\htdocs\adapter.wsgi
```

※ユーザー固有のフォルダとかに配置するとアクセス権限なくて403エラーになったり。

## アダプターの作成

wsgiの設定がうまくいっているかどうかを確認するために、WSGIScriptAliasで設定したパスにadapter.wsgiファイルを作成します。

```python:adapter.wsgi 
def application(environ,start_response):
    status = '200 OK'
    output = b'Hello World!'
    response_headers = [('Content-type','text/plain'),
                        ('Content-Length',str(len(output)))]
    start_response(status,response_headers)
    return [output]
```

※ちなみに"output"に普通の文字列入れると500エラー
`output = 'Hello World!' #Error! `
 →バイト文字列にする必要あり
https://stackoverflow.com/questions/34838443/typeerror-sequence-of-byte-string-values-expected-value-of-type-str-found

Apacheを再起動して、http://localhost/api にアクセス。
"Hello World"がでてきたら成功です！

## アダプター経由で自前のアプリを起動

先ほどの`index.py`と`adapter.wsgi`を編集します。

```python:adapter.wsgi
import sys, os
dirpath = os.path.dirname(os.path.abspath(__file__))
sys.path.append(dirpath)
os.chdir(dirpath)
import bottle
import index
application = bottle.default_app()
```

```python:index.py
from bottle import route, run, template
from bottle import TEMPLATE_PATH
import psycopg2

@route('/hello')
def hello():
    return template('<b>Hello World!</b>',)

@route('/users')
def users():
    conn = psycopg2.connect("postgresql://postgres:postgres@localhost:5432/sample")
    cur = conn.cursor()
    cur.execute('select * from sample.users;')
    users = cur.fetchall()
    cur.close()
    conn.close()
    return template('<b>{{users}}</b>!', users=users)
 
if __name__ == '__main__':
    run(host='localhost', port=8080, debug=True, reloader=True)
```

Apacheを再起動し、http://localhost/api/users にアクセスすると、DBからユーザーの一覧が取得できました。

# 感想
サーバーの構築には若干手間取ったものの、実際のアプリコーディングは10分程度でできました！
超爆速です！

ちなみにこのあとはpycopg2でDBから辞書型でデータ取得し、dict -> jsonに変換して返す～
みたいな対応でAPIを構築しました。

上記のやり方でできない、またはこんな方法もある！という方はぜひコメントくださいませ！

最後までお読みいただきありがとうございました。(m´・ω・｀)m

# 参考

* [Web Server Gateway Interface](https://ja.wikipedia.org/wiki/Web_Server_Gateway_Interface)
* [TypeError: sequence of byte string values expected, value of type str found](https://stackoverflow.com/questions/34838443/typeerror-sequence-of-byte-string-values-expected-value-of-type-str-found)
* [PythonのBottleを初めて触ってから３０分で本番環境にデプロイ](https://qiita.com/yoshizaki_kkgk/items/ff5a7b02620814048bc3)
* [Bottleで作成したWebアプリケーションを本番環境に適用する](https://gyobot.com/blog/detail/3/)
* [Python（bottle）をApacheで動かす](https://re-engines.com/2017/05/22/python%EF%BC%88bottle%EF%BC%89%E3%82%92apache%E3%81%A7%E5%8B%95%E3%81%8B%E3%81%99/)
* [Python3 Bottleフレームワーク入門（その１１）- WSGI方式 Bottle連携SSL Apache起動](https://www.netmarvs.com/archives/2494)