دليل البداية السريعة لـ FastAPI

خطوة بخطوة لبناء API احترافي في وقت قصير

١. تثبيت FastAPI

للبدء مع FastAPI، عليك تثبيت حزم Python اللازمة. نوصي باستخدام بيئة افتراضية:

# إنشاء بيئة افتراضية
python -m venv env

# تفعيل البيئة الافتراضية
# في Windows
env\Scripts\activate
# في Linux/Mac
source env/bin/activate

# تثبيت FastAPI و Uvicorn (خادم ASGI)
pip install fastapi uvicorn

شرح الخطوات:

  1. أولاً ننشئ بيئة افتراضية باسم env باستخدام الأمر python -m venv env.
  2. ثم نقوم بتفعيل البيئة الافتراضية. أمر التفعيل يختلف بين أنظمة التشغيل.
  3. أخيراً، نقوم بتثبيت حزمة FastAPI نفسها وكذلك Uvicorn، وهو خادم ASGI يسمح لنا بتشغيل تطبيق FastAPI.

٢. إنشاء أول API

لننشئ ملف Python باسم main.py ونكتب فيه الكود التالي:

from fastapi import FastAPI

# إنشاء تطبيق FastAPI
app = FastAPI()

# تعريف مسار الصفحة الرئيسية
@app.get("/")
def read_root():
    return {"message": "مرحباً بك في FastAPI!"}

شرح الكود سطراً بسطر:

  • from fastapi import FastAPI: استيراد فئة FastAPI الرئيسية من المكتبة.
  • app = FastAPI(): إنشاء كائن من فئة FastAPI وتخزينه في متغير يسمى app. هذا المتغير يمثل تطبيقنا.
  • @app.get("/"): هذا ما يسمى بالمزين (decorator) ويخبر FastAPI أن الدالة التي تليه تستجيب لطلبات GET على المسار "/".
  • def read_root():: تعريف دالة تسمى read_root. هذه الدالة ستنفذ عندما يزور المستخدم المسار "/".
  • return {"message": "مرحباً بك في FastAPI!"}: ترجع الدالة قاموس Python. سيقوم FastAPI تلقائيًا بتحويله إلى JSON.

لتشغيل التطبيق، افتح موجه الأوامر (Terminal) وقم بتنفيذ الأمر التالي:

uvicorn main:app --reload

main هو اسم ملف Python (main.py) و app هو اسم المتغير الذي يحتوي على تطبيق FastAPI.

الخيار --reload يجعل الخادم يعيد التحميل تلقائيًا عند تغيير الكود، وهو مفيد أثناء التطوير.

بعد تنفيذ هذا الأمر، يمكنك زيارة http://127.0.0.1:8000 في المتصفح لرؤية النتيجة.

٣. معلمات المسار (Path Parameters)

معلمات المسار هي قيم متغيرة في مسار URL. لنضيف مساراً يستخدم معلمة المسار:

@app.get("/items/{item_id}")
def read_item(item_id: int):
    return {"item_id": item_id}

شرح الكود:

  • @app.get("/items/{item_id}"): تعريف مسار يحتوي على جزء متغير {item_id}.
  • def read_item(item_id: int):: تعريف دالة تأخذ معاملاً يسمى item_id من نوع int. FastAPI سيقوم تلقائيًا بتحويل القيمة من النص إلى عدد صحيح.
  • return {"item_id": item_id}: إرجاع قاموس يحتوي على قيمة المعامل.

عندما تزور http://127.0.0.1:8000/items/5، ستحصل على استجابة {"item_id": 5}.

إذا أدخلت قيمة غير صحيحة مثل http://127.0.0.1:8000/items/abc، سترى خطأ التحقق التلقائي من FastAPI.

٤. معلمات الاستعلام (Query Parameters)

معلمات الاستعلام هي قيم تضاف في نهاية الرابط بعد علامة الاستفهام ?. مثل: /items/?skip=10&limit=5

from fastapi import FastAPI, Query

app = FastAPI()

@app.get("/products/")
def read_products(skip: int = 0, limit: int = 10, q: str | None = None):
    products = ["منتج 1", "منتج 2", "منتج 3", "منتج 4", "منتج 5"]
    
    if q:
        filtered_products = [p for p in products if q in p]
    else:
        filtered_products = products
    
    return {
        "products": filtered_products[skip : skip + limit],
        "total": len(filtered_products),
        "skip": skip,
        "limit": limit,
        "q": q
    }

شرح الكود:

  • def read_products(skip: int = 0, limit: int = 10, q: str | None = None):: تعريف دالة تأخذ ثلاثة معلمات استعلام اختيارية:
    • skip: عدد العناصر التي يتم تخطيها (القيمة الافتراضية 0).
    • limit: الحد الأقصى للعناصر المرجعة (القيمة الافتراضية 10).
    • q: سلسلة بحث اختيارية (القيمة الافتراضية None).
  • نقوم بتعريف قائمة منتجات للمثال.
  • إذا تم توفير معلمة البحث q، نقوم بتصفية المنتجات التي تحتوي على النص المطلوب.
  • نعيد النتائج مع استخدام skip و limit لتقسيم القائمة.

عند زيارة http://127.0.0.1:8000/products/?skip=1&limit=2&q=منتج، سترى النتائج المصفاة حسب المعلمات المقدمة.

٥. بيانات الطلب (Request Body)

لإرسال بيانات في جسم الطلب (مثل طلبات POST)، نستخدم نماذج Pydantic لتعريف هيكل البيانات:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

# تعريف نموذج البيانات
class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None

