[PYTHON] Run the app with Flask + Heroku

I wanted to deploy an app made with Flask to a production environment. It wasn't easy, and I ended up facing the whole day. When I was doing it with Rails, it started up instantly with git push heroku master from heroku create.

That's why I will leave a memorandum until Flask is launched on Heroku.

Development environment

Click here for the technology used for deployment this time.

In the Flask tutorial, the DB is created with the db.create_all () command. However, for those who are accustomed to so-called migration files, it is still desirable to manage the state of the table. In that case, use Flask Migrate.

Initial build of the app

First of all, we will do the initial construction of the application. Flask is quite customizable, so different developers have different directory structures. I'm still looking for best practices, but in the end it looks like this.

app/
├── manage.py
├── main
│   ├── __init__.py
│   ├── views.py
│   ├── config.py
│   ├── models.py
│   ├── app.db
│   ├── static/
│   ├── templates/
│   └── instance
│       └──application.cfg
├── Procfile
├── requirements.txt
├── migrations/
└── venv/

Creating a project

$ cd APP
$ mkdir -p main/{static,templates,instance}
$ cd main
$ touch manage.py requirements.txt Procfile
$ touch main/{__init__,views,models,config}.py

Add style sheets and view parts as you like. This time, the DB works properly on Heroku, and I will do it until "Hello world!" Is issued, so only the back end.

manage.py A file to start and run flask.

manage.py


from main import app
app.run()

main/init.py Generate flask app.

main/__init__.py


from flask import Flask

app = Flask(__name__)

import main.views

main/views.py The view part that displays Hello world !.

main/views.py


from flask import render_template
from main import app, db

@app.route('/')
def home():
    return render_template('home/index.html')

Creating a configuration file

There are many articles on best practices around here, so I thought it would be easier to understand if you refer to them. Here, I will introduce the ones that can hide the secrets once they move.

main/config.py

main/config.py


import os

class BaseConfig(object):
    SQLALCHEMY_TRACK_MODIFICATIONS = False  

class DevelopmentConfig(BaseConfig):
    DEBUG = True
    TESTING = True
    SQLALCHEMY_DATABASE_URI = 'sqlite:///app.db'

class ProductionConfig(BaseConfig):
    DEBUG = True
    TESTING = True
    SQLALCHEMY_DATABASE_URI=os.environ.get('DATABASE_URL')

config = {
    "default": "main.config.BaseConfig",
    "development": "main.config.DevelopmentConfig",
    "production": "main.config.ProductionConfig",
}

def configure_app(app):
    config_name= os.getenv('FLASK_ENV')
    app.config.from_object(config[config_name])
    app.config.from_pyfile('application.cfg', silent=True)

** FLASK_ENV ** should be set as ʻexport FLASK_ENV = development`. What I'm saying here is that while the basic BaseConfig contents are used in common, the variable contents are separated according to the environment (development / production).

ʻOs.environ.get ('DATABASE_URL')` will automatically pull ** DATABASE_UEL ** to the database on Heroku, so set this for production.

main/instance/application.cfg

instance/application.cfg


SECRET_KEY='XXXXXXXXXXXXXXXXXXX'

Here, API keys that cannot be made public are listed. Also, be sure to write it in .gitignore and do not publish it.

Read the configuration file

Make the prepared configuration file available in __init__.py.

main/__init__.py


#Add the following contents
from main.config import configure_app

app = Flask(__name__, instance_relative_config=True)
configure_app(app)

Deploy to Heroku

Installation of gunicorn and psycpg2

Deploy to Heroku and install two libraries to use PostgreSQL.

$ pip install gunicorm
$ pip install psycopg2

Added to Procfile

Add commands to run the app on heroku.

web: gunicorn main:app --log-file -

Prepare installation package

pip freeze is a convenient command that lists all the library information used in the virtual environment.

$ pip freeze > requirements.txt

Deploy to Heroku app

I will omit the setting of heroku.

$ heroku create flask-app
$ git push heroku master
$ heroku config:set FLASK_APP=main
$ heroku config:set FLASK_ENV=production

