jpskill.com
✍️ ライティング コミュニティ

fastapi

FastAPIは、Pythonの型ヒントとPydanticを活用し、API開発におけるデータ検証、シリアライズ、OpenAPIドキュメント生成を自動化、高速化するモダンなWebフレームワークを構築するSkill。

📜 元の英語説明(参考)

FastAPI is a modern, high-performance Python web framework for building APIs. It leverages Python type hints and Pydantic for automatic validation, serialization, and OpenAPI documentation generation with async/await support out of the box.

🇯🇵 日本人クリエイター向け解説

一言でいうと

FastAPIは、Pythonの型ヒントとPydanticを活用し、API開発におけるデータ検証、シリアライズ、OpenAPIドキュメント生成を自動化、高速化するモダンなWebフレームワークを構築するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o fastapi.zip https://jpskill.com/download/14889.zip && unzip -o fastapi.zip && rm fastapi.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/14889.zip -OutFile "$d\fastapi.zip"; Expand-Archive "$d\fastapi.zip" -DestinationPath $d -Force; ri "$d\fastapi.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して fastapi.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → fastapi フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

FastAPI

FastAPI は、Starlette (ASGI) と Pydantic を基盤とする Python ウェブフレームワークです。自動リクエストバリデーション、シリアライゼーション、およびインタラクティブな API ドキュメントを /docs (Swagger UI) と /redoc で提供します。

インストール

# uvicorn ASGI サーバーとともに FastAPI をインストール
pip install "fastapi[standard]"

プロジェクト構成

# 典型的な FastAPI プロジェクトのレイアウト
app/
├── main.py           # アプリケーションのエントリーポイント
├── config.py         # 設定
├── models/           # SQLAlchemy / DB モデル
├── schemas/          # Pydantic スキーマ
├── routers/          # API ルートモジュール
├── dependencies.py   # 共有依存関係
├── middleware.py     # カスタムミドルウェア
└── tests/

アプリケーションのセットアップ

# main.py — FastAPI アプリケーションのエントリーポイント
from fastapi import FastAPI
from contextlib import asynccontextmanager

@asynccontextmanager
async def lifespan(app: FastAPI):
    # 起動時: DB プール、キャッシュなどを初期化
    yield
    # シャットダウン時: 接続を閉じる

app = FastAPI(
    title="My API",
    version="1.0.0",
    lifespan=lifespan,
)

ルートとパスオペレーション

# routers/items.py — items の CRUD ルーター
from fastapi import APIRouter, HTTPException, status, Query, Path
from pydantic import BaseModel, Field

router = APIRouter(prefix="/items", tags=["items"])

class ItemCreate(BaseModel):
    name: str = Field(..., min_length=1, max_length=100)
    price: float = Field(..., gt=0)
    description: str | None = None

class ItemResponse(ItemCreate):
    id: int

    model_config = {"from_attributes": True}

@router.get("/", response_model=list[ItemResponse])
async def list_items(skip: int = Query(0, ge=0), limit: int = Query(20, le=100)):
    return await db.fetch_items(skip=skip, limit=limit)

@router.post("/", response_model=ItemResponse, status_code=status.HTTP_201_CREATED)
async def create_item(item: ItemCreate):
    return await db.create_item(item)

@router.get("/{item_id}", response_model=ItemResponse)
async def get_item(item_id: int = Path(..., gt=0)):
    item = await db.get_item(item_id)
    if not item:
        raise HTTPException(status_code=404, detail="Item not found")
    return item

依存性注入

# dependencies.py — 再利用可能な依存関係
from fastapi import Depends, Header, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession

async def get_db() -> AsyncSession:
    async with async_session() as session:
        yield session

async def get_current_user(authorization: str = Header(...)):
    token = authorization.removeprefix("Bearer ")
    user = await verify_token(token)
    if not user:
        raise HTTPException(status_code=401, detail="Invalid token")
    return user

# ルートでの使用例
@router.get("/me")
async def read_me(user=Depends(get_current_user), db=Depends(get_db)):
    return user

