اختبار HTTP و Flask
HTTP & Flask Quiz
اختبار HTTP و Flask — HTTP & Flask Quiz
وصلتَ إلى نهاية الفصل التاسع. هذا الاختبار يجمع كل ما تعلمته — من تحليل استجابات HTTP إلى بناء Flask handlers إلى تصميم JSON APIs. لا مادة جديدة هنا، فقط تطبيق موحّد لما اكتسبته عبر الدروس الثلاثة الماضية.
قبل البدء، تذكّر المبدأ الذي يميّز المبرمج المحترف: الكود الصحيح لا يكتفي بأن “يشتغل” في الحالة السعيدة — يتعامل بدقة مع كل الحالات، ويُنتج مخرجات متوقعة ودقيقة. رموز الحالة HTTP ليست تفصيلاً ثانوياً — هي العقد بين الخادم والعميل. وتنسيق الاستجابة ليس تزييناً — هو ما تبني عليه الواجهات البصرية قراراتها.
كل تحدٍّ يختبر زاوية مختلفة. إذا تعثّرت في تحدٍّ، راجع الدرس المقابل قبل المتابعة — الفهم أهم من الإنهاء. الهدف ليس تجاوز التحديات الخمسة، بل أن تخرج بفهم متماسك تستطيع البناء عليه.
ملاحظة: تحديات Flask تستخدم micropip.install("flask") داخل Pyodide. التحميل الأول يأخذ بضع ثوانٍ — هذا طبيعي وتلقائي. بعد ذلك تكون المكتبة محمّلة في الجلسة.
السؤال 1: تحليل استجابة JSON متداخلة
ما يُختبر: في الواقع العملي، معظم APIs لا تُعيد dict مسطحاً — تُعيد بيانات متداخلة (nested): بيانات المستخدم داخل user، والإحصاءات داخل stats، والملف الشخصي داخل profile. قدرتك على التنقل عبر هذا التداخل بدقة هي المهارة الأساسية لكل مطور يتعامل مع APIs خارجية.
الخطأ الشائع: الوصول إلى مفتاح غير موجود مباشرة بـ data["key"] يُنتج KeyError وتنهار البرنامج. الحل: data.get("key") يُعيد None بدل الانهيار، أو تأكد من وجود المفتاح أولاً. كذلك تحويل القيم المنطقية: JSON يُعيد true/false، وPython تُحوّلها إلى True/False — عند الطباعة بالعربية تحتاج أن تُحوّل بنفسك: "نعم" if value else "لا".
السؤال 2: تصفية قائمة JSON
ما يُختبر: نقاط نهاية APIs كثيراً ما تُعيد قوائم من العناصر — مئات أو آلاف. مهارتك في تصفية هذه القوائم بشرط رياضي وطباعتها بتنسيق محدد هي ما يفرق بين من يقرأ بيانات API وبين من يبنيها داخل برنامج حقيقي. كثير من لوحات التحكم، والتقارير، والواجهات البصرية تُبنى بالضبط على هذا النمط: استقبل قائمة، صفّها بشرط، اعرضها.
الخطأ الشائع: مقارنة القيمة بنوع خاطئ — price > "100" تُقارن نصاً برقم وتُعطي نتائج غير متوقعة لأن المقارنة النصية تختلف عن الرقمية. عند تحليل JSON، الأرقام تُحوَّل تلقائياً إلى float أو int في Python، لذا لا تحتاج تحويلاً إضافياً — لكن تأكد أن مصدر البيانات رقم فعلاً لا نص.
السؤال 3: Flask handler مع معاملات استعلام
ما يُختبر: معاملات الاستعلام (query parameters) هي العمود الفقري لنقاط نهاية البحث والتصفح والترتيب. كل تطبيق يعرض قائمة بيانات يحتاج صفحات (pagination) — وكل صفحة تأتي عبر معامل URL. بناء handler يقرأ هذه المعاملات ويتحقق منها ويرد برمز الحالة الصحيح هو نمط يتكرر في كل project تقريباً.
الخطأ الشائع: request.args.get("page") يُعيد نصاً دائماً حتى لو كانت القيمة "1". المقارنة page > 3 ستفشل لأنك تقارن نصاً برقم. دائماً حوّل: page = int(request.args.get("page", "1")). وإذا فشل التحويل (مثلاً المستخدم أرسل ?page=abc) — احتاط بـ try/except ValueError في كود الإنتاج.
السؤال 4: POST مع تحقق متعدد الحقول
ما يُختبر: تحقق من أكثر من حقل في طلب POST — يعكس واقع بناء APIs حيث كل حقل قد يكون سبب رفض مستقل وبرسالة مختلفة. في التطبيقات الحقيقية، التحقق من الحقول واحداً تلو الآخر (serial validation) يعطي المستخدم رسائل خطأ محددة ومفيدة. بالمقابل، التحقق بشرط واحد ضخم يجعل من الصعب معرفة أي حقل بالضبط هو المشكلة.
الخطأ الشائع الأول: التحقق من الحقول بشرط واحد طويل بدل شروط منفصلة — يجعل الرسائل غامضة. الخطأ الثاني: بعد إعادة الخطأ برمز 400 في if-block، ننسى return فيستمر تنفيذ الكود ويُنشئ سجلاً بالرغم من فشل التحقق. كل return jsonify(...), 400 يجب أن يوقف تنفيذ الدالة فوراً.
تنبيه: micropip.install يحتاج وقتاً في أول تشغيل — انتظر حتى تظهر النتائج.
السؤال 5: API مكتمل — قراءة وإنشاء وحذف
ما يُختبر: هذا هو التحدي الجامع للفصل. قدرتك على تجميع الأنماط الثلاثة (GET قائمة، POST إنشاء، DELETE حذف) في وحدة واحدة متسقة هو ما يعني “تعلّمت REST”. في بيئة الإنتاج، هذا بالضبط ما تكتبه عند بناء أي خدمة تُدير مورداً — منتجات، طلبات، مستخدمين، أو أي شيء آخر. الفارق عن ما تعلمته في الدروس: الآن أنت تكتب كل ذلك بدون مثال يُحاكيه.
الخطأ الشائع: نسيان global عند تعديل قائمة في مستوى module. في Python، قراءة متغير عالمي داخل دالة تعمل مباشرة، لكن إعادة تعيينه (مثل tasks = [...] أو next_id += 1) يحتاج global tasks وglobal next_id في بداية الدالة. إذا نسيت، Python تُنشئ متغيراً محلياً مؤقتاً لا يُغيّر الأصل — وتجد أن الحذف لم يحدث والعداد لم يتغير.
تهانينا — أكملتَ الفصل التاسع
إذا حللتَ هذه التحديات الخمس بنجاح، فأنت تمتلك مهارات حقيقية وقابلة للتطبيق المباشر:
- قراءة JSON متداخل — تحليل أي استجابة API مهما كان شكلها وعمقها
- تصفية البيانات — استخراج ما تحتاجه من قوائم JSON بشروط رياضية دقيقة
- معاملات URL — بناء مسارات مرنة تقبل خيارات الاستعلام وتتحقق منها
- التحقق من البيانات — رفض الطلبات الناقصة برسائل واضحة ورموز حالة صحيحة
- API مكتمل — جمع GET وPOST وDELETE في وحدة متسقة بإدارة حالة سليمة
هذه الأساسات تبني عليها أي خدمة ويب في Python. ما نقص هو الاستمرارية — هذا الـ API يعيش في الذاكرة وينتهي عند إيقاف الخادم. الفصل القادم يربط Flask بقاعدة بيانات حقيقية، فتصبح البيانات دائمة وقابلة للاستعادة بعد الإعادة التشغيل.