2.1. Flaskアプリの作成¶
目的¶
Flaskアプリケーションを作成します。
対象¶
- ローカル環境
パラメータ¶
パラメータの指定¶
パラメータの確認¶
変数の確認:
cat << ECHO # 0.1. DIR_DEVELOP:"${HOME}/environment" DIR_DEVELOP="${DIR_DEVELOP}" # 0.2. PRJ_NAME:"handson-cli-repository" PRJ_NAME="${PRJ_NAME}" # 0.3. ENV_NAME:"venv" ENV_NAME="${ENV_NAME}" ECHO
実施¶
venv環境の作成¶
venv環境の作成
変数の設定:
DIR_PRJ="${DIR_DEVELOP}/${PRJ_NAME}" \ && echo ${DIR_PRJ}
結果(例):
${HOME}/environment/handson-cli-repository
コマンド:
mkdir -p ${DIR_PRJ} \ && cd ${DIR_PRJ}
コマンド:
python3 -m venv ${ENV_NAME}
結果(例):
(出力なし)
venv環境のアクティブ化
コマンド:
. ${ENV_NAME}/bin/activate
結果(例):
シェルプロンプトの先頭に"(venv) "が追加されます。
Flaskのインストール¶
コマンド:
pip install Flask
結果(例):
Successfully installed Flask-1.0.2 Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 click-6.7 itsdangerous-0.24
requirementsファイルの作成¶
コマンド:
pip freeze > requirements.txt \ && cat requirements.txt
結果(例):
click==6.7 Flask==1.0.2 itsdangerous==0.24 Jinja2==2.10 MarkupSafe==1.0 Werkzeug==0.14.1
アプリケーションの作成¶
変数の設定:
DIR_APP="${DIR_PRJ}" \ && echo ${DIR_APP}
結果(例):
${HOME}/environment/handson-cli-repository
コマンド:
mkdir -p ${DIR_APP}/helloworld
helloworld/__init__.py
コマンド:
cat << EOF > ${DIR_APP}/helloworld/__init__.py EOF cat ${DIR_APP}/helloworld/__init__.py
結果(例):
helloworld/application.py
コマンド:
cat << EOF > ${DIR_APP}/helloworld/application.py #!flask/bin/python import json from flask import Flask, Response from helloworld.flaskrun import flaskrun application = Flask(__name__) @application.route('/', methods=['GET']) def get(): return Response(json.dumps({'Output': 'Hello World'}), mimetype='application/json', status=200) @application.route('/', methods=['POST']) def post(): return Response(json.dumps({'Output': 'Hello World'}), mimetype='application/json', status=200) if __name__ == '__main__': flaskrun(application) EOF cat ${DIR_APP}/helloworld/application.py
結果(例):
#!flask/bin/python import json from flask import Flask, Response from helloworld.flaskrun import flaskrun application = Flask(__name__) @application.route('/', methods=['GET']) def get(): return Response(json.dumps({'Output': 'Hello World'}), mimetype='application/json', status=200) @application.route('/', methods=['POST']) def post(): return Response(json.dumps({'Output': 'Hello World'}), mimetype='application/json', status=200) if __name__ == '__main__': flaskrun(application)
helloworld/flaskrun.py
コマンド:
cat << EOF > ${DIR_APP}/helloworld/flaskrun.py import optparse def flaskrun(app, default_host="0.0.0.0", default_port="80"): """ Takes a flask.Flask instance and runs it. Parses command-line flags to configure the app. """ # Set up the command-line options parser = optparse.OptionParser() msg = 'Hostname of Flask app [{}]'.format(default_host) parser.add_option("-H", "--host", help=msg, default=default_host) msg = 'Port for Flask app [{}]'.format(default_port) parser.add_option("-P", "--port", help=msg, default=default_port) parser.add_option("-d", "--debug", action="store_true", dest="debug", help=optparse.SUPPRESS_HELP) options, _ = parser.parse_args() app.run( debug=options.debug, host=options.host, port=int(options.port) ) EOF cat ${DIR_APP}/helloworld/flaskrun.py
結果(例):
import optparse def flaskrun(app, default_host="0.0.0.0", default_port="80"): """ Takes a flask.Flask instance and runs it. Parses command-line flags to configure the app. """ # Set up the command-line options parser = optparse.OptionParser() msg = 'Hostname of Flask app [{}]'.format(default_host) parser.add_option("-H", "--host", help=msg, default=default_host) msg = 'Port for Flask app [{}]'.format(default_port) parser.add_option("-P", "--port", help=msg, default=default_port) parser.add_option("-d", "--debug", action="store_true", dest="debug", help=optparse.SUPPRESS_HELP) options, _ = parser.parse_args() app.run( debug=options.debug, host=options.host, port=int(options.port) )
スクリプトの作成
コマンド:
mkdir -p ${DIR_APP}/scripts
scripts/install_dependencies
コマンド:
cat << EOF > ${DIR_APP}/scripts/install_dependencies #!/bin/bash easy_install pip pip install virtualenv cd /home/ec2-user/python-flask-service virtualenv environment source environment/bin/activate pip install -r requirements.txt pip install supervisor python setup.py install EOF cat ${DIR_APP}/scripts/install_dependencies
結果(例):
#!/bin/bash easy_install pip pip install virtualenv cd /home/ec2-user/python-flask-service virtualenv environment source environment/bin/activate pip install -r requirements.txt pip install supervisor python setup.py install
scripts/start_server
コマンド:
cat << EOF > ${DIR_APP}/scripts/start_server cd /home/ec2-user/python-flask-service/ source environment/bin/activate supervisord -c scripts/supervisord.conf EOF cat ${DIR_APP}/scripts/start_server
結果(例):
cd /home/ec2-user/python-flask-service/ source environment/bin/activate supervisord -c scripts/supervisord.conf
scripts/stop_server
コマンド:
cat << EOF > ${DIR_APP}/scripts/stop_server pkill supervisord EOF cat ${DIR_APP}/scripts/stop_server
結果(例):
pkill supervisord
scripts/supervisord.conf
コマンド:
cat << EOF > ${DIR_APP}/scripts/supervisord.conf ;For a sample configuration file, refer to https://github.com/Supervisor/supervisor/blob/master/supervisor/skel/sample.conf [unix_http_server] file=/tmp/supervisor.sock ; (the path to the socket file) [supervisord] logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log) logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) logfile_backups=10 ; (num of main logfile rotation backups;default 10) loglevel=info ; (log level;default info; others: debug,warn,trace) pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid) nodaemon=false ; (start in foreground if true;default false) minfds=1024 ; (min. avail startup file descriptors;default 1024) minprocs=200 ; (min. avail process descriptors;default 200) [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket [program:flaskapplication] command = /home/ec2-user/python-flask-service/environment/bin/python /home/ec2-user/python-flask-service/helloworld/application.py autostart=true stdout_logfile = /var/log/flask-application-stdout.log stderr_logfile = /var/log/flask-application-stderr.log EOF cat ${DIR_APP}/scripts/supervisord.conf
結果(例):
;For a sample configuration file, refer to https://github.com/Supervisor/supervisor/blob/master/supervisor/skel/sample.conf [unix_http_server] file=/tmp/supervisor.sock ; (the path to the socket file) [supervisord] logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log) logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) logfile_backups=10 ; (num of main logfile rotation backups;default 10) loglevel=info ; (log level;default info; others: debug,warn,trace) pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid) nodaemon=false ; (start in foreground if true;default false) minfds=1024 ; (min. avail startup file descriptors;default 1024) minprocs=200 ; (min. avail process descriptors;default 200) [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket [program:flaskapplication] command = /home/ec2-user/python-flask-service/environment/bin/python /home/ec2-user/python-flask-service/helloworld/application.py autostart=true stdout_logfile = /var/log/flask-application-stdout.log stderr_logfile = /var/log/flask-application-stderr.log
テストの作成
コマンド:
mkdir -p ${DIR_APP}/tests
tests/test_application.py
コマンド:
cat << EOF > ${DIR_APP}/tests/test_application.py import json import pytest from helloworld.application import application @pytest.fixture def client(): return application.test_client() def test_response(client): result = client.get() response_body = json.loads(result.get_data()) assert result.status_code == 200 assert result.headers['Content-Type'] == 'application/json' assert response_body['Output'] == 'Hello World' EOF cat ${DIR_APP}/tests/test_application.py
結果(例):
import json import pytest from helloworld.application import application @pytest.fixture def client(): return application.test_client() def test_response(client): result = client.get() response_body = json.loads(result.get_data()) assert result.status_code == 200 assert result.headers['Content-Type'] == 'application/json' assert response_body['Output'] == 'Hello World'
setupスクリプトの作成
setup.py
コマンド:
cat << EOF > ${DIR_APP}/setup.py from setuptools import setup, find_packages setup( name='helloworld', packages=find_packages(), include_package_data=True, install_requires=[ 'flask', ], setup_requires=[ 'pytest-runner', ], tests_require=[ 'pytest', ], ) EOF cat ${DIR_APP}/setup.py
結果(例):
from setuptools import setup, find_packages setup( name='helloworld', packages=find_packages(), include_package_data=True, install_requires=[ 'flask', ], setup_requires=[ 'pytest-runner', ], tests_require=[ 'pytest', ], )