@app.post("/items/")
def create_item(item: Item):
    # حساب السعر الإجمالي إذا كانت قيمة الضريبة موجودة
    total_price = item.price
    if item.tax:
        total_price += item.tax
    
    # إنشاء قاموس يحتوي على البيانات المدخلة والسعر الإجمالي
    return {
        "item_name": item.name,
        "item_price": item.price,
        "tax": item.tax,
        "total_price": total_price,
        "description": item.description
    }

شرح الكود:

  • from pydantic import BaseModel: استيراد BaseModel من Pydantic، وهو يستخدم لتعريف نماذج البيانات والتحقق منها.
  • class Item(BaseModel):: تعريف فئة تمثل نموذج البيانات المتوقع في جسم الطلب.
  • داخل الفئة، نحدد الحقول وأنواعها:
    • name: str: حقل إجباري من نوع سلسلة نصية.
    • description: str | None = None: حقل اختياري من نوع سلسلة نصية (يمكن أن يكون None).
    • price: float: حقل إجباري من نوع عدد عشري.
    • tax: float | None = None: حقل اختياري من نوع عدد عشري.
  • @app.post("/items/"): تعريف مسار يستجيب لطلبات POST.
  • def create_item(item: Item):: تعريف دالة تأخذ البيانات من جسم الطلب وتتوقع أن تكون من نوع Item.
  • الدالة تقوم بحساب السعر الإجمالي بناءً على السعر والضريبة ثم تعيد النتائج.

لاختبار هذا المسار، يمكنك استخدام أداة مثل Postman أو curl لإرسال طلب POST مع بيانات JSON:

{
  "name": "هاتف ذكي",
  "description": "هاتف ذكي جديد",
  "price": 799.99,
  "tax": 50
}

٦. التحقق من البيانات (Validation)

يمكننا إضافة قواعد تحقق إضافية باستخدام Pydantic:

from fastapi import FastAPI, Path, Query
from pydantic import BaseModel, Field, EmailStr

app = FastAPI()

class User(BaseModel):
    username: str = Field(..., min_length=3, max_length=50)
    email: EmailStr
    full_name: str | None = None
    age: int = Field(..., gt=0, lt=120)
    
    class Config:
        schema_extra = {
            "example": {
                "username": "user123",
                "email": "[email protected]",
                "full_name": "مستخدم كامل",
                "age": 25
            }
        }

@app.post("/users/")
def create_user(user: User):
    return {"user": user.dict()}

شرح الكود:

  • from pydantic import Field, EmailStr: استيراد أدوات إضافية من Pydantic للتحقق.
  • في تعريف فئة User، نستخدم Field() لإضافة قواعد تحقق:
    • username: str = Field(..., min_length=3, max_length=50): حقل إجباري (بسبب ...) مع طول لا يقل عن 3 أحرف ولا يزيد عن 50.
    • email: EmailStr: حقل من نوع خاص للبريد الإلكتروني يتحقق من صحة التنسيق.
    • age: int = Field(..., gt=0, lt=120): عدد صحيح أكبر من 0 وأقل من 120.
  • class Config:: فئة داخلية لتكوين النموذج.
  • schema_extra: يحدد مثالًا للبيانات سيظهر في مستندات API.
  • عندما يتلقى FastAPI طلبًا، سيقوم تلقائيًا بالتحقق من البيانات وإرجاع أخطاء مفصلة إذا كانت البيانات غير صالحة.

٧. توثيق API تلقائيًا

واحدة من أفضل ميزات FastAPI هي التوثيق التلقائي باستخدام Swagger UI و ReDoc:

from fastapi import FastAPI

# تخصيص معلومات التوثيق
app = FastAPI(
    title="تطبيق API مثال",
    description="هذا مثال لـ API باستخدام FastAPI",
    version="0.1.0",
    contact={
        "name": "فريق الدعم",
        "url": "https://example.com/support",
        "email": "[email protected]",
    },
    license_info={
        "name": "MIT",
        "url": "https://opensource.org/licenses/MIT",
    }
)

@app.get("/")
def read_root():
    """
    قراءة الصفحة الرئيسية.
    
    هذا النص سيظهر في التوثيق.
    """
    return {"message": "مرحباً بك في FastAPI!"}

@app.get("/items/{item_id}")
def read_item(item_id: int):
    """
    قراءة معلومات عنصر محدد.
    
    - **item_id**: معرف العنصر الذي تريد استرجاعه
    """
    return {"item_id": item_id}

شرح الكود:

  • عند إنشاء كائن FastAPI، نضيف معلومات للتوثيق مثل العنوان والوصف والإصدار.
  • يمكننا إضافة معلومات الاتصال ومعلومات الترخيص أيضًا.
  • نضيف تعليقات توثيق (docstrings) إلى الدوال حيث:
    • النص الرئيسي يصبح الوصف العام للنقطة النهائية.
    • العناصر المميزة بالنجمة مثل **item_id** تظهر بتنسيق خاص في التوثيق.
  • للوصول إلى التوثيق التفاعلي، قم بزيارة:
    • واجهة Swagger UI: http://127.0.0.1:8000/docs
    • واجهة ReDoc: http://127.0.0.1:8000/redoc

هذه الواجهات تتيح لك:

  • تصفح جميع نقاط النهاية في واجهة API
  • رؤية نماذج الطلبات والاستجابات
  • اختبار نقاط النهاية مباشرة من المتصفح
  • استكشاف قواعد التحقق وأنواع البيانات المتوقعة

الخطوات التالية

لقد تعرفنا على الأساسيات الضرورية لبدء العمل مع FastAPI. هناك العديد من الميزات المتقدمة الأخرى التي يمكنك استكشافها:

  • إعداد قواعد البيانات مع SQLAlchemy
  • إضافة المصادقة والتفويض
  • رفع الملفات
  • التعامل مع المهام الخلفية
  • إنشاء اختبارات تلقائية
  • نشر التطبيق