LoginSignup
61
69

More than 3 years have passed since last update.

Flaskチュートリアル + herokuにデプロイ

Posted at

概要

Flaskに入門したのでherokuデプロイまでの手順を記して置こうと思います。

フェーズ1: Hello, World!アプリ
フェーズ2: sqliteを用いたflaskアプリ
フェーズ3: postgres + herokuにデプロイ

の順番でやっていこうと思います。

環境

  • macOS High Sierra 10.13.6
  • python 3.6.5

最終的なディレクトリ構成

最終的なディレクトリ構成はこのようになります。

flask-demo-app/
├── run.py
├── app
│   ├── __init__.py
│   ├── config.py
│   ├── views.py
│   ├── models.py
│   ├── test.db
│   └── templates/
├── Procfile
├── requirements.txt
└── venv/

プロジェクトの作成

mkdir flask-demo-app
cd flask-demo-app
git init

python 仮想環境 構築

python3 -m venv venv
source venv/bin/activate

venvに関してはこちらがわかりやすいです。
https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e

source venv/bin/activateするとこんな感じになっているはずです。

(venv)$ 

venv環境はgitで管理する必要はないので、
.gitignoreにvenvを追加しておきます。

.gitignore
venv

flaskのインストール

pipをアップグレードしてflaskをインストールします。

(venv)$ pip install --upgrade pip
(venv)$ pip install flask

フォルダの作成

(venv)$ mkdir main

今回は、このmainディレクトリにflaskの主要ファイルたちを置いていきます。

フェーズ1

まずは最小構成でHello, World!をしていきます。

run.py

アプリケーションをデバッグモードで起動するだけのプログラムです。

(venv)$ vim run.py
run.py
from main import app

if __name__ == '__main__':
    app.run(debug=True)

main/_init_.py

(venv)$ vim main/__init__.py
__init__.py
from flask import Flask

app = Flask(__name__)

import main.views

main packageがimportされた際にこのスクリプトが実行されます。

_init_.pyの働きに関してはこちらがわかりやすかったです。
https://www.kangetsu121.work/entry/2018/09/16/004008

main/views.py

(venv)$ vim main/views.py
views.py
import flask 
from main import app

@app.route('/')
def show_entries():
    return 'Hello, World!'

実行

(venv)$ python run.py

http://localhost:5000 へアクセス

Hello, World!が見えたらOK!

フェーズ2

sqliteデータベースを使用するアプリケーションにしてみます。
Entryというクラスを作成し、ブログ(title, text)を投稿できるようにしていきます。

flask_sqlalchemyのインストール

SQLAlchemyというORMを使用します。
flask用のものをインストール。

(venv)$ pip install flask_sqlalchemy 

main/_init_.py を編集

(venv)$ vim main/__init__.py
__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy # 追加

app = Flask(__name__)
app.config.from_object('main.config') # 追加

db = SQLAlchemy(app) # 追加

import main.views

main/config.py

(venv)$ vim main/config.py
config.py
import os

SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or "sqlite:///test.db"
SQLALCHEMY_TRACK_MODIFICATIONS = True
SECRET_KEY="secret key"

or 演算子を使用して、os.environ.get('DATABASE_URL')が空文字だった場合,右辺を代入するようにしています。
os.environ.get('DATABASE_URL')はherokuのpostgresで使用し、
右辺はsqliteのデータベースです。
こうすることでherokuの環境とローカルの環境で書き換える必要がありません。

SECRET_KEYはセッション情報を暗号化するためのキーです
実際に運用する場合には、SECRET_KEYは必ず変更してください。

main/models.py

models.py
from main import db
from flask_sqlalchemy import SQLAlchemy


class Entry(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.Text)
    text = db.Column(db.Text)

    def __repr__(self):
        return "<Entry id={} title={!r}>".format(self.id, self.title)


def init():
    db.create_all()

データベース作成

(venv)$ python -c "import main.models; main.models.init()"

SQLALCHEMY_DATABASE_URI の場所に作成されます。
main/test.dbが存在することを確認してください。

データ挿入

初期データをいくつかいれておきます。
インタラクティブシェルから挿入することができます。

(venv)$ python
>>> from main.models import Entry
>>> from main import db
>>> entry1 = Entry(title='title1', text='text1')
>>> db.session.add(entry1)
>>> db.session.commit()
>>> 
>>> entry2 = Entry(title='title2', text='text2')
>>> db.session.add(entry2)
>>> db.sesion.commit()
>>> db.session.commit()
>>> entries = Entry.query.all()
>>> entries
[<Entry id=1 title='title1'>, <Entry id=2 title='title2'>]
>>> exit()

