4.2واجهات الويب مع Flask و FastAPI
الأساسي في 30 ثانية
- واجهة البرمجة = عقد JSON : الموارد (
GET /articlesوPOST /articles) وحالات صادقة (200 قُرئ، 201 أُنشئ، 400 غير صالح، 404 غير موجود). - Flask = حرية بسيطة (خدمات صغيرة، للتعلم) ؛ وFastAPI = حديث : تلميحات الأنواع ← تحقق تلقائي + توثيق تفاعلي
/docs، ولاتزامن أصيل. - منعكس نبيل : تصميم الموارد والحالات قبل الكود، والتحقق من كل مدخَل عبر Pydantic، والاختبار بـ TestClient.
حالة مصغرة متسلسلة — نبيل يقدم مبيعاته كـ JSON
المكتب الخلفي Django لنبيل (4.1) مفيد جدا، لكن زميلا يريد أرقام المبيعات في لوحة قيادة منفصلة : يلزمه JSON لا صفحات HTML. بنى نبيل واجهة FastAPI صغيرة في الجزائر : GET /ventes للقراءة، وPOST /ventes (201 إن أُنشئ، 400 إن كان غير صالح) للإضافة، مع تحقق Pydantic وتوثيق تفاعلي على /docs. صار الزميل يستكشف الواجهة وحده دون الاتصال بنبيل. ثاني محطة في الخيط الرابط : البيانات نفسها، مقدمة لكل العملاء.
تتمة حالة 4.1 — نبيل يفصل بياناته عن عرضها.
1. واجهة REST : الموارد و JSON والحالات
تعرض واجهة REST (REST API) البيانات كـ JSON عبر روابط وطرق HTTP : GET /ventes يقرأ، وPOST /ventes ينشئ، وحالة HTTP تقول النتيجة — 200 قُرئ، و201 أُنشئ، و400 مدخَل غير صالح، و404 غير موجود. ويطابق JSON (مفاتيح/قيم، قوائم) قواميس وقوائم بايثون تماما : إنه الصيغة العالمية. ويصمم نبيل أولا موارده وحالاته — العقد — قبل كتابة أي سطر.
2. Flask البسيط و FastAPI الحديث
Flask إطار مصغر : مسار واحد = رابط واحد إلى دالة، وحرية تامة، ومثالي للتعلم والخدمات الصغيرة. وFastAPI خليفته الحديث : تلميحات الأنواع (titre: str) تغذي Pydantic الذي يتحقق من كل مدخَل تلقائيا، وتوثيق OpenAPI يتولد وحده (صفحة تفاعلية /docs)، ولاتزامن (async) أصيل (async/await) يعالج الطلبات المتزامنة دون حجب. اختار نبيل FastAPI لواجهة مبيعاته : تحقق + توثيق حي دون جهد.
ونوثق : نختبر كل مسار بـ pytest + TestClient (POST صالح ← 201، وPOST غير صالح ← 400)، ونوثق عبر /docs بدلا من مستند Word يتقادم. فواجهة مختبرة وموثقة ذاتيا عقد يستعمله الزملاء دون إزعاجك.
🔎 مثال ملموس — 🔎 مثال ملموس — واجهة مبيعات نبيل
خطوات نبيل مع الواجهات الحقيقية لـ FastAPI :
class Vente(BaseModel): ville: str; montant: float # تحقق تلقائي
@app.get("/ventes") ← قائمة JSON (200)
@app.post("/ventes", status_code=201) ← ينشئ (201) أو 400 إن كان غير صالح
uvicorn main:app --reload + التوثيق على /docs
القراءة : نموذج متحقق منه، ومساران، وحالات صريحة.
الدرس : التلميحات تمنح التحقق + التوثيق.
مفردات القسم
- واجهة REST (API REST)
- بيانات معروضة كـ JSON عبر روابط وطرق HTTP (GET للقراءة، POST للإنشاء)، مع حالات تقول النتيجة.
مثال بسيط: واجهة نبيل : GET /ventes يقرأ، وPOST /ventes ينشئ (201).
ما ليس كذلك: صفحات HTML محصورة في عرض وحيد.
رد فعل: صمم الموارد + الحالات قبل الكود.
- Flask
- إطار بايثون مصغر : مسار واحد = رابط واحد إلى دالة ؛ حرية تامة، ومثالي للتعلم والخدمات الصغيرة.
مثال بسيط: يسود فيه نبيل أول نموذج لواجهته في بضعة أسطر.
ما ليس كذلك: إطار كامل يفرض الإدارة ورسم الكائنات العلائقية.
رد فعل: خدمة صغيرة مفصلة ؟ يكفي Flask.
- FastAPI + Pydantic
- إطار واجهات حديث : تلميحات الأنواع تغذي Pydantic الذي يتحقق من المدخلات، ويولد توثيق OpenAPI ويدعم اللاتزامن.
مثال بسيط: بيع نبيل متحقق منه (المبلغ رقم مطلوب) دون كود مراقبة.
ما ليس كذلك: مدخلات مقبولة دون تحقق.
رد فعل: نمط كل نموذج مدخَل، واختبر الـ 400.
- حالات HTTP
- رموز النتيجة : 200 قُرئ، و201 أُنشئ، و400 مدخَل غير صالح، و404 غير موجود — العقد الذي يقرؤه العميل أولا.
مثال بسيط: POST نبيل يجيب 201 إن أُنشئ، و400 إن غاب المبلغ.
ما ليس كذلك: 200 مرجعة لكل شيء، نجاحا وأخطاء.
رد فعل: لكل مسار : أي حالة لأي وضع ؟
في التطبيق — عمليا — تقديم واجهة FastAPI
- ثبت fastapi و uvicorn في بيئة افتراضية، ثم صرح بنموذج Pydantic (مثلا بيع : المدينة str، والمبلغ float).
- أضف GET /ventes (للقراءة، 200) وPOST /ventes (للإنشاء، status_code=201) على قائمة في الذاكرة.
- أطلق بـ « uvicorn main:app --reload » واستكشف التوثيق التفاعلي على /docs : واختبر من المتصفح.
- اكتب اختبارين (pytest + TestClient) : POST صالح ← 201، وPOST غير صالح ← 400 ؛ وصحح حتى الاخضرار.
نص جاهز للقول — عرض واجهته (30 ثانية)
«معكم نبيل : مبيعاتنا مقدمة كـ JSON — GET للقراءة، وPOST بـ 201 للإنشاء، و400 إن كان المدخَل غير صالح. يتحقق Pydantic من كل شيء، والتوثيق على /docs محدث أصلا، والاختبارات تقفل العقد.»
يُقال في العرض ؛ واعرض /docs مباشرة.
نموذج نسخ-لصق — واجهة FastAPI (كود مختبر)
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Vente(BaseModel):
ville: str
montant: float
VENTES: list[Vente] = []
@app.get("/ventes")
def lister():
return VENTES
@app.post("/ventes", status_code=201)
def creer(vente: Vente):
VENTES.append(vente)
return vente
# التشغيل : uvicorn main:app --reload
# التوثيق التفاعلي : /docs
# الاختبار :
# from fastapi.testclient import TestClient
# client = TestClient(app)
# assert client.post("/ventes", json={"ville": "Alger", "montant": 1200.5}).status_code == 201
# assert client.post("/ventes", json={"ville": "Alger"}).status_code == 422
نموذج سريع
Flask في بضعة أسطر : مسار واحد وJSON، وفكرتك قابلة للعرض هذا المساء.
واجهة فريق
مثل نبيل : FastAPI + Pydantic في كل مكان، و/docs كتوثيق رسمي، وTestClient عادة.
حركة كثيفة
مرر العروض الشرهة إلى اللاتزامن (async def) : فانتظارات الشبكة لم تعد تكدس الطلبات.
بيانات Django
احتفظ بنماذج Django (4.1) واعرضها كـ JSON : البيانات نفسها، وعقد جديد، وصفر إعادة كتابة.
✓ ممارسات جيدة
- صمم العقد (الموارد + الحالات) قبل الكود.
- تحقق من كل مدخَل عبر Pydantic.
- اختبر بـ TestClient ووثق عبر /docs.
✗ أخطاء شائعة
- إرجاع 200 لكل شيء، نجاحا وأخطاء.
- قبول مدخلات غير متحقق منها.
- صيانة توثيق منفصل يتقادم.
النقاط الأساسية
- واجهة REST = JSON عبر الرابط + طرق HTTP ؛ وحالات صادقة (200/201/400/404).
- FLASK بسيط (الحرية، الخدمات الصغيرة) ؛ وFASTAPI حديث (تحقق تلقائي، /docs، لاتزامن).
- PYDANTIC يتحقق انطلاقا من تلميحات الأنواع ؛ وTESTCLIENT يقفل العقد.
- البيانات نفسها، وعملاء متعددون : افصل العرض عن الإظهار.
تحدي 48 ساعة — طبق غدا
اعرض بياناتك الخاصة : GET + POST مع نموذج Pydantic، و201/400 صحيحان، و/docs مستكشفة واختباران خضراوان.
- أستطيع ذكر الموارد و JSON والحالات 200/201/400/404.
- أعرف شرح تحقق Pydantic و/docs.
- عندي واجهة مختبرة تقدم بياناتي.
أسئلة شائعة
لماذا JSON في كل مكان في الواجهات ؟
لأنها صيغة نصية خفيفة بمفاتيح/قيم وقوائم تطابق قواميس وقوائم بايثون تماما : مقروءة للإنسان، وقابلة للتدبير في سطر كود واحد، ومفهومة لكل اللغات. يستلم العميل JSON، فيحوله إلى كائنات أصلية، ويشتغل — دون مشغل ولا صيغة مملوكة.
ما فائدة اللاتزامن (async/await) في FastAPI ؟
معالجة كثير من الطلبات المتزامنة دون حجب : فبينما ينتظر طلب القاعدة أو الشبكة، يعالج الخادم الطلبات الأخرى بدلا من الانتظار. ولواجهة تقرأ البيانات أو تنادي خدمات، يرفع اللاتزامن الإنتاجية بوضوح بالخادم نفسه — دون تغيير المنطق.
ماذا تعرض واجهة REST لعملائها ؟