0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🛠️FastAPI × SQLModelで作るTodoアプリ①:開発環境とプロジェクトのセットアップ

Last updated at Posted at 2025-07-12

はじめに

どうも、水無月せきなです。

PythonのWebフレームワークである FastAPI の学習として、ローカルで動作する Todo アプリ(API)を作ってみました。
本シリーズでは、アプリの開発過程で得た知見や工夫点などを数回に分けて紹介していきます。

初回となる今回は、以下の内容を取り上げます。

  • 使用した技術スタック
  • 開発環境(devcontainerなど)
  • 使用ライブラリのインストール

シリーズ一覧

リポジトリ

技術スタック

  • 言語: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
.devcontainer/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
.devcontainer/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
.devcontainer/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
.devcontainer/.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マイグレーションについて解説していきます。

ぜひ次回も合わせてお読みください!

参考資料

  1. 一応、SQLModelでマイグレーションもできそうなことをユーザーガイドで匂わせていますが、肝心の内容について記載を見つけられませんでした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?