Chuyển đến nội dung chính

レッスン 3: FastAPI プロジェクトのインストールと初期化

FastAPI と Uvicorn をインストールし、プロジェクト構造を初期化し、標準のディレクトリ構造を理解します。開発サーバー、Swagger UI、ReDoc を実行し、最初の API エンドポイントを作成します。

💻 プログラミング — レッスン 3 レッスン 3: FastAPI プロジェクトのインストールと初期化

Python FastAPI: 基本から高度まで

パート 1: Python の基礎と FastAPI

xdev.asia

1. 開発環境をインストールする

システム要件

  • Python 3.12+ (3.12 または 3.13 を推奨)
  • 紫外線 または 詩 依存関係管理用
  • VSコード または PyCharm Python 拡張機能を使用する
  • Git バージョン管理用

Python 3.12以降をインストールする

# macOS (Homebrew)
brew install [email protected]

# Ubuntu/Debian
sudo apt update
sudo apt install python3.12 python3.12-venv python3.12-dev

# Windows - tải từ https://python.org

# Kiểm tra version
python3 --version
# Python 3.12.x

UV設定(推奨)

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

# Kiểm tra
uv --version

2. FastAPI プロジェクトの初期化

# Tạo project mới
uv init fastapi-tutorial
cd fastapi-tutorial

# Thêm FastAPI và Uvicorn
uv add fastapi "uvicorn[standard]"

# Thêm dev dependencies
uv add --dev ruff mypy pytest httpx

# Xem project structure
tree .

ファイル pyproject.toml 初期化後:

[project]
name = "fastapi-tutorial"
version = "0.1.0"
description = "FastAPI Tutorial - From Basic to Advanced"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
    "fastapi>=0.115.0",
    "uvicorn[standard]>=0.32.0",
]

[dependency-groups]
dev = [
    "httpx>=0.28.0",
    "mypy>=1.13.0",
    "pytest>=8.3.0",
    "ruff>=0.8.0",
]

[tool.ruff]
target-version = "py312"
line-length = 120

[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "UP", "B", "A", "SIM", "TCH"]

[tool.mypy]
python_version = "3.12"
strict = true

3. プロジェクトの構造

標準のディレクトリ構造を作成します。

# Tạo cấu trúc thư mục
mkdir -p app/{api/v1,models,schemas,services,core}
touch app/__init__.py app/main.py app/config.py
touch app/api/__init__.py app/api/v1/__init__.py
touch app/models/__init__.py app/schemas/__init__.py
touch app/services/__init__.py app/core/__init__.py
fastapi-tutorial/
├── pyproject.toml
├── uv.lock
├── .env
├── .gitignore
├── app/
│   ├── __init__.py
│   ├── main.py              # Entry point
│   ├── config.py            # Configuration
│   ├── api/
│   │   ├── __init__.py
│   │   └── v1/
│   │       ├── __init__.py
│   │       └── items.py     # Item routes
│   ├── models/
│   │   └── __init__.py
│   ├── schemas/
│   │   ├── __init__.py
│   │   └── item.py          # Pydantic schemas
│   ├── services/
│   │   └── __init__.py
│   └── core/
│       └── __init__.py
└── tests/
    └── __init__.py

4. 最初の FastAPI アプリケーションを作成する

app/config.py - 構成

from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    app_name: str = "FastAPI Tutorial"
    app_version: str = "0.1.0"
    debug: bool = True

    model_config = {"env_file": ".env", "env_file_encoding": "utf-8"}


settings = Settings()

app/schemas/item.py - Pydantic スキーマ

from pydantic import BaseModel, Field


class ItemBase(BaseModel):
    name: str = Field(..., min_length=1, max_length=100, examples=["Laptop"])
    description: str | None = Field(None, max_length=500, examples=["A powerful laptop"])
    price: float = Field(..., gt=0, examples=[999.99])
    is_available: bool = Field(True)


class ItemCreate(ItemBase):
    pass


class ItemUpdate(BaseModel):
    name: str | None = Field(None, min_length=1, max_length=100)
    description: str | None = Field(None, max_length=500)
    price: float | None = Field(None, gt=0)
    is_available: bool | None = None


class ItemResponse(ItemBase):
    id: int

    model_config = {"from_attributes": True}

app/api/v1/items.py - ルート ハンドラー

from fastapi import APIRouter, HTTPException, status

from app.schemas.item import ItemCreate, ItemResponse, ItemUpdate

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

# In-memory storage (sẽ thay bằng database sau)
fake_db: dict[int, dict] = {}
counter = 0


@router.get("/", response_model=list[ItemResponse])
async def list_items(skip: int = 0, limit: int = 10):
    """Lấy danh sách items với pagination."""
    items = list(fake_db.values())
    return items[skip : skip + limit]


