[PYTHON] [Premier développement personnel] L'histoire du déploiement de l'application Flask et du robot de réponse automatique de Twitter sur Heroku

introduction

Ce sera le premier message. Je suis un ingénieur PHP avec un an et demi d'expérience en programmation.

J'utilise AWS pour mon travail quotidien, mais je n'ai pas encore été impliqué dans l'environnement de production, je voudrais donc résumer ce que j'ai appris grâce à ce déploiement sur Heroku du point de vue d'un débutant.

Je vais présenter brièvement l'application que j'ai créée cette fois.

--Créez un écran de gestion pour ajouter / modifier du texte pour une réponse automatique avec flacon

--Bot est implémenté en utilisant la bibliothèque twitter de Python

Structure du répertoire

app/
├── web.py           #fichier d'exécution de l'application flask
├── web/             #application flacon
│   ├── models/
│   ├── static/
│   ├── templates/
│   ├── views/
│   ├── __init__.py
│   ├── config.py
│   └── database.py
├── twitter.py       #Fichier d'exécution du robot de réponse automatique
├── twitter/         #Bot de réponse automatique (partiellement omis)
│   ├── __init__.py
│   ├── config.py
│   └── database.py
├── Procfile
├── requirements.txt
├── runtime.txt
├── .env
├── .gitignore
├── migrations/      # Flask-Créé avec Migrate
└── venv/            #Environnement virtuel local

Concernant le flacon, je me suis référé à l'article suivant.

Fichiers requis pour déployer sur Heroku

Il semble que vous deviez préparer un fichier pour indiquer à Heroku l'environnement, les bibliothèques nécessaires et les fichiers exécutables.

requirements.txt

Répertoriez les bibliothèques requises, y compris la version. Depuis que j'ai développé avec venv, j'exporte le package installé dans l'environnement virtuel dans un fichier avec la commande suivante.

(venv)$ pip freeze > requirements.txt

Liste des bibliothèques installées

requirements.txt


alembic==1.4.2
autopep8==1.5.3
cffi==1.14.0
click==7.1.2
cryptography==2.9.2
Flask==1.1.2
Flask-Login==0.5.0
Flask-Migrate==2.5.3
Flask-SQLAlchemy==2.4.3
gunicorn==20.0.4
itsdangerous==1.1.0
Jinja2==2.11.2
Mako==1.1.3
MarkupSafe==1.1.1
pycodestyle==2.6.0
pycparser==2.20
PyMySQL==0.9.3
python-dateutil==2.8.1
python-dotenv==0.14.0
python-editor==1.0.4
six==1.15.0
SQLAlchemy==1.3.18
toml==0.10.1
twitter==1.18.0
Werkzeug==1.0.1

runtime.txt

Il semble que cela ne doit pas être séparé, mais je vais le préparer pour spécifier la version de python. Veillez également à spécifier les versions prises en charge par Heroku (https://devcenter.heroku.com/articles/python-support).

runtime.txt


python-3.7.8

Procfile

Spécifiez comment lancer l'application. L'application flask doit utiliser un serveur WSGI tel que gunicorn dans un environnement de production.

Procfile


web: gunicorn web:app --log-file=-
worker: python twitter.py

web lance une instance Flask appelée app dans web.py. Dans worker, le fichier d'exécution twitter.py du Bot de réponse automatique est exécuté.

Définition des variables d'environnement

Je suis tombé sur la façon de définir différentes variables d'environnement (ex. Informations de base de données) entre l'environnement local et l'environnement de production sans réécrire le code, je vais donc les résumer.

Variables d'environnement Heroku

Vous pouvez définir des variables d'environnement avec la commande suivante. (Vous devez installer Heroku CLI (https://devcenter.heroku.com/articles/heroku-cli) pour utiliser la commande)

$ heroku config:set DB_HOST=xxxxxxxxxxx

Vous pouvez afficher la liste des variables d'environnement et vérifier si elles ont été définies.

$ heroku config

Pour le paramétrage des variables d'environnement de MySQL DB, reportez-vous ici. ・ Comment utiliser MySQL avec Heroku

Variables d'environnement local

Préparez un fichier .env et décrivez-y les variables d'environnement. Ce sont des informations sensibles, alors n'oubliez pas de les ignorer.

.env


ENV = 'LOCAL'

# DB
DB_HOST = 'xxxxx'
DB_NAME = 'xxxxx'
DB_USER = 'xxxxx'
DB_PASSWORD = 'xxxxx'

# Session
SESSION_SECRET_KEY = 'xxxxx'

Lire les variables d'environnement du côté de l'application

Lisez les variables d'environnement dans app / web / config.py comme indiqué ci-dessous et configurez les paramètres du côté de l'application.

config.py


"""Fournir la configuration du flacon"""
import os
from os.path import join, dirname
from dotenv import load_dotenv

dotenv_path = join(dirname(__file__), '../.env')
load_dotenv(dotenv_path)


class Config:

    # Flask
    if (os.environ.get('ENV') == 'LOCAL'):
        DEBUG = True
    else:
        DEBUG = False

    # Session
    SECRET_KEY = os.environ.get('SESSION_SECRET_KEY')

    # SQLAlchemy
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://{user}:{password}@{host}/{db_name}?charset=utf8'.format(**{
        'user': os.environ.get('DB_USER'),
        'password': os.environ.get('DB_PASSWORD'),
        'host': os.environ.get('DB_HOST'),
        'db_name': os.environ.get('DB_NAME')
    })
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_ECHO = False


