続いてはPython（Flask）でHeroku!

どうも。前日の[Rubyに負けるな！HerokuでPython(Django)動かす方法](http://qiita.com/nakazye/items/48651e39f07da82fe79e)に触発されて思わず登録してしまいました。[kounoike](http://qiita.com/kounoike)です。

[herokuでmatplotlibでSVGなグラフを書く](http://qiita.com/kounoike/items/7a73ed7417289edb8be7)という記事でもFlask＋herokuの導入について触れているのですが、今回はmatplotlib抜きの記事としてみましょう。その代わりに MongoHQ をちょこっと使ってみます。

## Flaskとは？

Djangoが「フルスタック」Web フレームワークなら、Flask は「micro」Web フレームワークです。標準の Flask コアは Jinja2 テンプレートエンジンと Werkzeug WSGI ツールキットの２つのライブラリにしか依存していません。提供する主な機能はルーティング、Jinja2 テンプレート、静的ファイルの提供、デバッグ支援くらいでしょうか（すべてを知っている訳ではないので・・・）。もちろん、様々な Flask 拡張ライブラリが提供されているので、もっと凝ったことも色々できるはずです。

.py ファイルが1ファイルで始められる非常にシンプルなフレームワークですので、簡単な Web アプリを作って公開してみたいというときに便利でしょう。

また、昨日の記事を見るに Django では静的ファイルの配信に一手間かかるようですが、Flask では単にstaticの下に置くだけですので js/css/img の配信も楽々です。

## まずは簡単に始めてみましょう

heroku のアカウント作成や Toolbelt 導入は済んでるものとします。また、環境は Mac で pyenv, pyenv-virtualenv を導入済みとしています。

heroku の python は 2.7.8 か 3.4.1 なのですが、ここでは 2.7.8 を選択しています。

### ライブラリの準備

```shell-session
$ mkdir heroku-qiita-advent-2014
$ cd heroku-qiita-advent-2014
$ pyenv virtualenv 2.7.8 qiita-advent-2014
$ pyenv local qiita-advent-2014
$ echo .python-version > .gitignore
$ pip install flask
```

### テンプレート、アプリの準備

```py:app.py
#!/bin/env python
# coding: utf-8

import os
from flask import Flask, render_template

app = Flask(__name__)
app.debug = True


@app.route('/')
def index():
    return u'テスト'


@app.route('/hello/<name>')
def hello(name=''):
    if name == '':
    ¦   name = u'ななしさん'
    return render_template('hello.html', name=name)


@app.route('/debug')
def debug():
    return render_template('notemplate.html')


if __name__ == '__main__':
    port = int(os.environ.get('PORT', 5000))
    app.run(port=port)
```

テンプレートファイルは templates/ 以下に置きます。また、静的ファイルはstatic/以下に置きます。

```html+jinja:templates/hello.html
<html>
<head>
    <title>Hello {{ name }}</title>
</head>
<body>
    <h1>こんにちは{{ name }}さん</h1>
    <a href="http://flask.pocoo.org/"><img src="/static/img/flask.png"></a>
</body>
</html>
```

```shell-session
$ tree
.
├── Procfile
├── app.py
├── requirements.txt
├── runtime.txt
├── static
│   └── img
│       └── flask.png
└── templates
    └── hello.html
```


### ローカルで試してみよう

`python app.py`とするとローカルホストのポート 5000 でアプリが立ち上がります。/ と /hello/名前 と /debug がありますので試してみましょう。

`app.debug = True`を入れてあるので，http://localhost:5000/debug にアクセスするとエラーページが出ます。

![スクリーンショット 2014-12-07 14.05.05.png](https://qiita-image-store.s3.amazonaws.com/0/53147/9107a8fc-619d-d233-deee-a4f7d7e16e9a.png)

## heroku にデプロイ

### heroku 用のファイルを準備する

```shell-session
$ pip install gunicorn
$ pip freeze > requirements.txt
$ echo python-2.7.8 > runtime.txt
$ echo web: gunicorn app:app --log-file=- > Procfile
```

### git で管理する

```shell-session
$ git init
$ git add .gitignore
$ git add .
$ git commit -m "initial commit"
```

### heroku にデプロイ

```shell-session
$ heroku login
$ heroku apps:create
$ git push heroku master
```

https://stark-forest-4893.herokuapp.com/ でこのアプリが見られます。https://stark-forest-4893.herokuapp.com/hello/ に続けて適当な名前を入れてみてください。

また、heroku 上だと Flask の`app.debug = True`は無効になっています。

![スクリーンショット 2014-12-07 14.23.55.png](https://qiita-image-store.s3.amazonaws.com/0/53147/355a28f9-f737-98b7-5905-ab568ea0df92.png)

`heroku logs` コマンドで確認しましょう。

![スクリーンショット 2014-12-07 14.23.48.png](https://qiita-image-store.s3.amazonaws.com/0/53147/87053ada-2d90-6aa5-3531-ed3b54ffad49.png)

## データベースを使おう

PostgreSQL の使い方は、英語の記事になりますが、[Flask and PostgreSQL on Heroku](http://blog.y3xz.com/blog/2012/08/16/flask-and-postgresql-on-heroku)を参照すると良いでしょう（使ったことないもので・・・）。

なんで使ったことないかと言うと、無料枠は1万行までという制限がきつくて、[MongoHQ](https://addons.heroku.com/mongohq)を使っちゃうからです。MongoHQは512MBまでが無料枠です。小さなデータが数多くある場合はこちらの方が使い勝手が良いですね。

### MongoHQを使う

色々準備しましょう。

```shell-session
$ heroku addons:add mongohq
$ pip install pymongo
$ pip freeze > requirements.txt
```

アプリ＆テンプレートの修正

```py:app.py
#!/bin/env python
# coding: utf-8

import os
from urlparse import urlparse

from flask import Flask, render_template
from pymongo import Connection


app = Flask(__name__)
app.debug = True

MONGO_URL = os.environ.get('MONGOHQ_URL')

if MONGO_URL:
    # Get a connection
    connection = Connection(MONGO_URL)
    # Get the database
    db = connection[urlparse(MONGO_URL).path[1:]]
else:
    # Not on an app with the MongoHQ add-on, do some localhost action
    connection = Connection('localhost', 27017)
    db = connection['QiitaAdvent2014']


@app.route('/')
def index():
    return u'テスト'


@app.route('/hello/<name>')
def hello(name=''):
    if name == '':
        name = u'ななしさん'
    return render_template('hello.html', name=name)


@app.route('/hello2/<name>')
def hello2(name=''):
    if name == '':
        name = u'ななしさん'

    helloObj = db.hello.find_one({'name': name})
    if not helloObj:
        helloObj = {'name': name, 'count': 1}
    else:
        helloObj['count'] += 1
    db.hello.save(helloObj)

    return render_template('hello2.html', hello=helloObj)


@app.route('/debug')
def debug():
    return render_template('notemplate.html')


if __name__ == '__main__':
    port = int(os.environ.get('PORT', 5000))
    app.run(port=port)
```

```html+jinja:hello2.html
<html>
<head>
    <title>Hello {{ hello.name }}</title>
</head>
<body>
    <h1>こんにちは{{ hello.name }}さん</h1>
    <h2>{{ hello.count }}回目ですね！</h2>
</body>
</html>
```

https://stark-forest-4893.herokuapp.com/hello2/<名前> で名前ごとにカウントされるようになりました。色々と手抜きですが、サンプルということで。

## お次は

[kiyoto](http://qiita.com/kiyoto)さんによるfluentd, Postgres, TreasureData 関係だそうです！
fluentd は最近色々と話題ですね。私も興味があります。これらがどう heroku と結びつくのか・・・楽しみです。