VS CodeとPythonとFlaskで作成したWeb APIをDockerコンテナ上で実行したり、リモートデバッグしたりしてみよう。
連載「Visual Studio Codeで始めるPythonプログラミング」
前回は、Flaskアプリの構成方法について見た。今回は、ToDoリストを扱うWeb APIをDockerコンテナに展開するまでを見ていこう。最後に、コンテナで実行されるコードをリモートデバッグする方法も簡単に見る。ただし、Dockerについての解説はここでは割愛する。Dockerの概要を知りたいという方は「超入門Docker」などを参照されたい。また、本稿の内容はWindows版のVisual Studio Code 1.26.1(以下、VS Code)、Python 3.6.5の仮装環境(myenv)、Docker for Windows 18.06.1を使用して検証している。
ここでは前々回に作成した、Web APIをベースとする。当初のファイル構成は次のようになる。なお、「pip install flask flask-sqlalchemy flask-cors flask-restless waitress」コマンドにより、必要となる各種パッケージ/モジュールをインストールしてある(最後のwaitressはWindowsやLinuxで動作するWSGI準拠のHTTPサーバで、これをプロダクション用のサーバと見立てて使用する)。
instanceフォルダは前回に説明した「インスタンスフォルダ」だ(本来は機密性のある情報などを保存しておく箇所)。アプリ本体はtodoapiパッケージに記述する。main.pyファイルは、todoapiパッケージをブートするためのコードだ。
todoapiフォルダには__init__.pyファイルとconfig.pyファイル、dbサブフォルダとその中にtodoitems.dbファイルがある。コードの主要な部分は__init__.pyファイルに記述した。
# __init__.pyファイル
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_restless import APIManager
from flask_cors import CORS
import os
from todoapi.config import Config, DevConfig, DockerConfig
config = {
"default": Config,
"dev": DevConfig,
"docker": DockerConfig
}
app = Flask(__name__, instance_relative_config=True)
cfg = config[os.getenv("TODOAPI_ENV", default="default")]
app.config.from_object(cfg)
app.config.from_pyfile("config.cfg")
db = SQLAlchemy(app)
manager = APIManager(app, flask_sqlalchemy_db=db)
CORS(app)
class ToDoItem(db.Model):
__tablename__ = "todoitems"
item_id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
done = db.Column(db.Boolean, nullable=False, default=False)
manager.create_api(ToDoItem,
methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
results_per_page=100)
@app.route("/")
def index():
return f'{app.config["TODOAPI_CONFIG"]}, <br>{app.config["TODOAPI_CONFIG2"]}'
# config.pyファイル
class Config():
TODOAPI_CONFIG = "configured by Config in config.py"
SQLALCHEMY_DATABASE_URI = "sqlite:///db/todoitems.db"
class DevConfig(Config):
TODOAPI_CONFIG = "configured by DevConfig in config.py"
class DockerConfig(Config):
TODOAPI_CONFIG = "configured by DockerConfig in config.py"
前回までのコードの総まとめといった感じのコードなので、詳しく説明はしない。説明が必要なのは、configオブジェクトとconfig.pyファイルの内容だ。これは前回に説明した通り、オブジェクトを使用してアプリの構成を行う例として含めてある。configオブジェクトは、config.pyファイルで定義されているクラスを値とする辞書となっている。そして、環境変数TODOAPI_ENVの値に応じて、アプリで使用する構成値を変化させようとしているということだ。例えば、環境変数TODOAPI_ENVの値が「dev」であれば、それに対応したDevConfigクラスを利用してapp.config.from_objectメソッドが実行される。その後、インスタンスフォルダから構成値を読み込むことで、状況に応じた多段階の構成を行うようになっている(が、なっているだけで、特にそれらしいことはしていない)。
インスタンスフォルダには以下に示すconfig.cfgファイルだけが含まれている。
TODOAPI_CONFIG2 = "configured in instance folder"
SQLALCHEMY_TRACK_MODIFICATIONS = True
「http://localhost:5000」にGETリクエストを送信したら、これらの構成値を確認するようにindex関数を記述している。
その間にあるデータベースモデルの定義や、Flask-Restlessを利用したWeb APIの作成、Flask-CORSを利用したクロスオリジンアクセスの許可といった事項については前々回の記事を参考にしてほしい。
todoitems.dbファイルを作成したら(簡単に書いておくと、「環境変数FLASK_APP」の値を「todoapi」パッケージに設定し、「flask shell」コマンドを実行したら、「from todoapi import db」コマンドでdbオブジェクトをインポートして、最後に「db.create_all()」を実行する)、コマンドパレットの[Python: Create Terminal]コマンドにより起動したターミナル内で「flask run」コマンドでWeb APIを起動できる。ただし、このときには既に何度も見てきたであろう以下のようなメッセージが表示される。
プロダクション環境で使用可能なスタンドアロンのWSGIサーバには幾つかの種類があり、「Standalone WSGI Containers」ページでも紹介されている。が、ここでは「Windowsでも動作する」ことをポイントとして、Waitressを使ってみることにした(本稿では開発はWindowsで行い、Linuxコンテナにそれを展開するため、両者で動作するものが適切だった)。Waitressを使って、Web APIを起動するのがmain.pyファイルの役目となる。
from todoapi import app
from waitress import serve
if __name__ == "__main__":
serve(app, host="0.0.0.0", port=5000)
ご覧の通り、Waitressが提供するserve関数に、todoapi.appオブジェクトを渡しているだけだ。よって、「python main.py」により、このWeb APIが起動するようになる(あるいは「waitress-serve --port=5000 todoapi:app」コマンドをコマンドラインで実行してもよい)。仮装環境を有効にしたターミナルから起動している様子を以下に示す。
前々回に作成したVue.jsプロジェクトを利用して、このWeb APIにアクセスしているところを以下に示す(Vue.jsプロジェクトのコードは割愛する)。
動作が確認できたところで、次はこのWeb APIをDockerで利用するためにDockerfileを記述してみよう。
Copyright© Digital Advantage Corp. All Rights Reserved.