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
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.
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é.
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.
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
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'
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
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)
# ...
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.
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