Config = Config

Avec ce paramètre, les variables d'environnement peuvent être lues à la fois dans l'environnement Heroku et dans l'environnement local. Pour la gestion des variables d'environnement en Python, je me suis référé ici. ・ Comment écrire des variables d'environnement que vous ne voulez pas mettre sur [GitHub] Python

Comment mettre en œuvre une réponse par compte et par jour

Comme il n'est pas bon pour l'API Twitter de répondre automatiquement plusieurs fois en peu de temps, nous lui avons fait une spécification d'une réponse par compte et par jour.

Je me demandais comment gérer les utilisateurs qui ont répondu une fois.

De plus, Dynas est redémarré (diffusé) au moins une fois par jour pour maintenir la santé de l'application exécutée sur Heroku. Toutes les modifications apportées au système de fichiers local seront supprimées. Le cycle se produit toutes les 24 heures (plus jusqu'à 216 minutes aléatoires pour empêcher tous les dynos de l'application de redémarrer en même temps).

Redémarrage automatique de Heroku semble être effectué toutes les 24 heures, donc cette fois c'est sur le fichier Python spécifié comme worker (toujours en boucle) ) J'ai décidé de gérer les utilisateurs qui ont répondu. En faisant cela, la liste sera initialisée à chaque redémarrage automatique et vous serez en mesure de répondre automatiquement toutes les 24 heures.

twitter.py


replied_user_list = [] #Gérer les utilisateurs qui répondent dans une liste

#Continuez à surveiller pendant 24 heures (le programme continue de fonctionner)
for tweet in twitter_stream.statuses.filter(language='ja', track=tracking_text):
    #Ci-dessous, un mot spécifique (tracking)_Traitement lorsqu'un tweet contenant du texte) est détecté
    # ...
    #La réponse automatique s'ajoutera à la liste
    replied_user_list.append(user_id)
    # ...

Problème selon lequel le travailleur dort lorsque le Web est en veille

Le plan Free Dyno de Heroku se met automatiquement en veille si vous n'accédez pas à l'application Web pendant 30 minutes. Il n'y a pas de problème avec cela, mais il semble que lorsque web dort, worker dort également. [https://devcenter.heroku.com/articles/free-dyno-hours#dyno-sleeping]

Apps that only utilise a free worker dyno do not sleep, because they do not respond to web requests. Be mindful of this as they may run 24/7 and consume from your pool of hours.

C'est tout un problème car le robot de réponse automatique cessera de répondre si le worker s'endort.

Par conséquent, il semble y avoir une solution de contournement telle que l'envoi d'une demande périodiquement comme suit pour empêcher «web» de dormir. ・ Quatre façons de faire fonctionner le dyno gratuit d'Heroku 24 heures sur 24

Dans ce cas, le dynamomètre "web" et le "worker" continueront à fonctionner 24 heures sur 24, dépassant le temps libre du dynamomètre de 1000 heures / mois.

En conséquence, j'ai décidé d'arrêter web sauf en cas de besoin. (Facile à lancer sur le tableau de bord Heroku) Puisque «worker» seul ne dort pas, le bot de réponse automatique peut maintenant être opérationnel 24 heures sur 24.

Résumé

C'était la première fois que je développais une application Web avec python, et je pensais que j'écrirais à ce sujet, mais cette fois, j'ai principalement écrit sur ce sur quoi j'ai trébuché lors du déploiement sur Heroku.

J'ai bien compris que j'avais besoin d'acquérir plus de connaissances que le codage. À l'avenir, j'aimerais étudier AWS et devenir associé d'AWS Solution Architect.

Puisqu'il s'agit de mon premier blog technique, j'apprécierais vos conseils sur des questions non techniques telles que la difficulté à lire. Bien entendu, j'apprécierais vos suggestions techniques.

Recommended Posts

[Premier développement personnel] L'histoire du déploiement de l'application Flask et du robot de réponse automatique de Twitter sur Heroku
Déployez l'application Flask sur Heroku
Déployez l'application Flask sur heroku
Notes diverses sur le déploiement de l'application django sur Heroku
Un mémorandum où je suis tombé sur mon HEROKU & Python personnel (Flask)
L'histoire de la création d'un outil qui fonctionne sur Mac et Windows sur le site de développement de jeux
L'histoire de Python et l'histoire de NaN
Exécutez l'application avec Flask + Heroku
Déployer l'application Flask sur heroku (amer)
Déploiement Heroku de la première application Django à laquelle les débutants sont accros
L'histoire de l'exécution de l'application asp.net core 3.1 sur la version arm64 Amazon Linux 2
Déployer l'application Django sur Heroku [Partie 2]
Déployer l'application Django sur Heroku [Partie 1]
L'histoire d'essayer deep3d et de perdre
Changer l'ordre de PostgreSQL dans Heroku
Premiers pas avec Heroku, déploiement de l'application Flask