はじめに
どうも、水無月せきなです。
PythonのWebフレームワークである FastAPI の学習として、ローカルで動作する Todo アプリ(API)を作ってみました。
本シリーズでは、アプリの開発過程で得た知見や工夫点などを数回に分けて紹介していきます。
初回となる今回は、以下の内容を取り上げます。
- 使用した技術スタック
- 開発環境(devcontainerなど)
- 使用ライブラリのインストール
シリーズ一覧
- 🛠️FastAPI × SQLModelで作るTodoアプリ①:開発環境とプロジェクトのセットアップ
- 🗄️FastAPI × SQLModelで作るTodoアプリ②:AlembicによるDBマイグレーション入門
- 📝FastAPI × SQLModelで作るTodoアプリ③:アーキテクチャと実装の詳細
- 🧪FastAPI × SQLModelで作るTodoアプリ④:テストの手法と実装
リポジトリ
技術スタック
- 言語:Python
- Webフレームワーク:FastAPI
- DB:PostgreSQL
- ORM:SQLModel
- その他
- パッケージマネージャー:uv
- テスト関連
- pytest
- pytest-mock
- pytest-cov
- pytest-postgresql
- フォーマッター:ruff
開発環境
Windows 11 24H2
WSL2
Docker Desktop 4.43.1
Cursor 1.2.2
Python 3.12
PostgreSQL 15
環境構築
良さげなテンプレートがあったので、拝借しました。
ただ、DBを追加したかったので、compose.ymlを追加したりと色々いじっています。
以下は、追加・修正したファイルです(記載が漏れてたらすみません)。
devcontainer.json
{
"name": "python-devcontainer",
- "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
- "containerEnv": {
- "DISPLAY": "${localEnv:DISPLAY}",
- "PYTHONUNBUFFERED": "1",
- "PYTHONDONTWRITEBYTECODE": "1",
- "UV_CACHE_DIR": "${containerWorkspaceFolder}/.cache/uv",
- "UV_LINK_MODE": "copy",
- "UV_PROJECT_ENVIRONMENT": "/home/vscode/.venv",
- "UV_COMPILE_BYTECODE": "1"
- },
+ "dockerComposeFile": "compose.yml",
+ "service": "app",
+ "workspaceFolder": "/workspace",
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {},
- "ghcr.io/devcontainers/features/common-utils:2": {
- "configureZshAsDefaultShell": true
- },
- "ghcr.io/rocker-org/devcontainer-features/apt-packages:1": {
- "packages": "curl,wget,git,jq,ca-certificates,build-essential,ripgrep"
- },
"ghcr.io/va-h/devcontainers-features/uv:1": {
"shellAutocompletion": true
},
- "ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}
},
"runArgs": [
- "--init",
- "--rm"
+ "--init"
],
"hostRequirements": {
"gpu": "optional"
},
"customizations": {
"vscode": {
"settings": {
"python.defaultInterpreterPath": "/home/vscode/.venv/bin/python"
},
"extensions": [
"ms-python.python",
"charliermarsh.ruff",
"eamodio.gitlens",
"tamasfe.even-better-toml",
"ms-toolsai.jupyter",
"yzhang.markdown-all-in-one"
]
}
},
- "mounts": [
- "source=claude-code-config,target=/home/vscode/.claude,type=volume"
- ],
- "postCreateCommand": "uv sync",
+ "postCreateCommand": "uv sync --dev",
"postStartCommand": "uv run pre-commit install"
}
compose.yml
services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ..:/workspace:cached
- claude-code-config:/home/vscode/.claude
environment:
DISPLAY: "${DISPLAY:-}"
PYTHONUNBUFFERED: "1"
PYTHONDONTWRITEBYTECODE: "1"
UV_CACHE_DIR: "/workspace/.cache/uv"
UV_LINK_MODE: "copy"
UV_PROJECT_ENVIRONMENT: "/home/vscode/.venv"
UV_COMPILE_BYTECODE: "1"
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_SERVER: ${POSTGRES_SERVER}
POSTGRES_PORT: ${POSTGRES_PORT}
# Keep container running
command: sleep infinity
depends_on:
- db
db:
image: postgres:15
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
claude-code-config:
Dockerfile
FROM mcr.microsoft.com/devcontainers/base:ubuntu
# Set environment variables
ENV DEBIAN_FRONTEND=noninteractive \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
UV_CACHE_DIR=/workspace/.cache/uv \
UV_LINK_MODE=copy \
UV_PROJECT_ENVIRONMENT=/home/vscode/.venv \
UV_COMPILE_BYTECODE=1
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
wget \
git \
jq \
ca-certificates \
build-essential \
ripgrep \
&& rm -rf /var/lib/apt/lists/*
# Install Node.js (for additional development tools)
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - \
&& apt-get install -y nodejs
.env
POSTGRES_DB={お好みのDB名}
POSTGRES_USER={お好みのユーザー名}
POSTGRES_PASSWORD={お好みのパスワード}
POSTGRES_SERVER={compose.ymlで定義したDBのサービス名}
POSTGRES_PORT={compose.ymlで定義したDBサービスのポート}
開発の準備
FastAPIのインストール
英語版のチュートリアルにならって、FastAPIをインストールします。
uv add "fastapi[standard]"
データベース関連のインストール
uv add sqlmodel
uv add psycopg2-binary
uv add alembic
SQLModel
FastAPIの作者と同じ人が作っているORMライブラリです。
psycopg
今回データベースにPostgreSQLを採用したため、ドライバとして入れました。
Alembic
SQLModelだとマイグレーションができない1ので、マイグレーション管理用に入れました。
テスト関連のインストール
uv add pytest-mock
uv add pytest-cov
uv add pytest-postgresql
uv add "psycopg[binary]"
pytest-mock
モックを使いたかったので入れました。
Python標準でもモックはあるようですが、こちらの方が良いっぽいです。
pytest-cov
テストコードを書くので、カバレッジを見たいということで導入しました。
pytest-postgresql
テスト用のDB作成とテスト終了後のDB削除までしてくれる、素晴らしいライブラリです。
開発環境とテスト環境のDBを分離できます。
Psycopg 3
pytest-postgresqlが依存しているので必要です。
psycopgとは共存可能なので、一緒に入れています。
Psycopg 3でSQLModelが動くか(=Psycopg 3のインストールだけで良いか)は未検証です。
プロジェクト設定
pytestのコマンド省略や、カバレッジにテストファイルを含めないために、pyproject.toml
に下記の設定を追加しました。
[tool.pytest.ini_options]
pythonpath = ["."]
testpaths = ["app/tests"]
addopts = "--cov=app --cov-report=term --cov-report=html"
[tool.coverage.run]
source = ["app"]
omit = [
"tests/*",
"*/*_test.py",
"*/test_*.py",
]
テストはapp/tests
配下を実行し、結果を標準出力とHTMLで出すようにしています。
カバレッジはソースファイルのディレクトリをapp
として指定し、tests
などのテスト関連を除外指定しています。
オプションやパスは適宜ご自身の環境に合わせて修正してください。
おわりに
ここまでで、FastAPI を用いた開発環境と初期セットアップについて紹介しました。
次回は、AlembicによるDBマイグレーションについて解説していきます。
ぜひ次回も合わせてお読みください!
参考資料
- uv, ruff, devcontainer, Claude Codeを使ったモダンなPython開発環境のテンプレート
- pytest-covでテストファイルがカバレッジ追跡対象にされないようomitを追加
- FastAPIアプリケーション〜環境設定からログイン処理まで〜
- Ruffのリント警告を特定のコードブロックで無視する方法