WebAPIスタブの作成を依頼された
いまどきWebAPIスタブを作るのには、"Python の FastAPI + Uvicorn, Gunicorn" がよいとのことを教えてもらったので調査したメモ。
環境
Proxmox の LXC で作業してます。
# cat /etc/redhat-release
AlmaLinux release 10.1 (Heliotrope Lion)
Python で Uvicorn, Gunicorn
最近では、Gunicorn(WSGI/同期),Uvicorn(ASGI/非同期)で、FastAPI(Python/pip)の組み合わせが定番ということでインストール。
python + pip をインストール
# dnf install python3-pip
# dnf install python3.12
# python3 -V
Python 3.12.12
# pip3 -V
pip 23.3.2 from /usr/lib/python3.12/site-packages/pip (python 3.12)
python 仮想環境の作成
$ python3 -m venv venv
$ source venv/bin/activate
((venv) ) $
Uvicorn, Gunicorn, FastAPI の インストール
((venv) ) $ pip3.12 list
((venv) ) $ pip3.12 install gunicorn uvicorn fastapi
Uvicore の起動ができるか簡易サーバで確認などしてみる
下記のファイルを mai.py で作成しておく。
# mai.py
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8080, log_level="info")
uvicornを起動してみる。※firewallを停止するか穴あけしておく
((venv) ) $ uvicorn main:app --port 8080 --host 0.0.0.0 --reload
Gunicorn で systemd 化してみる
Uvicorn+FastAPI での起動確認ができたので Gunicorn によるワーカ起動とsystemd 化してみる
ディレクトリ・ファイル構成
/home
└── test
├── logs
├── venv
└── webapp
├── gunicorn_config.py
└── main.py
systemd のファイルを作成 /etc/systemd/system/test-gunicon.service
#
# /etc/systemd/system/test-gunicorn.service
#
[Unit]
Description=Python+Gunicron+Uvicorn Test
After=network.target
[Service]
User=実行したいユーザを指定
Group=実行したいユーザグループを指定
UMask=002
WorkingDirectory=/home/test/webapp
ExecStart=/home/test/venv/bin/gunicorn -c /home/test/webapp/gunicorn_config.py main:app
Restart=always
Environment="PATH=/home/test/venv/bin"
[Install]
WantedBy=multi-user.target
Gunicorn の 設定ファイルも用意しておく
# /home/test/webapp/gunicorn_config.py
chdir = '/home/test/webapp'
pythonpath = '/home/test/venv/bin'
workers = 2
worker_class = 'uvicorn.workers.UvicornWorker'
bind = '0.0.0.0:8080'
pidfile = '/tmp/prod.pid'
#daemon = True
errorlog = '/home/test/logs/error_log.txt'
proc_name = 'my_python_app'
accesslog = '/home/test/logs/access_log.txt'
loglevel = 'debug'
さて…うまく起動するかな?
# systemctl start test-gunicon.service
# systemctl status test-gunicon.service
status=Failed になったら… journalctl コマンドで確認してみる。
# journalctl -u test-gunicon.service
確認してみる
$ curl http://127.0.0.1:8080
{"Hello":"World"}
ここまでの感想
とりあえず Uvicorn が非同期での処理ができるとか…ありますが、最初の環境設定で躓かないのはエンジニアとして歓迎すべきことかなと思いました。
参考にさせて頂いたサイト様