2つのデータを挿入しました。

main/views.py を編集

main/views.py
import flask 
from main import app
from main.models import Entry # 追加

@app.route('/')
def show_entries():
    entries = Entry.query.all() # 追加
    return flask.render_template('entries.html', entries=entries) # 変更

flask.render_templateでhtmlテンプレートが使用できます。
htmlテンプレートはtemplatesに置きます。

htmlテンプレートの準備

(venv)$ mkdir main/templates
(venv)$ vim main/templates/entries.html 
entries.html
<!DOCTYPE html>
<html>
  <head>
    <title>flask demo app</title>
  </head>
  <body>
    <ul class="entries">
    {% for entry in entries %}
      <li>{{entry.title}} / {{entry.text}}</li>
    {% endfor %}
    </ul>
  </body>
</html>

実行

(venv)$ python run.py

http://localhost:5000 へアクセス

インタラクティブシェルで挿入したデータが見れたらOK!

フォームの追加

データが表示出来たので、htmlにフォームを設置し、
そこからDBへ追加できるようにします。

views.py の編集

(venv)$ vim main/views.py
views.py
import flask 
from main import app, db # 変更
from main.models import Entry

@app.route('/')
def show_entries():
    entries = Entry.query.all()
    return flask.render_template('entries.html', entries=entries)

# add_entry 関数の追加
@app.route('/add', methods=['POST'])
def add_entry():
    entry = Entry(
        title = flask.request.form['title'],
        text = flask.request.form['text']
    )
    db.session.add(entry)
    db.session.commit()
    return flask.redirect(flask.url_for('show_entries'))

htmlテンプレート の編集

(venv)$ vim main/templates/entries.html 
entries.html
<!DOCTYPE html>
<html>
  <head>
    <title>flask demo app</title>
  </head>
  <body>
    <!-- 追加 -->
    <form action="{{ url_for('add_entry') }}" method=post>
      <input type="text" name="title">
      <input type="text" name="text">
      <input type="submit">
    </form>
    <!-- ここまで -->
    <ul class="entries">
    {% for entry in entries %}
      <li>{{entry.title}} / {{entry.text}}</li>
    {% endfor %}
    </ul>
  </body>
</html>

実行

(venv)$ python run.py

http://localhost:5000 へアクセス

postしたデータがviewとしてみれたらOK!

フェーズ3

ここからはherokuへデプロイのための準備をしていく。

heroku用準備

gunicorn のインストール

(venv)$ pip install gunicorn

psycopg2 のインストール

pythonからPostgreSQLを使用するためにドライバのpsycopg2をインストールします。

(venv)$ pip install psycopg2-binary  

pip install psycopg2 を実行するとうまくいかなかったため、
こちらを実行しています。

Procfile の準備

heroku 上で実行するコマンドを記載します。

(venv)$ vim Procfile
Procfile
web: gunicorn run:app --log-file -

requirements.txt の準備

pip freeze でインストール済パッケージ一覧を表示することが出来ます。
herokurequirements.txtを頼りに必要なライブラリをインストールするので準備してあげます。

(venv)$ pip freeze > requirements.txt

herokuアプリの作成

ログイン

(venv)$ heroku login

アプリの作成

(venv)$ heroku create flask-demo-app

こういうエラーが出たら名前がすでに使われているので、
違う名前でアプリを作成してください。

Creating ⬢ flask-demo-app... !
 ▸    Name flask-demo-app is already taken

postgresql アドオンの追加

(venv)$ heroku addons:create heroku-postgresql:hobby-dev

heroku コミット

まずはgitにコミットして

(venv)$ git add .
(venv)$ git commit

herokuにpush!

(venv)$ git push heroku master

heroku にデータベース作成

(venv)$ heroku run python -c "import main.models; main.models.init()" 
(venv)$ heroku open

heroku で確認できたらOKです!


python 仮想環境を抜けるには下のコマンドです。

(venv)$ deactivate   

終わりに

heroku デプロイまで出来ましたでしょうか..?
flaskですが、ディレクトリ構成がかなり自由で、どういうファイル配置にしていくか悩みましたが、一旦これに落ち着きました。

なにか間違っているところやこうしたほうがいい!というところがあれば教えてくださると幸いです。

参考

61
69
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
61
69