本文 AI 產出,尚未審核

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.basicConfiguvicorn.run(..., log_level="info") 來統一管理。

最佳實踐

  1. 分離開發與正式設定:使用 --reload--workers、環境變數等方式,讓同一套程式碼在不同環境下自動切換。
  2. app 放在獨立模組:例如 app/__init__.py 中建立 app = FastAPI()main.py 僅負責啟動,方便測試與重構。
  3. 加入健康檢查端點/health/ready,配合容器平台的 liveness / readiness probe。
  4. 使用 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 快速上線!