「できるだけPythonだけでWEBアプリを作る第2弾」は、第1弾から少し構成を変えて、拡張性を考慮したやり方で作っていきます。
今回はZappaというフレームワークを使っており、様々なAWSの設定が簡単になる反面、裏で何をやっているのかが完全に理解できなかったので、とりあえずシステムの作成フローをこのページにまとめて、掘り下げて分かったことは追ってまとめようと思います。
第1弾(前回)記事は以下の通り。
dango-study.hatenablog.jp
目次
WEBアプリをクラウド(AWS)で作成するためのアプローチ
前回はとりあえずWEBアプリを作る!という感じだったので、特に気にしていなかったのですが、本来はどんなアプローチ方法がとれるのかを踏まえた上で適切に選択すべきなので、ここで一旦まとめようと思います。調べた限り、(AWS)サービスの組み合わせ方で言うと、かなり色々な方法があったので、主観ですが大きなくくりでまとめていきます。
FaaS(Function as a Service)サービスを使うアプローチ[AWS Lambda + API Gateway等]
FaaSとは「Function as a Service」の略で、サーバーレスでアプリケーション開発ができるクラウドサービスのこと。
AWS Lambda等のインスタンスを返してサーバーを任意のタイミングで利用するパターンで、サーバー管理はサービスベンダーが行うため、その費用などを抑えることができる。
CaaS(Container as a Service)サービスを使うケース[ECS + Fargate等]
CaaSとは「Container as a Service」の略で、コンテナ化をすることで環境に依存しない開発ができるクラウドサービスのこと。
CaaSサービスであるECSはAmazon EC2インスタンスを用いてDockerコンテナ管理することができるが、Amazon EC2のような仮想サーバーの管理は不要なアーキテクチャを構築できる。
IaaS(Infrastructure as a Service
IaaSとは「Infrastructure as a Service」の略で、サーバやストレージなどのインフラを提供するサービスのこと。
仮想サーバーを使用できることから開発自由度は上がるが、サーバー管理が必要であること(作業が増える)、コストが他と比較して高い。
LambdaとECS、EC2を様々な観点で比較結果は以下が詳しくまとめられていました。感謝です
EC2 vs ECS vs Lambda:APIのサービングの観点から | Hakky Handbook
つまり、使い分けは、以下の通りと理解しました。
現時点ではLambdaでできる範囲で問題がなさそうなので、コストを重視してLambdaを使う構成で対応します。
おすすめサービス | |
開発における制限(実行時間やライブラリ利用可否)を重視する場合 | ECSかEC2 |
コストを重視する場合 | Lambda |
アーキテクチャについて
(おさらい)前回作ったアプリのアーキテクチャ
以下画像のような構成で、Amazon S3に保存したHTMLファイルにアクセス頂き、HTMLページのボタンを押すと、JavaScriptからAmazon API GatewayにHTTPリクエストが送信され、 AWS Lambdaを動かして、計算した結果をJavaScriptでHTMLに上書きするといった動きをします。
今回作るアプリのアーキテクチャ
ここが完全に理解できていないので、現状記載ができない(後述のZappaが理解できていない)。なんで、前回と同じ構成で作らないのか?という疑問が出てくるが、今回はFlaskというPythonのWebアプリケーションフレームワークで作成したWebアプリケーションをAWSでデプロイしたいから、が理由になります。今後も想定すると、1からすべて作る前回の方法よりもフレームワークを使った方がよさそうだなと・・・また、今回はFlaskのWEBアプリケーションをAWSにデプロイするのに、Zappaというフレームワークも使っています。ZappaはAWS LambdaとAPI Gatewayを使って、FlaskやDjangoなどのPython WEBアプリケーションをデプロイすることができます。AWS上の設定などを自動で設定して、構成してくれるのが便利なようです。このような理由から、こちらを使いました。
AWS マネジメントコンソールのAWS Lambda画面では、以下のような画面になっていますが、全体の構成としては、AWS Lambda/EventBridge/API Gatewayの構成になっている?この辺りから怪しいのですが、アクセスするURL(WEBアプリ)はAPI Gatewayで作成するHTTPエンドポイントで、HTTPリクエストをAWS Lambda関数に転送して実行していると思っています。ただ、EventBridgeでAWS Lambdaを定期実行する必要があるのでしょうか?Zappaを使うと、インターフェースの設定を勝手にやってくれるのが便利なのですが、どう設定をしたのかを勉強したい人にとってはつらいですね・・・
分かっていない部分も多いですが、、じゃんけんゲームのアプリを作っていきます。
ちなみに、その他の同じような構成(FaaSサービスを使うケース)例として、以下を紹介しておきます。
AWS での開始方法 | AWS Lambda、Amazon API Gateway、AWS Amplify、Amazon DynamoDB、および Amazon Cognito を使用してサーバーレスウェブアプリケーションを構築する
開発環境
[ローカル]
・Microsoft Windows 10 Pro
・Python 3.9.0
[AWS]
・AWS Lambda ランタイム python3.9
・AWS API Gateway
・Amazon S3
開発手順
- 前準備
- アプリ作成(コード作成)
- コード実行(動作確認)
実装
前準備
AWS CLIを使えるようにする(省略)
ZappaではAWS CLIを使用する為、使えるようにしておく必要がある。
こちらは色々なページで記載があるので省略します。
AWS CLIの設定(以下)をするところまで対応します。
$ aws configure
仮想環境の導入
Zappaを使うには仮想環境の用意が必須となる為、その手順を説明します。
手順は以下の通りコマンドとともに示します。
1. 仮想環境を作る venvモジュールを使用する。pyenvモジュールを使うケースも多いみたいであるが、Windows OSだと問題がありそうなのでこっちを使う(私はpythonバージョン3.9.0が入っていたので、Python 3.9.0の仮想環境ができる) $ python -m venv <好きなファイル名> $ cd <上記コマンドで作成したファイルパス> 2. 仮想環境に入る $ Scripts\activate
必要モジュールのインストール
Zappaでは仮想環境の用意が必須で、アプリを構成するコード類と合わせて仮想環境のモジュールもzip化してAWS Lambdaにアップロードするので、不要なモジュールを入れすぎても負荷を掛けそうなので、最低限のモジュールをインストールする。
ここからの作業は仮想環境に入った状態で対応します。
$ pip install flask $ pip install zappa 私の環境では、この後のZappaモジュール実行時にurlib3に関するエラーが出た為(バージョン指定)、エラーに従って以下の通り対応した。 $pip uninstall urllib3 $pip install "urllib3>=1.25.4,<1.27"
アプリ作成(コード作成)
やっとアプリの作成に移り、じゃんけんゲームのアプリを作っていきます。
htmlは2種類、初期画面/じゃんけん結果画面の2つであり、コードを含めたもろもろの構成は以下の通りです。
<flask_sample> ├ <templates> │ ├ home.html 初期画面 │ └ result.html じゃんけん結果画面 └ __init__.py my_app4.py アプリで最初に実行されるファイル requirements.txt 必要モジュールなどを記載したtxt zappa_settings.json zappa設定ファイル
WEBページの作成
初期画面/じゃんけん結果画面は以下のコードで構成しています。
home.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>じゃんけんゲーム</title> <style> body { font-family: Arial, sans-serif; text-align: center; } h1 { font-size: 32px; } form { margin-top: 32px; display: flex; flex-direction: column; align-items: center; } form label { font-size: 20px; margin-bottom: 8px; } form input[type="radio"] { margin-right: 8px; } form button { margin-top: 16px; font-size: 24px; padding: 8px 16px; border: none; background-color: #1E90FF; color: #FFFFFF; border-radius: 8px; cursor: pointer; } form button:hover { background-color: #4169E1; } </style> </head> <body> <h1>じゃんけんゲーム</h1> <form action="{{ url_for('play') }}" method="POST"> <label><input type="radio" name="choice" value="グー" required>グー</label> <label><input type="radio" name="choice" value="チョキ">チョキ</label> <label><input type="radio" name="choice" value="パー">パー</label> <button type="submit">決定</button> </form> </body> </html>
ハマったところとして、画面遷移が最初はうまくいきませんでした・・・("forbidden 403"が表示)
該当箇所は、
pythonコードについて
pythonコードは2ファイル(__init__.pyだけの1ファイルだけでも良かったが・・)に分かれていて、最初にmy_app4.pyが実行される設定にしています。
コードは以下の通りです
my_app4.py
#---------- #Flaskアプリケーション実行ファイル #---------- from flask_sample import app if __name__ == "__main__": app.run()
__init__.pyを実行するだけの役割ですね
#---------- #Flaskアプリケーション立ち上げ後に呼び出されるファイル #my_app4.py→__init__.py #---------- #Flaskとrender_template(HTMLを表示させるための関数)をインポート from flask import Flask,render_template, request, url_for import random #Flaskオブジェクトの生成 app = Flask(__name__) #「/」へアクセスがあった場合に、「home.html」を返す @app.route("/") def home(): return render_template("home.html") @app.route("/result", methods=["POST"]) def play(): # ユーザーの選択を取得 print("def_play_start") user_choice = request.form["choice"] # コンピュータの選択をランダムに決定 choices = ["グー", "チョキ", "パー"] computer_choice = random.choice(choices) print("chiices", choices) # 勝敗を判定 result = "" if user_choice == computer_choice: result = "引き分け" elif (user_choice == "グー" and computer_choice == "チョキ") or (user_choice == "チョキ" and computer_choice == "パー") \ or (user_choice == "パー" and computer_choice == "グー"): result = "勝ち" else: result = "負け" # 結果を表示 return render_template("result.html", user_choice=user_choice, computer_choice=computer_choice, result=result)
コチラのコードがメインとなり、初期アクセスでは関数: homeが実行され、後述のhome.htmlが表示されます。
コード実行(動作確認)
アプリのデプロイ
作ったアプリは、zappa_settings.jsonファイルがあるディレクトに移動して、以下コードでAWSにデプロイします。
デプロイする $ zappa deploy default ←defaultは自分が設定した値 一度デプロイをして、アップデートをしたい場合は以下を実行 $ zappa update default ←defaultは自分が設定した値 アプリケーションを削除 $ zappa undeploy default ←defaultは自分が設定した値 デプロイ時などのエラーを見たい場合 $ zappa tail
デプロイが完了すると、以下文字が出力され、URLが吐き出される。
Your updated Zappa deployment is live!: https:/*******************
動作確認
吐き出されたURLにアクセスする。
決定をクリックする
どこからでもアクセスができるURLでじゃんけんゲームができるようになりました。