1184 字
6 分鐘
比較多個主流 OpenAPI SDK Generator
2026-01-17
Ying Xiang Zhao
Ying Xiang Zhao

前言#

FastAPI 開發大量微服務,時常需要手(A)動(I)撰寫 SDK 給其他服務使用 平時公司內部 SDK 主要需求是 Python and TypeScript,

  • Python 硬需求有: >=3.10、Pydantic>=2、httpx,支援 Sync and Async,uv python manager
  • TypeScript: zod

聽聞 OpenAPITools/openapi-generator 很久,所以就上手測試了一下

受測者1: OpenAPI-Generator 上手測試#

Terminal window
# 取得 FastAPI 的 openapi.json,請事先啟動 server
curl -O http://localhost:8000/openapi.json
# openapi generator 需要 JAVA runtime,直接上 docker
# 預設沒 async
docker run --rm \
-v "${PWD}:/local" \
openapitools/openapi-generator-cli generate \
-i /local/openapi.json \
-g python \
-o /local/client-python-default \
--additional-properties=packageName=director_credit
# 支援 async 版本 (aiohttp)
docker run --rm \
-v "${PWD}:/local" \
openapitools/openapi-generator-cli generate \
-i /local/openapi.json \
-g python \
-o /local/client-python-asyncio \
--additional-properties=packageName=director_credit,library=asyncio
# async - httpx
docker run --rm \
-v "${PWD}:/local" \
openapitools/openapi-generator-cli generate \
-i /local/openapi.json \
-g python \
-o /local/client-python-httpx \
--additional-properties=packageName=director_credit,library=httpx
# 其餘設定看這邊 https://openapi-generator.tech/docs/generators/python

產出成果 - httpx#

預設有 pydantic, docs and unittest,不錯 小可惜殘留了一點 poetry 2,但 pyproject.toml 遵循 PEP 621,所以也是可以直接用 uv 讀取並建立虛擬環境,這點影響不大

Terminal window
tree ./client-python-httpx -I "__pycache__"
./client-python-httpx
├── README.md
├── director_credit
├── __init__.py
├── api
├── __init__.py
└── credit_api.py
├── api_client.py
├── api_response.py
├── configuration.py
├── exceptions.py
├── models
├── __init__.py
├── balance_response.py
├── deduct_request.py
├── expires_at.py
├── gift_credit_request.py
├── gift_credit_response.py
├── gift_type.py
├── http_validation_error.py
├── location_inner.py
├── refund_request.py
├── subscription_request.py
├── topup_request.py
├── transaction_response.py
├── transaction_type.py
└── validation_error.py
├── py.typed
└── rest.py
├── docs
├── BalanceResponse.md
├── CreditApi.md
├── DeductRequest.md
├── ExpiresAt.md
├── GiftCreditRequest.md
├── GiftCreditResponse.md
├── GiftType.md
├── HTTPValidationError.md
├── LocationInner.md
├── RefundRequest.md
├── SubscriptionRequest.md
├── TopupRequest.md
├── TransactionResponse.md
├── TransactionType.md
└── ValidationError.md
├── git_push.sh
├── pyproject.toml
├── requirements.txt
├── setup.cfg
├── setup.py
├── test
├── __init__.py
├── test_balance_response.py
├── test_credit_api.py
├── test_deduct_request.py
├── test_expires_at.py
├── test_gift_credit_request.py
├── test_gift_credit_response.py
├── test_gift_type.py
├── test_http_validation_error.py
├── test_location_inner.py
├── test_refund_request.py
├── test_subscription_request.py
├── test_topup_request.py
├── test_transaction_response.py
├── test_transaction_type.py
└── test_validation_error.py
├── test-requirements.txt
├── tox.ini
└── uv.lock
6 directories, 64 files

受測者2: Stainless#

Stainless and Speakeasy 算是第一梯隊,Fern 第二梯隊(不過他的 cli 體驗真的不賴) 這邊就只整理 Stainless 上來,因為他的比較能夠呈現商業化 SDK generator 目前的頂點,OpenAI 是使用他們家的

