تكرار السؤال: …
الإجابة المختصرة
يحل Depends الاعتماديات (اتصال قاعدة البيانات، المستخدم الحالي، الإعدادات) لكل طلب ويمررها للمسار، ويدعم الاعتماديات المتداخلة والتنظيف عبر yield. استخدم async def عندما يكون كل ما بداخله غير متزامن، و def للكود الحاجب لأن FastAPI يشغّله في threadpool.
الشرح
تُخزن نتيجة الاعتمادية مؤقتًا داخل الطلب الواحد، فإذا طلبتها عدة اعتماديات تُحسب مرة واحدة. الاعتمادية التي تستخدم yield مناسبة لفتح جلسة قاعدة بيانات وإغلاقها بعد الرد. أخطر خطأ هو استدعاء مكتبة حاجبة (مثل requests أو ORM متزامن) داخل async def، لأنها تحجب الـ event loop وتوقف كل الطلبات. ويمكن تجاوز الاعتماديات في الاختبارات عبر app.dependency_overrides.
مثال بالكود
from typing import Annotated
from fastapi import Depends, FastAPI, HTTPException
app = FastAPI()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
def current_user(token: str = Depends(oauth2_scheme), db=Depends(get_db)) -> User:
user = verify_token(db, token)
if not user:
raise HTTPException(status_code=401)
return user
@app.get("/me")
def me(user: Annotated[User, Depends(current_user)]): # def: الـ ORM متزامن
return {"email": user.email}أخطاء شائعة
- استخدام requests أو ORM متزامن داخل async def فيتجمد الخادم تحت الحمل.
- إنشاء جلسة قاعدة بيانات عامة مشتركة بين الطلبات بدل اعتمادية لكل طلب.