Pydantic スキーマとバリデーション

# schemas/user.py — バリデーション付きのリクエスト/レスポンススキーマ
from pydantic import BaseModel, EmailStr, field_validator
from datetime import datetime

class UserCreate(BaseModel):
    email: EmailStr
    password: str = Field(..., min_length=8)
    username: str

    @field_validator("username")
    @classmethod
    def username_alphanumeric(cls, v: str) -> str:
        if not v.isalnum():
            raise ValueError("must be alphanumeric")
        return v

class UserResponse(BaseModel):
    id: int
    email: EmailStr
    username: str
    created_at: datetime

    model_config = {"from_attributes": True}

ミドルウェア

# middleware.py — カスタムミドルウェアの例
import time
from fastapi import Request

@app.middleware("http")
async def add_timing_header(request: Request, call_next):
    start = time.perf_counter()
    response = await call_next(request)
    elapsed = time.perf_counter() - start
    response.headers["X-Process-Time"] = f"{elapsed:.4f}"
    return response

バックグラウンドタスク

# routers/notifications.py — バックグラウンドタスクの例
from fastapi import BackgroundTasks

async def send_email(to: str, body: str):
    # 時間のかかるメール送信ロジック
    ...

@router.post("/notify")
async def notify(email: str, bg: BackgroundTasks):
    bg.add_task(send_email, email, "Welcome!")
    return {"status": "queued"}

WebSocket サポート

# routers/ws.py — WebSocket エンドポイント
from fastapi import WebSocket, WebSocketDisconnect

