کتابخانه fastapi-utils در پایتون
fastapi-utils یک بسته جانبی سبک برای فریمورک FastAPI است که چندین ابزار عملی و الگوهای متداول توسعه وب را بهصورت آماده فراهم میکند. این کتابخانه مخصوصاً برای توسعهدهندگانی مفید است که میخواهند کدهای مرتبتر، خواناتر و قابل نگهداریتری بنویسند — بهویژه زمانی که پروژه بزرگ و پیچیده میشود.
چرا از fastapi-utils استفاده کنیم؟
- سادهسازی الگوهای رایج مانند class-based views (CBV).
- ابزارهای کوچک کمکی که تکرار کد را کاهش میدهند.
- ادغام آسان با سیستم dependency که FastAPI ارائه میکند.
- مناسب برای پروژههایی که میخواهند ساختار مرتبتری برای مسیرها و کنترلرها داشته باشند.
ویژگیهای کلیدی
- cbv (Class-Based Views): امکان تعریف endpointها به صورت متدهای کلاس و اشتراکگذاری وابستگیها بین متدها.
- InferringRouter: جایگزین APIRouter با برخی بهبودها برای کار با cbv و تسهیل ثبت مسیرها.
- چند ابزار جانبی کوچک که در برخی پروژهها مفیدند (ساختدهندههای پاسخ، کمک به تست و…).
نصب
نصب بسیار ساده است و از pip قابل انجام است:
pip install fastapi-utils
این دستور پکیج را نصب میکند تا بتوانید از cbv و InferringRouter در پروژه FastAPI خود استفاده کنید.
مثال عملی: استفاده از cbv و InferringRouter
یکی از پرکاربردترین امکانات، امکان نوشتن کنترلرها بهصورت کلاس است. مثال زیر نشان میدهد چگونه یک router و کلاس با وابستگی مشترک را تعریف کنیم.
from fastapi import Depends, FastAPI
from fastapi_utils.cbv import cbv
from fastapi_utils.inferring_router import InferringRouter
app = FastAPI()
router = InferringRouter()
def get_db():
# فرضی: بازگرداندن شیء اتصال به دیتابیس
return {"conn": "db_connection"}
@cbv(router)
class ItemAPI:
def __init__(self, db = Depends(get_db)):
self.db = db
@router.get("/items/{item_id}")
def read_item(self, item_id: int):
return {"item_id": item_id, "db": self.db}
app.include_router(router)
توضیح: در این مثال، با @cbv(router) کلاس ItemAPI به روتر متصل میشود. متد __init__ با استفاده از Depends یک وابستگی (در اینجا اتصال به دیتابیس) دریافت میکند و سپس همه متدهای مسیرِ کلاس میتوانند به این وابستگی دسترسی داشته باشند. این روش خوانایی را افزایش میدهد و از تکرار dependency در هر مسیر جلوگیری میکند.
مزایا نسبت به تعریف تابعی معمولی
| مسأله | تعریف تابعی | تعریف با cbv |
|---|---|---|
| اشتراک وابستگیها | هر تابع باید وابستگی را دوباره تعریف کند | وابستگیها در __init__ تعریف و بین متدها مشترک میشوند |
| سازماندهی کد | تعداد زیادی تابع پراکنده | گروهبندی مسیرها در کلاسهای منطقی |
بهترین روشها و نکات کاربردی
- وابستگیهای حالتدار (مثلاً اتصال پایگاه داده) را در __init__ بگیرید، اما مراقب مدیریت context و همزمانی باشید.
- از Pydantic models برای ورودی و خروجی endpointها استفاده کنید تا از مزایای اعتبارسنجی و مستندسازی خودکار FastAPI بهرهمند شوید.
- هرگاه عملیات I/O سنگین دارید (مثل پایگاه داده)، از متدهای async استفاده کنید تا مقیاسپذیری حفظ شود.
- برای تستپذیری بهتر، وابستگیها را بهراحتی با override کردن در تستها جایگزین کنید.
نسخه async و بهبود یافته
در مثال قبل میتوان متد خواندن آیتم را به صورت async نوشت تا با کدهای غیرهمزمان بهتر کار کند:
from fastapi import Depends, FastAPI
from fastapi_utils.cbv import cbv
from fastapi_utils.inferring_router import InferringRouter
app = FastAPI()
router = InferringRouter()
async def get_db():
# فرضی: بازگرداندن شیء اتصال async به دیتابیس
return {"conn": "async_db_connection"}
@cbv(router)
class ItemAPI:
def __init__(self, db = Depends(get_db)):
self.db = db
@router.get("/items/{item_id}")
async def read_item(self, item_id: int):
# مثلاً await self.db.fetch_item(item_id)
return {"item_id": item_id, "db": self.db}
app.include_router(router)
توضیح: این نسخه از get_db و متد read_item بهصورت async تعریف شدهاند تا با موتورهای async دیتابیس یا دیگر عملیات I/O همخوانی داشته باشند. استفاده از async به افزایش کارایی در بارهای همزمان کمک میکند.
موارد احتیاط و محدودیتها
- cbv کمک میکند کد منظمتری بنویسید، اما اگر وابستگیها بهصورت سراسری یا mutable باشند باید مراقب race condition و مسائل thread-safety باشید.
- تا حد امکان منطق پیچیده کسبوکار را در سرویسها یا لایههای جداگانه (نه مستقیماً در متدهای route) قرار دهید تا تستپذیری بهتر شود.
- fastapi-utils ابزار کمکی است و همه نیازها را پوشش نمیدهد؛ گاهی استفاده از APIRouter استاندارد و توابع ساده مناسبتر است.
نمونهی تست ساده با TestClient
مثالی از تست کردن endpoint نوشتهشده با cbv با استفاده از TestClient:
from fastapi.testclient import TestClient
client = TestClient(app)
def test_read_item():
response = client.get("/items/1")
assert response.status_code == 200
data = response.json()
assert data["item_id"] == 1
assert "db" in data
توضیح: این تست ساده نشان میدهد که چگونه میتوانید endpointهای ساختهشده با fastapi-utils را مانند مسیرهای معمولی تست کنید. در تستهای پیچیدهتر میتوان وابستگی get_db را با نسخههای mock جایگزین کرد.
نتیجهگیری و توصیهها
fastapi-utils یک ابزار جمعوجور اما قدرتمند برای بهبود ساختار و کاهش تکرار در پروژههای FastAPI است. اگر پروژه شما بزرگ میشود و نیاز به سازماندهی مسیرها و وابستگیها دارید، استفاده از cbv و InferringRouter میتواند خوانایی و نگهداری کد را بهطرز محسوسی افزایش دهد. با این حال، همواره توجه کنید که استفاده از این الگوها باید با درک محدودیتهای همزمانی و نحوه مدیریت وابستگیها همراه باشد.
آیا این مطلب برای شما مفید بود ؟