安裝跟處理方式照官網文件,生成很省心,直接 sync + async 都給了

Code quality 非常接近手寫的溫度,沒有模版冷冰冰的感覺,然後多了許多邊緣情境的處理 (Streaming, Retry and Pagination),難怪 OpenAI 使用

直接比較生成結果#

Stainless#

介面非常 Pythonic DX,攤平所有應傳的參數,這對使用 SDK 的用戶來說,非常舒服 Stainless 對 IDE 友善,request > transform

async def deduct(
self,
*,
amount: int,
user_id: str,
idempotency_key: str,
service_name: str | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> TransactionResponse:

OpenAPI Generator (httpx)#

非常 Pydantic,這點變得要使用者要先處理好 Pydantic Object instance,會顯得更加繁瑣

@validate_call
async def deduct(
self,
idempotency_key: StrictStr,
deduct_request: DeductRequest,
_request_timeout: Union[
None,
Annotated[StrictFloat, Field(gt=0)],
Tuple[
Annotated[StrictFloat, Field(gt=0)],
Annotated[StrictFloat, Field(gt=0)]
]
] = None,
_request_auth: Optional[Dict[StrictStr, Any]] = None,
_content_type: Optional[StrictStr] = None,
_headers: Optional[Dict[StrictStr, Any]] = None,
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
) -> TransactionResponse:

接下來是 LLM 查看我測試的幾個解決方案的一些分析(僅供參考)#

特性OpenAPI Generator (HTTPX)Stainless觀點
模型純度高 (標準 Pydantic)中 (含大量 Helper 邏輯)如果您需要將 Model 拿去其他地方用,OpenAPI Gen 的 Model 比較乾淨。
呼叫彈性顯式 (with_http_info)隱式 (.with_raw_response)風格偏好不同,OpenAPI Gen 的方式比較傳統但明確。
依賴性低 (僅 httpx, pydantic)高 (依賴 stainless core)OpenAPI Gen 產出的碼大部分是自己包含的,不依賴像 stainless-python 這樣的外部 Runtime 套件 (除了 httpx/pydantic)。

🏆 現代 Python SDK 生成器終極比較

維度Stainless 👑Speakeasy 🥈Fern 🥉OpenAPI (HTTPX)Liblab
核心技術httpxhttpxhttpxhttpxrequests
Async 支援✅ 原生 (True Async)✅ 原生 (True Async)✅ 原生 (True Async)✅ 原生 (True Async)❌ 模擬 (Thread)
Idempotency⭐ 自動注入 (UUID)⭐ 需寫 Hook⭐ 手動傳參❌ 手動傳參⭐ 需寫 Hook
Retry 機制⭐ 極致 (Header感知)⭐ 需 Config⭐ 極致 (Header感知)❌ 無內建⭐ 基本 (Chain)
資安 (Auth)⭐⭐⭐⭐⭐ (直觀)⭐⭐⭐⭐⭐ (強型別)⭐⭐⭐⭐⭐ (直觀)⭐⭐⭐ (Setter)⭐⭐⭐ (Setter)
程式碼風格極簡、教科書級標準、Pydantic極簡、Pythonic略顯繁瑣複雜 (責任鏈)
開源/商業💰 商業付費💰 商業 (有免費層)💰 商業 (有免費層)🆓 完全開源💰 商業

總結#

我之後應該會做的選擇

  • OpenAPI Generator (HTTPX):適合喜歡 DIY。它是穩健且標準的開源選擇。
  • Stainless / Speakeasy / Fern:適合 SDK 為產品的一部分的團隊。雖然有商業成本,但換來的是更佳的開發者體驗 (DX)。
比較多個主流 OpenAPI SDK Generator
https://geminixiang.xyz/posts/openapi-sdk-generator-comparison/
作者
Ying Xiang Zhao
發佈於
2026-01-17
許可協議
CC BY-NC-SA 4.0