@router.get("/{item_id}", response_model=ItemResponse)
async def get_item(item_id: int):
    """Lấy thông tin item theo ID."""
    if item_id not in fake_db:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Item with id {item_id} not found",
        )
    return fake_db[item_id]


@router.post("/", response_model=ItemResponse, status_code=status.HTTP_201_CREATED)
async def create_item(item: ItemCreate):
    """Tạo item mới."""
    global counter
    counter += 1
    item_data = {"id": counter, **item.model_dump()}
    fake_db[counter] = item_data
    return item_data


@router.put("/{item_id}", response_model=ItemResponse)
async def update_item(item_id: int, item: ItemUpdate):
    """Cập nhật item theo ID."""
    if item_id not in fake_db:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Item with id {item_id} not found",
        )
    stored_item = fake_db[item_id]
    update_data = item.model_dump(exclude_unset=True)
    stored_item.update(update_data)
    fake_db[item_id] = stored_item
    return stored_item


@router.delete("/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_item(item_id: int):
    """Xóa item theo ID."""
    if item_id not in fake_db:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Item with id {item_id} not found",
        )
    del fake_db[item_id]

app/main.py - エントリ ポイント

from fastapi import FastAPI

from app.api.v1.items import router as items_router
from app.config import settings

app = FastAPI(
    title=settings.app_name,
    version=settings.app_version,
    description="FastAPI Tutorial - Learning from basic to advanced",
    docs_url="/docs",       # Swagger UI
    redoc_url="/redoc",     # ReDoc
    openapi_url="/openapi.json",
)

# Include routers
app.include_router(items_router, prefix="/api/v1")


@app.get("/")
async def root():
    return {
        "app": settings.app_name,
        "version": settings.app_version,
        "docs": "/docs",
    }


@app.get("/health")
async def health_check():
    return {"status": "healthy"}

5. 開発サーバーを実行する

# Chạy với uv
uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

# Hoặc chạy trực tiếp
uvicorn app.main:app --reload

# Output:
# INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
# INFO:     Started reloader process [12345] using WatchFiles
# INFO:     Started server process [12346]
# INFO:     Waiting for application startup.
# INFO:     Application startup complete.

Uvicorn オプションが重要

# Development
uvicorn app.main:app \
    --reload \              # Auto-reload khi code thay đổi
    --host 0.0.0.0 \       # Listen all interfaces
    --port 8000 \           # Port
    --log-level debug       # Log level

# Production (preview)
uvicorn app.main:app \
    --workers 4 \           # Số worker processes
    --host 0.0.0.0 \
    --port 8000 \
    --no-access-log         # Tắt access log cho performance

6. Swagger UI と ReDoc を探索する

サーバーを実行した後、以下にアクセスします。

  • Swagger UI: http://localhost:8000/docs - インタラクティブ API ドキュメント
  • 再ドキュメント: http://localhost:8000/redoc - 代替ドキュメント
  • OpenAPI JSON: http://localhost:8000/openapi.json - 生の OpenAPI 仕様

Swagger UI では次のことが可能になります。

  • HTTP メソッドを使用したすべての API エンドポイントを表示する
  • リクエスト/レスポンスのスキーマを参照
  • 「試してみて」 - ブラウザから直接APIを呼び出す
  • 値の例と検証ルールを参照してください。

7.curl を使用して API をテストする

# Health check
curl http://localhost:8000/health

# Tạo item
curl -X POST http://localhost:8000/api/v1/items/ \
  -H "Content-Type: application/json" \
  -d '{"name": "Laptop", "description": "Gaming laptop", "price": 1299.99}'

# Lấy danh sách items
curl http://localhost:8000/api/v1/items/

# Lấy item theo ID
curl http://localhost:8000/api/v1/items/1

# Cập nhật item
curl -X PUT http://localhost:8000/api/v1/items/1 \
  -H "Content-Type: application/json" \
  -d '{"price": 999.99}'

# Xóa item
curl -X DELETE http://localhost:8000/api/v1/items/1

8. FastAPI 用の VS コードのセットアップ

必要な拡張機能をインストールします。

// .vscode/extensions.json
{
  "recommendations": [
    "ms-python.python",
    "ms-python.vscode-pylance",
    "charliermarsh.ruff",
    "ms-python.mypy-type-checker"
  ]
}
// .vscode/settings.json
{
  "python.defaultInterpreterPath": ".venv/bin/python",
  "[python]": {
    "editor.defaultFormatter": "charliermarsh.ruff",
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
      "source.organizeImports": "explicit"
    }
  }
}

概要

この記事では、次の内容を説明します。

  • Python、uv、FastAPI をインストールする
  • 標準のディレクトリ構造でプロジェクトを初期化する
  • Pydantic スキーマを使用して最初の CRUD API アプリケーションを作成する
  • 開発サーバーを実行して Swagger UI を探索する
  • Python 開発用に VS Code を構成する

次の記事では、FastAPI でのパス操作、リクエストとレスポンスの処理について詳しく説明します。