At this point, if you do $ heroku open, you should see" Hello world! ".

Database settings

Creating a model

This time, we will prepare the ʻUser` model as a test.

main/models.py


from main import db

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    email = db.Column(db.String, unique=True)

    def __repr__(self):
        return '<User %r>' % self.name

Install Flask Migrate, SQL Alchemy

Install each library required to migrate the DB.

$ pip install flask_migrate
$ pip install flask_sqlalchemy

Model loading

Add the preparation for loading the set model to __init__.py.

main/__init__.py


#I will add the following
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

db = SQLAlchemy(app)
migrate = Migrate(app, db)
db.init_app(app)

import main.models

migration

Migrate according to the Flask Migrate command.

$ flask db init
$ flask db migrate
$ flask db upgrade

Doing this will generate a migrations file and a database called ʻapp.db`.

Migrate on Heroku

Prepare installation package

As before, set up the newly installed library for use on Heroku.

$ pip freeze > requirements.txt

Migration execution

I'm a little addicted to this, but for Heroku, I'll give the locally generated migrations files to the server and not run db init or db migrate.

$ heroku run flask db upgrade

References

Recommended Posts

Run the app with Flask + Heroku
Touch Flask + run with Heroku
Deploy the Flask app on Heroku
Deploy the Flask app on heroku
Easy web app with Python + Flask + Heroku
Getting Started with Heroku, Deploying Flask App
Run the flask app on Cloud9 and Apache Httpd
How to deploy a web app made with Flask to Heroku
(Failure) Deploy a web app made with Flask on heroku
Creating a simple app with flask
Deploy Flask app on heroku (bitterly)
Open the file with the default app
Azure table storage with PTVS Flask app
Deploy flask app with mod_wsgi (using pipenv)
Run the original YOLO with Jetson Nano
[Python] Run Flask on Google App Engine
Run the interaction model with Attention Seq2 Seq
Deploy the Django app on Heroku [Part 2]
Deploy the Django app on Heroku [Part 1]
Create a simple web app with flask
Launch Flask application with Docker on Heroku
How to upload with Heroku, Flask, Python, Git (4)
Create an image composition app with Flask + Pillow
Vienna with Python + Flask web app on Jenkins
Create a bulletin board with Heroku, Flask, SQLAlchemy
Easily realize microservices with Cloud Run x Flask
Run Flask on CentOS with python3.4, Gunicorn + Nginx.
I made a twitter app that decodes the characters of Pricone with heroku (failure)
Run Python with VBA
Run prepDE.py with python3
Run with CentOS7 + Apache2.4 + Python3.6 for the time being
How to upload with Heroku, Flask, Python, Git (Part 3)
Easy machine learning with scikit-learn and flask ✕ Web app
Create a Todo app with the Django REST framework
Until you run a Flask application on Google App Engine for the time being
Run Blender with python
How to upload with Heroku, Flask, Python, Git (Part 1)
linux with termux app
IP restrictions with Flask
How to upload with Heroku, Flask, Python, Git (Part 2)
POST the image with json and receive it with flask
Miscellaneous notes about deploying the django app on Heroku
Work memo that I tried i18n with Flask app
Hello world with flask
Run Apache2 + WSGI + Flask
Programming with Python Flask
Deploy a web app created with Streamlit to Heroku
Run iperf with python
Run the intellisense of your own python library with VScode.
From environment construction to deployment for flask + Heroku with Docker
Run LINE Bot implemented in Python (Flask) "without using Heroku"
How to run an app built with Python + py2app built with Anaconda
Create Heroku, Flask, Python, Nyanko bulletin boards with "csv files"
The highlight of REST + Normal Site construction with Flask, Eve
Easy deep learning web app with NNC and Python + Flask
Deploy Flask with ZEIT Now
Todo app with django-bootstrap-modal-forms plugin
Run python with PyCharm (Windows)
Hello World with Flask + Hamlish
Insert the debugger with nose
Run Python with CloudFlash (arm926ej-s)