@app.websocket("/ws/{client_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: str):
    await websocket.accept()
    try:
        while True:
            data = await websocket.receive_text()
            await websocket.send_text(f"Echo: {data}")
    except WebSocketDisconnect:
        pass

テスト

# tests/test_items.py — httpx を使用したテスト
from httpx import AsyncClient, ASGITransport
import pytest

@pytest.mark.anyio
async def test_create_item():
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        resp = await client.post("/items/", json={"name": "Widget", "price": 9.99})
        assert resp.status_code == 201
        assert resp.json()["name"] == "Widget"

実行

# 自動リロード付きの開発サーバーを実行
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

主要なパターン

  • response_model を使用して出力のシリアライゼーションを制御し、内部フィールドを取り除く
  • APIRouter でルートをグループ化し、app.include_router(router) を介してメインアプリに含める
  • DB セッション、認証、ページネーションには Depends() を使用する — これらはリクエストごとに構成およびキャッシュされる
  • エラーレスポンスには HTTPException を発生させる。グローバルパターンにはカスタム例外ハンドラーを使用する
  • 非推奨のイベントの代わりに、起動/シャットダウンには lifespan コンテキストマネージャーを使用する
  • ORM オブジェクトから読み取るには、Pydantic の設定で from_attributes = True を設定する
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

FastAPI

FastAPI is a Python web framework built on Starlette (ASGI) and Pydantic. It provides automatic request validation, serialization, and interactive API docs at /docs (Swagger UI) and /redoc.

Installation

# Install FastAPI with uvicorn ASGI server
pip install "fastapi[standard]"

Project Structure

# Typical FastAPI project layout
app/
├── main.py           # Application entry point
├── config.py         # Settings and configuration
├── models/           # SQLAlchemy / DB models
├── schemas/          # Pydantic schemas
├── routers/          # API route modules
├── dependencies.py   # Shared dependencies
├── middleware.py     # Custom middleware
└── tests/

Application Setup

# main.py — FastAPI application entry point
from fastapi import FastAPI
from contextlib import asynccontextmanager

@asynccontextmanager
async def lifespan(app: FastAPI):
    # Startup: initialize DB pool, caches, etc.
    yield
    # Shutdown: close connections

app = FastAPI(
    title="My API",
    version="1.0.0",
    lifespan=lifespan,
)

Routes and Path Operations

# routers/items.py — CRUD router for items
from fastapi import APIRouter, HTTPException, status, Query, Path
from pydantic import BaseModel, Field

router = APIRouter(prefix="/items", tags=["items"])

class ItemCreate(BaseModel):
    name: str = Field(..., min_length=1, max_length=100)
    price: float = Field(..., gt=0)
    description: str | None = None

class ItemResponse(ItemCreate):
    id: int

    model_config = {"from_attributes": True}

@router.get("/", response_model=list[ItemResponse])
async def list_items(skip: int = Query(0, ge=0), limit: int = Query(20, le=100)):
    return await db.fetch_items(skip=skip, limit=limit)

@router.post("/", response_model=ItemResponse, status_code=status.HTTP_201_CREATED)
async def create_item(item: ItemCreate):
    return await db.create_item(item)

@router.get("/{item_id}", response_model=ItemResponse)
async def get_item(item_id: int = Path(..., gt=0)):
    item = await db.get_item(item_id)
    if not item:
        raise HTTPException(status_code=404, detail="Item not found")
    return item

Dependency Injection

# dependencies.py — reusable dependencies
from fastapi import Depends, Header, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession

async def get_db() -> AsyncSession:
    async with async_session() as session:
        yield session

async def get_current_user(authorization: str = Header(...)):
    token = authorization.removeprefix("Bearer ")
    user = await verify_token(token)
    if not user:
        raise HTTPException(status_code=401, detail="Invalid token")
    return user

# Use in routes
@router.get("/me")
async def read_me(user=Depends(get_current_user), db=Depends(get_db)):
    return user

Pydantic Schemas and Validation

# schemas/user.py — request/response schemas with validation
from pydantic import BaseModel, EmailStr, field_validator
from datetime import datetime

class UserCreate(BaseModel):
    email: EmailStr
    password: str = Field(..., min_length=8)
    username: str

    @field_validator("username")
    @classmethod
    def username_alphanumeric(cls, v: str) -> str:
        if not v.isalnum():
            raise ValueError("must be alphanumeric")
        return v

class UserResponse(BaseModel):
    id: int
    email: EmailStr
    username: str
    created_at: datetime

    model_config = {"from_attributes": True}

Middleware

# middleware.py — custom middleware example
import time
from fastapi import Request

@app.middleware("http")
async def add_timing_header(request: Request, call_next):
    start = time.perf_counter()
    response = await call_next(request)
    elapsed = time.perf_counter() - start
    response.headers["X-Process-Time"] = f"{elapsed:.4f}"
    return response

Background Tasks

# routers/notifications.py — background task example
from fastapi import BackgroundTasks

async def send_email(to: str, body: str):
    # Long-running email sending logic
    ...

@router.post("/notify")
async def notify(email: str, bg: BackgroundTasks):
    bg.add_task(send_email, email, "Welcome!")
    return {"status": "queued"}

WebSocket Support

# routers/ws.py — WebSocket endpoint
from fastapi import WebSocket, WebSocketDisconnect

@app.websocket("/ws/{client_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: str):
    await websocket.accept()
    try:
        while True:
            data = await websocket.receive_text()
            await websocket.send_text(f"Echo: {data}")
    except WebSocketDisconnect:
        pass

Testing

# tests/test_items.py — testing with httpx
from httpx import AsyncClient, ASGITransport
import pytest

@pytest.mark.anyio
async def test_create_item():
    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        resp = await client.post("/items/", json={"name": "Widget", "price": 9.99})
        assert resp.status_code == 201
        assert resp.json()["name"] == "Widget"

Running

# Run development server with auto-reload
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

Key Patterns

  • Use response_model to control output serialization and strip internal fields
  • Group routes with APIRouter and include in main app via app.include_router(router)
  • Use Depends() for DB sessions, auth, pagination — they compose and cache per-request
  • Raise HTTPException for error responses; use custom exception handlers for global patterns
  • Use lifespan context manager for startup/shutdown instead of deprecated events
  • Set from_attributes = True in Pydantic config to read from ORM objects