前段の話
お恥ずかしい話ですが、私はちゃんと使える言語がPHPだけです。他のメジャーな言語やトレンディな言語やフレームワークに対しては苦手意識があり、Webに公開するためにはどうサーバー構成したらいいのかわかっていません。PHPなら、LinuxにApacheとPHPをインストールしてルートディレクトリに.phpファイルをアップしてURLをたたけば実行されますが、他の言語は一体どうすればいいの?状態です。
PythonについてはGoogle Colaboratory上でちょっとした作業効率化のプログラムを書いて活用などはしたことがありますが、アプリケーションを作って公開するにはどうしたらいいのか知識がありません。
そこで、Pythonで書いたプログラムをWebサーバーにアップして動作させるには何をどうしたらいいのかをChatGPT先生に聞いてみました。結果、とっても優しく丁寧に教えていただき、大変勉強になりました。ありがとう!ChatGPT先生!
※自分が使ってるサーバーはEC2上のAmazonLinux2なので、Ubuntuじゃないですってこの段階で言っておけばよかった。こういう前提は遠慮なく先に言っておいた方がChatGPT先生にとっても自分にとっても無駄がなくて良い結果を生むと思いました。
前提
サーバー:AWS EC2(AmazonLinux2)
Webサーバー:Apache2インストール済み
※独自ドメインとサブドメインを設定済み
※SSLを設定済み
以下に、ChatGTP先生に教えていただいたことをまとめました。
Step01:PythonとWSGIのインストール
Linuxサーバーにログインし、ルート権限でインストールします。
WSGIとはApacheとPythonをつなげるインターフェースモジュールです。
Python3とWSGIをインストール
# yum install python3
# yum install mod_wsgi-python3
※ 2行目のmod_wsgi-python3はリポジトリになかったようでインストールできなかったので、ChatGPT先生から代替方法として、手動で mod_wsgi
モジュールをビルドしてインストールする方法を提案されました。
補足:上記はChatGTPに指示されたとおりに進めてますが、ググると、yumで「python3」「python3-devel」「gcc」をインストールした後に、「pip3 install mod_wsgi」でモジュールをインストールするのが良いようです。
mod_wsgiをビルドするのに必要なものをインストール
# yum groupinstall "Development Tools"
# yum install httpd-devel
# yum install python3-devel
mod_wsgiをダウンロードしてビルド
# wget https://github.com/GrahamDumpleton/mod_wsgi/archive/refs/tags/4.9.0.tar.gz
# tar -xvf 4.9.0.tar.gz
# cd mod_wsgi-4.9.0
# ./configure --with-python=/usr/bin/python3
# make
# make install
※wgetは自分のHomeやテンポラリディレクトリなどで行ってくださいね
Step02:Apacheのconfの設定
ApacheとPythonアプリケーションをつなぐための設定を記述します。
/etc/httpd/conf.d/ssl.conf
<VirtualHost *:443>
ServerName myapp.example.com:443
ServerAlias myapp.example.com
DocumentRoot /var/www/myapp
#(略)
WSGIDaemonProcess myapp python-path=/var/www/myapp
WSGIProcessGroup myapp
WSGIScriptAlias / /var/www/myapp/myapp.wsgi
<Directory /var/www/myapp>
Require all granted
</Directory>
</VirtualHost>
WSGIなんたら、という3つの設定ですね。ドメインのルートにアクセスしたら、ルートディレクトリの「myapp.wsgi」を実行せよという設定です。
そしてモジュールを有効にする設定を、モジュールのconfにも記述します。
/etc/httpd/conf.modules.d/wsgi.conf を新規作成しました
LoadModule wsgi_module modules/mod_wsgi.so
Apache再起動します
# systemctl restart httpd.service
Step03:pythonプログラムと、wsgiファイルの作成
環境は無事設定できました。サンプルプログラムを動作させたいけど自分で書くのは大変なのでこれもChatGTPに聞きました。
※なんかmyappの下にmyappを掘ってくれたのですがたぶん違うんだろうなと解釈してルートディレクトリ(/var/www/myapp/)の下に、Pythonのプログラムファイルと、WSGIファイルを作成します。
app.py
def application(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'text/plain')]
start_response(status, headers)
return [b'Hello, World!\n']
myapp.wsgi
#!/usr/bin/python3
import sys
import os
sys.path.insert(0, '/var/www/myapp')
from app import application
このスクリプトは、app.py から application 関数をインポートし、WSGI アプリケーションとして使用します。(ChatGTP談)
Step04:ブラウザで確認する
ブラウザでhttps://myapp.example.comにアクセスすると…
でたーーーー!!!できました!
ChatGTP先生ありがとう!
ねぎらいの言葉も優しい。
疑問に思ったこともぶつけてみた
この状態でphpのような感覚でなんらかの.wsgiファイルを作って配置し、そのURLにアクセスしてもそれは実行されません。/myapp.wsgiが実行されます。どんなデタラメなURLを叩いても/myapp.wsgiの中身が実行されます。
PHPだとサーバーのルートディレクトリに階層を作ってそこにファイルを置けば、そのまんまのディレクトリとファイル名でアクセスできますが、WSGIをconfに設定しなきゃいけないのは何故?たくさんプログラムがあったらその分confに指定しなきゃいけないの?(そんなわけないよな)と思ったので先生に聞いてみました。
エイリアスに指定したファイルにルーティング処理を書けばいいとのことでサンプルもくれました。
from werkzeug.wrappers import Request, Response
def application(environ, start_response):
request = Request(environ)
script_name = request.script_root
if request.path.startswith('/app1'):
# /app1 の場合のアプリケーション
response = Response("This is App 1")
elif request.path.startswith('/app2'):
# /app2 の場合のアプリケーション
response = Response("This is App 2")
else:
response = Response("Hello, World!")
return response(environ, start_response)
if __name__ == '__main__':
from werkzeug.serving import run_simple
run_simple('localhost', 4000, application)
「Pythonでは、直接ファイルのURLにはアクセスせず、ルーティングによって処理を書き分けるのが一般的なのですね。」と問いかけたら解説してくれました。
Pythonのウェブアプリケーション開発において、一般的なアプローチは直接ファイルのURLにアクセスするのではなく、ルーティングを使用して処理を書き分けることです。これは、多くのPythonウェブフレームワーク(例: Flask、Django、FastAPIなど)が採用しているパターンです。
以下はその理由とメリットです:
- URLパスの抽象化: ルーティングを使用すると、特定のURLパスが特定の関数やビューにマップされ、そのルートURLパスの内部の詳細を隠すことができます。これにより、URL構造を変更しやすくなり、アプリケーションの柔軟性が向上します。
- リクエストとレスポンスの処理: ルーティングを使用すると、リクエストを受けて適切なビュー関数を呼び出し、そのビュー関数がレスポンスを生成する仕組みを作成できます。これにより、リクエストの処理が明確に分かれ、コードが整理しやすくなります。
- RESTful APIの実装: ルーティングはRESTful APIの実装に非常に適しており、HTTPメソッド(GET、POST、PUT、DELETEなど)に基づいて異なる操作を実行できます。
- テスト容易性: ルーティングを使用すると、個々のビュー関数やエンドポイントを単体でテストしやすくなり、ユニットテストが容易になります。
- 拡張性: 新しいエンドポイントやビューを追加し、アプリケーションの機能を拡張しやすくなります。
Pythonのウェブフレームワーク(例: Flask、Django、FastAPI)では、ルーティング機能が組み込まれており、URLパスとビューのマッピングを効率的に実現できます。したがって、Pythonウェブアプリケーションを開発する際には、このルーティングパターンを活用することが一般的です。
先生、勉強になります。
発生したエラーメッセージから素早く対処法を教えてくれる
また、インストールや設定でエラーが出たときなどもこれまではGoogle先生に聞いて答えを探して試して解決していましたが一発で対処法を教えてくださいます。
まとめ
知識ゼロからPythonでHello,Worldするまで2時間程度(途中お茶をいれたりお菓子を食べたりしつつ)で到達できました。
プログラミング環境構築の家庭教師としてChatGTP先生は優しくて親切で時間を問わずに対応してくれてとっても良い!と思いました。(とはいえ、Hello,Worldレベルなのでもうすこし複雑な事を試みたら使えないってこともあるかもしれません)
この調子で、ちょっとしたアプリケーションを作成するまでやってみようと思っています。