FastAPI – 應用結構與啟動方式(Application Setup)
主題:uvicorn main:app --reload 啟動伺服器
簡介
在使用 FastAPI 開發 Web API 時,最常見的第一步就是把應用程式跑起來,讓客戶端可以透過 HTTP 請求與之互動。雖然 FastAPI 本身只是一個框架,但它依賴 ASGI(Asynchronous Server Gateway Interface)伺服器來處理實際的網路 I/O,而最受歡迎的選擇就是 Uvicorn。
使用 uvicorn main:app --reload 這條指令,我們可以在開發階段快速啟動伺服器、即時載入程式碼變更,並且得到詳細的錯誤訊息與自動重載功能。對於 初學者 來說,掌握這個指令不僅能縮短測試迴圈,更能體驗到 FastAPI 的高效能與開發友好度;對 中級開發者 則是日常開發與除錯的必備工具。
核心概念
1. 為什麼選擇 Uvicorn?
- 輕量且高效:使用
uvloop(libuv 的 Python 包裝)與httptools,在非同步 I/O 上表現優異。 - 原生支援 ASGI:FastAPI 產生的
app物件即是符合 ASGI 規範的 callable,Uvicorn 直接接收即可。 - 開發模式自動重載:
--reload參數會監控檔案變化,檔案變動時自動重新啟動伺服器,省去手動重啟的麻煩。
2. uvicorn main:app --reload 的語法拆解
| 參數 | 說明 |
|---|---|
uvicorn |
執行 Uvicorn 伺服器的指令入口。 |
main:app |
module:application 的寫法,main 為 Python 檔名(不含 .py),app 為在該模組中建立的 FastAPI 物件。 |
--reload |
開啟開發模式的自動重載功能。只建議在開發環境使用,正式部署時請改用 --workers 或其他監控工具。 |
3. 建立最小 FastAPI 應用
以下示範最簡單的 main.py,只需要三行程式碼即可跑起來:
# main.py
from fastapi import FastAPI
app = FastAPI() # 建立 FastAPI 實例
@app.get("/") # 設定根路徑的 GET 請求
async def read_root():
return {"message": "Hello, FastAPI!"}
說明:
FastAPI()建立的app會被 Uvicorn 當作 ASGI 應用載入。- 使用
@app.get("/")裝飾器定義路由,回傳的字典會自動轉成 JSON。
4. 常見的啟動方式變形
4.1 指定主機與埠口
uvicorn main:app --host 0.0.0.0 --port 8080 --reload
--host 0.0.0.0讓容器或遠端主機也能存取。--port 8080自訂埠號,避免與其他服務衝突。
4.2 使用環境變數管理設定
# config.py
import os
HOST = os.getenv("HOST", "127.0.0.1")
PORT = int(os.getenv("PORT", 8000))
HOST=0.0.0.0 PORT=5000 uvicorn main:app --reload
這樣可以在 CI/CD、Docker 或 Kubernetes 中靈活調整。
4.3 多工作者 (workers) 於正式環境
uvicorn main:app --workers 4 --host 0.0.0.0 --port 8000
--workers會啟動多個子進程,提升併發處理能力。- 注意:
--reload與--workers不能同時使用。
5. 程式碼範例(實務應用)
範例 1:加入 CORS 中介軟體
# main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# 允許所有來源的 CORS 請求(開發階段常用)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # <--- 這裡可改為具體的 domain 列表
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
範例 2:使用環境變數動態載入設定檔
# main.py
import os
from fastapi import FastAPI
from pydantic import BaseSettings
class Settings(BaseSettings):
debug: bool = False
title: str = "My FastAPI App"
version: str = "0.1.0"
class Config:
env_file = ".env"
settings = Settings()
app = FastAPI(
debug=settings.debug,
title=settings.title,
version=settings.version,
)
@app.get("/info")
async def get_info():
return {"title": app.title, "version": app.version}
.env 範例:
DEBUG=True
TITLE=Demo API
VERSION=1.0.0
範例 3:結合 Logging 與 Uvicorn
# main.py
import logging
from fastapi import FastAPI
# 設定基本的 logging 格式
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
)
logger = logging.getLogger(__name__)
app = FastAPI()
@app.on_event("startup")
async def startup_event():
logger.info("FastAPI 應用啟動")
@app.get("/ping")
async def ping():
logger.info("收到 ping 請求")
return {"msg": "pong"}
執行時:
uvicorn main:app --reload
在終端機即可看到自訂的 log 訊息,協助除錯與監控。
常見陷阱與最佳實踐
| 陷阱 | 說明 | 解決方案 / Best Practice |
|---|---|---|
忘記加 --reload |
開發時每次修改程式碼都必須手動重啟,浪費時間。 | 開發環境一定加上 --reload;正式環境則移除。 |
使用 --reload 時加 --workers |
兩者互斥,會導致啟動失敗或行為不一致。 | 正式部署使用 --workers,開發只使用 --reload。 |
| 硬編碼 IP/Port | 部署在 Docker、K8s 時無法彈性調整。 | 使用環境變數或 config.py 讀取設定。 |
| CORS 設定過於寬鬆 | 生產環境若仍保留 allow_origins=["*"],會有安全風險。 |
只允許信任的前端域名,或在 .env 中管理。 |
| 未設定 Logging 等級 | 預設的 Uvicorn log 可能不包含自訂訊息。 | 透過 logging.basicConfig 或 uvicorn.run(..., log_level="info") 來統一管理。 |
最佳實踐:
- 分離開發與正式設定:使用
--reload、--workers、環境變數等方式,讓同一套程式碼在不同環境下自動切換。 - 將
app放在獨立模組:例如app/__init__.py中建立app = FastAPI(),main.py僅負責啟動,方便測試與重構。 - 加入健康檢查端點:
/health或/ready,配合容器平台的 liveness / readiness probe。 - 使用
python -m uvicorn:在虛擬環境或 Dockerfile 中,CMD ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]更具可移植性。
實際應用場景
| 場景 | 需求 | 使用 uvicorn main:app --reload 的好處 |
|---|---|---|
| 本機開發 | 快速驗證 API 設計、即時測試前端呼叫 | 自動重載讓開發者不需手動重啟,提升開發效率。 |
| Docker 本地測試 | 在容器內跑 FastAPI,確認依賴與環境 | --reload 能偵測容器內掛載的程式碼變更,配合 -v .:/app 完成即時迭代。 |
| CI/CD 單元測試 | 需要在測試腳本中啟動伺服器,執行 API 呼叫 | 使用 uvicorn 作為測試伺服器,搭配 pytest 的 fixtures,簡化測試流程。 |
| 簡易原型展示 | 把 API 交給產品或設計師快速試玩 | 只要一條指令即可啟動,降低門檻,快速收集回饋。 |
小技巧:在
docker-compose.yml中加入command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload,即可在本機開發時即時看到容器內的變更。
總結
uvicorn main:app --reload 是 FastAPI 開發者最常使用的啟動指令,它結合了 ASGI 高效能伺服器 與 開發友好自動重載,讓我們可以在本機或容器環境中快速驗證 API 設計。透過正確的參數配置(--host、--port、--workers)與環境變數管理,我們能在開發、測試、部署三個階段保持一致的程式碼基礎,同時避免常見的安全與效能陷阱。
掌握這個指令的使用方式與背後概念,將為日後使用 FastAPI 建構高效、可擴充的服務奠定堅實基礎。祝開發順利,API 快速上線!