1.安裝開發環境
系統需求
- Python 3.12+ (建議3.12或3.13)
- 紫外線 或 詩歌 用於依賴管理
- VS程式碼 或 皮查姆 帶有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
三、項目結構
建立標準目錄結構:
# 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
運行伺服器後,訪問:
- 招搖的使用者介面:
http://localhost:8000/docs- 互動式API文檔 - 重新文檔:
http://localhost:8000/redoc- 替代文檔 - 開放API 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 Code 設定
安裝必要的擴充功能:
// .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
- 配置 VS Code 以進行 Python 開發
下一篇文章將深入探討 FastAPI 中的路徑操作、請求和回應處理。