今天我們要建立一個完整的 FastAPI 應用程式,作為後續 Locust 測試的目標。這個應用將包含典型的電商使用者行為:註冊、登入、瀏覽商品、購買等功能。
day14/
├── README.md
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI 應用主程式
│ ├── models.py # 資料模型
│ ├── database.py # 資料庫設定
│ └── auth.py # 認證相關函數
├── requirements.txt # 依賴套件
└── test_data.py # 測試資料初始化
我們的 FastAPI 應用需要包含以下功能:
使用者管理
商品管理
購物功能
# requirements.txt
fastapi==0.104.1
uvicorn==0.24.0
sqlalchemy==2.0.23
python-jose[cryptography]==3.3.0
python-multipart==0.0.6
bcrypt==4.0.1
# app/models.py
from sqlalchemy import Column, Integer, String, Float, Boolean, DateTime, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from datetime import datetime
Base = declarative_base()
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
username = Column(String, unique=True, index=True)
email = Column(String, unique=True, index=True)
hashed_password = Column(String)
is_active = Column(Boolean, default=True)
created_at = Column(DateTime, default=datetime.utcnow)
class Product(Base):
__tablename__ = "products"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
description = Column(String)
price = Column(Float)
stock = Column(Integer, default=0)
is_available = Column(Boolean, default=True)
class CartItem(Base):
__tablename__ = "cart_items"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"))
product_id = Column(Integer, ForeignKey("products.id"))
quantity = Column(Integer, default=1)
user = relationship("User")
product = relationship("Product")
class Order(Base):
__tablename__ = "orders"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"))
total_amount = Column(Float)
status = Column(String, default="pending")
created_at = Column(DateTime, default=datetime.utcnow)
user = relationship("User")
# app/main.py
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import HTTPBearer
from sqlalchemy.orm import Session
from typing import List
import uvicorn
app = FastAPI(title="Shop API", version="1.0.0")
@app.get("/")
def root():
return {"message": "Welcome to Shop API"}
@app.post("/register")
def register(user_data: dict, db: Session = Depends(get_db)):
# 註冊邏輯
return {"message": "User registered successfully"}
@app.post("/login")
def login(credentials: dict, db: Session = Depends(get_db)):
# 登入邏輯
return {"access_token": "fake_token", "token_type": "bearer"}
@app.get("/products")
def get_products(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
# 回傳商品列表
return [
{"id": 1, "name": "iPhone 15", "price": 35900, "stock": 50},
{"id": 2, "name": "MacBook Pro", "price": 65900, "stock": 20},
{"id": 3, "name": "AirPods", "price": 5490, "stock": 100},
{"id": 4, "name": "iPad", "price": 15900, "stock": 30}
]
@app.get("/products/{product_id}")
def get_product(product_id: int, db: Session = Depends(get_db)):
# 回傳特定商品
products = {
1: {"id": 1, "name": "iPhone 15", "description": "最新款 iPhone", "price": 35900, "stock": 50},
2: {"id": 2, "name": "MacBook Pro", "description": "M3 晶片筆電", "price": 65900, "stock": 20},
3: {"id": 3, "name": "AirPods", "description": "無線耳機", "price": 5490, "stock": 100},
4: {"id": 4, "name": "iPad", "description": "平板電腦", "price": 15900, "stock": 30}
}
if product_id not in products:
raise HTTPException(status_code=404, detail="Product not found")
return products[product_id]
@app.post("/cart/items")
def add_to_cart(item: dict, db: Session = Depends(get_db)):
# 添加商品到購物車
return {"message": "Item added to cart"}
@app.get("/cart")
def get_cart(db: Session = Depends(get_db)):
# 查看購物車
return {
"items": [
{"product_name": "iPhone 15", "price": 35900, "quantity": 1, "subtotal": 35900}
],
"total_amount": 35900
}
@app.post("/checkout")
def checkout(db: Session = Depends(get_db)):
# 結帳
return {
"message": "Order completed successfully",
"order_id": 12345,
"total_amount": 35900
}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
# 1. 安裝依賴
pip install fastapi uvicorn
# 2. 啟動應用
uvicorn app.main:app --reload
# 3. 查看 API 文檔
# 瀏覽器開啟 http://localhost:8000/docs
# 註冊使用者
curl -X POST "http://localhost:8000/register" \
-H "Content-Type: application/json" \
-d '{"username":"testuser","email":"test@example.com","password":"password123"}'
# 登入
curl -X POST "http://localhost:8000/login" \
-H "Content-Type: application/json" \
-d '{"username":"testuser","password":"password123"}'
# 查看商品
curl -X GET "http://localhost:8000/products"
# 添加到購物車
curl -X POST "http://localhost:8000/cart/items" \
-H "Content-Type: application/json" \
-d '{"product_id":1,"quantity":2}'
# 結帳
curl -X POST "http://localhost:8000/checkout"
今天我們建立了一個簡化版的 FastAPI 電商應用,包含:
這個應用將作為明天 Day15 Locust 測試的目標,我們將模擬多個使用者同時進行各種操作,測試系統的效能表現。