Re:ゼロからFlaskで始めるHeroku生活 〜環境構築とこんにちは世界〜

# はじめに
部活のハッカソンにて、初めてPythonのFlaskをHerokuに乗せて簡単なAPIを作ったので書きたいと思います。

(2016/10/28追記)
SeleniumでPhantomJSを動かし、BeautifulsoupでスクレイピングするAPIのコードとその解説などは中編にあたる
[Re:ゼロからFlaskで始めるHeroku生活 〜Selenium & PhantomJS & Beautifulsoup〜](http://qiita.com/ymgn_ll/items/4c2964a14ff80ca2fa28)
にて、
そのプログラムをHerokuにデプロイするまでは後編にあたる
[Re:ゼロからFlaskで始めるHeroku生活 〜PhantomJSをHerokuへ〜](http://qiita.com/ymgn_ll/items/585e94a3d2d23ca1fec3)
にて書いているので合わせてご覧ください。
# 使用したもの
+ Mac OSX El Capitan 10.11.6
+ Python 3.5.1
	+ とりあえずPythonをやりたかった
	+ どうせPython触るならPython3を触りたかった
+ Flask
	+ Django使おうとしたら大きすぎて手に負えなかった
	+ jsonを返してくれるAPIならDB使わないしサンプルがシンプルだったFlaskにした
+ Heroku
	+ とりあえず使ってみたかった

####Pythonの環境
+ pyenv
+ pyenv-virtualenv(普通のvirtualenvじゃない！ここ重要)

## 最終目標
HerokuにPythonのFlaskで作ったものを置き、GETした時にjsonを返してくるAPIを作る
ついでにChrome対策
### 今回の目標
Pythonの環境構築をし、HelloWorldをするFlaskをHerokuに上げる所まで
### 次回の目標
PythonでWebページをスクレイピングし、json形式に加工して吐き出すようにしたものをHerokuにプッシュし、
HerokuからjsonをGETしてくる所まで

# 準備
##Pythonの環境
まずQiitaなどでわかりやすくまとめてくださっている方の記事を見ながら
homebrewなどで **pyenv** と **pyenv-virtualenv** を入れましょう！
参考:

+ [Mac上でpythonの環境作成](http://qiita.com/WizowozY/items/4c0b1c0dc93017855429)
+ [homebrew+pyenvを使ったvirtualenv環境の構築](http://qiita.com/s5601026/items/4bd70f03701ed1f78047)

ここで、pyenv-virtualenvではなく、通常のvirtualenvを入れようとしたり、
入れてしまうと面倒なことになる可能性があるため、入れる時は必ずpyenvのプラグインの方のvirtualenvを入れましょう
参考：http://qiita.com/who_you_me/items/09f572c842b1c3fea015


pyenvとpyenv-virtualenvのインストールができたら、Herokuに上げる予定のフォルダへ移動して環境の準備をします。

```
$ mkdir hello-flask
# プロジェクトのフォルダを作る

$ cd hello-flask
# フォルダに移動する


$ pyenv virtualenv 3.5.1 v3.5.1-flask 
# v3.5.1-flaskという名前の環境を作成する

$ pyenv versions
# v3.5.1-flaskが追加されているのを確認


$ pyenv shell v3.5.1-flask
# 作業用フォルダより下にこの環境を適用する

$ pyenv rehash
# 念のためrehashをしておく

$ pyenv versions
# v3.5.1-flaskに移動しているのを確認
```
こうすることで、このフォルダの中で様々なパッケージを入れても他の環境が汚れることはないし、
他のフォルダでFlaskを使う際もこれを適用すれば同じ環境を使うことができます！やったー！

# FlaskでHelloWorldするまで

## Flask
今回使うPythonのフレームワークを入れる

```
$ pip install flask
```
## Gunicorn
今回使うWebサーバーも入れる

```
$ pip install gunicorn
```

## Flaskのファイルを作っていく
```
$ touch hello.py Procfile
# flaskのファイルと設定を書くファイルを作る
```
```hello.py
# -*- coding: utf-8 -*-
# 日本語を使う場合は絶対に必要

# flaskなどの必要なライブラリをインポート
import os
from flask import Flask

# 自分の名称を app という名前でインスタンス化
app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello World!'
    
# bashで叩いたかimportで入れたかを判定する
if __name__ == '__main__':
    app.run()
```
Procfile

```
web: gunicorn hello:app --log-file=-
```
ここまで用意すれば、あとはPythonで起動すれば動く！便利！

```
$ python hello.py
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
```
こういう風になるので、言われるがままにわがままに 
http://127.0.0.1:5000/ にアクセスすれば・・・
![hello.png](https://qiita-image-store.s3.amazonaws.com/0/93180/54c86d53-1b33-fc37-a1fa-e64fb8d53186.png "hello.png")

書かれている通り control と C を同時押しすれば終了できます。

# Herokuへの旅立ち
## Herokuに登録する
https://www.heroku.com/
singupからアカウントを作りましょう。
完了確認メールが15分以内に返ってくるようなのでのんびり待機

新規登録できてダッシュボードまで見れたら準備完了です。

## 実際にHerokuへと上げる
いよいよ作ったものをHerokuにあげて行きます！
####使っているライブラリを書き出したファイルを作る
```
$ pip freeze > requirements.txt
```
Herokuはこのファイルを見て、ライブラリなどを用意するので、
このファイルを更新しないままHerokuに上げるとエラーが出てきます。
##Herokuとgit
### gitを適用してコミットまでしておく
```
$ git init
# フォルダにgitを設定する

$ git add .
# 全てをadd


$ git commit -m "helloworld"
# コミット名をhelloworldにしてコミットしておく
```

### ここからHerokuにあげていく
```
$ heroku login
# herokuにログインする　登録したメルアドとパスを入力

$ heroku create hello-flask
# herokuに対して新しいプロジェクトを作る
```
webのheroku上ではなく、この場で heroku create するとgitのリモートリポジトリの設定までしてくれます。
ただし、このherokuのプロジェクト名は他のユーザー含めて **heroku内で同じ名前が使用できない** ので、作れなかった場合は何か数字を後につけてもいいかもしれません
heroku create の後に何も書かなければherokuが自動で適当な名前をつけてくれます。

```
$ git push heroku master
# heroku masterとすることでherokuのリモートリポジトリにプッシュ
# このコマンド1つでheroku上にライブラリを入れたり色々してくれます

$ heroku open
# このコマンドで、URLをコピーしたりしなくてもブラウザで開いてくれる
```
heroku open　でherokuのURLが開いたら、HelloWorldが見れると思います。

ここまでくれば、この返す内容テキストををjsonにすることさえできれば、いわゆるjsonAPIになるはずですね！やったー！

# エラーが出た場合
herokuに上げたものを見た時、エラーが出てしまっている時は、
```$ heroku logs```
で見てみましょう
logsで見た時、行数が多くて見るのがイヤになるかもしれませんが、その中から自分が作ったファイル名を探して

```
File "/app/hello.py", line 10
```
のように書いてあれば、その箇所かそこに関係する箇所が間違っていることがわかります。

## エラーチェックシート
####pythonのファイル内で日本語を使っている場合
ファイルの一番上に

```
# -*- coding: utf-8 -*-
```
を書き忘れていませんか？コメントアウト内でも日本語を使う場合は必須です。
コメントアウトじゃない所で日本語使う場合、先頭にuをつける必要があるかもしれません

```hello.py
# 日本語で出力する場合
def index():
    return u'こんにちは 世界！！'
```

####herokuにpushした時に失敗した場合

```
$ pip freeze > requirements.txt
```
requirements.txtを作るのを忘れていたりしませんか？
また、プッシュできていてもエラーの出る場合は、このコマンドを一度実行した後に、
新しく追加したライブラリをファイル内で使ったりしていないかチェックしてみてください

##参考
+ [Python+Flask+Herokuで簡単webアプリ](http://qiita.com/gogotanaka/items/a30764001d9f312465d8)

##あとがき
改善点でしたり、間違い等ございましたら、コメント欄などでご指摘していただけたら幸いです。

Twitter:@ymgn_ll