الخلاصة والامتحان النهائيّ
عشر وحدات لتحويل نموذج داخل دفتر Jupyter إلى واجهة برمجيّة تصمد في الإنتاج. هذه المراجعة تُلخّص المسار، تُبرز الخيوط التي تعبر الدورة، ثمّ تفتح الباب على الامتحان النهائيّ.
الدورة في لمحة
| الوحدة | الجوهر الواجب حفظه |
|---|---|
| 1. المسارات والأنواع والتوثيق الآليّ | التوثيق التفاعليّ آليّ عبر الأنواع؛ Uvicorn في التطوير مع --reload |
| 2. التحقّق من المدخلات مع Pydantic | Field(ge=0) يعطي 422 تلقائيّ؛ مخطّط الاستجابة يمنع تسريب حقول داخليّة |
| 3. تحميل النموذج عند بدء التشغيل | lifespan مرّة واحدة، لا joblib.load في المسار؛ الفش ل عند البدء لا عند الطلب |
| 4. التوقّع الفرديّ وبالدفعات | Pipeline scikit-learn يمنع انحراف المعالجة؛ max_length على الدفعات إلزاميّ |
| 5. معالجة الأخطاء ورموز الحالة | 422 لخرق المخطّط، 400 لخرق قاعدة العمل؛ لا تتبّع استثناء في الاستجابة أبدًا |
| 6. الطلبات غير المتزامنة ومهامّ الخلفيّة | async def مع نموذج حاجب يعطّل الحلقة؛ BackgroundTasks للأعمال القصيرة، Celery للطويلة |
| 7. المصادقة بالرمز | API Key في الترويسة لا في URL؛ JWT للعملاء البشر؛ حدّ المعدّل بـSlowAPI |
| 8. التسجيل ومجسّات الصحّة | JSON مُهيكل بـrequest_id؛ liveness أدنى، readiness يفحص التبعيّات فعلًا |
| 9. التحزيم في حاويات والنشر | Dockerfile متعدّد المراحل يخفض 1.4 غيغا إلى 220 ميغا؛ عدد العمّال = عدد النوى |
| 10. اختبارات الحمل وتحديد الحجم | p95 وp99 لا المتوسّط؛ Locust قبل الإنتاج؛ اختبار الانهيار يكشف كيفيّة الفشل |
الخيوط التي تعبر الدورة
كلّ مسار يعرض واجهة، لا يُنفّذ منطقًا. الوحدات 1، 2، 5، 7 تعبّر عن هذا المبدأ. المسار يستقبل، يتحقّق، يفوّض إلى دالّة داخليّة، يُعيد استجابة مُهيكلة. المنطق التجاريّ في دوالّ Python خالصة قابلة للاختبار وحدها بدون FastAPI. لو صار المسار يمتلئ بـif/else معقّدة، فذلك دليل على أنّه يحمل منطقًا يجب استخراجه.
المخطّط يوقّع العقد بين العميل والخدمة. Pydantic (الوحدة 2) والاستجابة المُهيكلة للأخطاء (الوحدة 5) والتوثيق التفاعليّ (الوحدة 1) ثلاث وجوه لمبدأ واحد: العقد مصرَّح، محقّق تلقائيًّا، ومُوثَّق آليًّا. لو تغيّرت واجهة مسار، Pydantic يُنبّه المستهلكين قبل النشر، ومطوّرو العميل يرون التغيير في الصفحة /docs قبل أن يكسر مكوّنهم.
كلّ عمليّة ثقيلة تُنفَّذ خارج حلقة الأحداث. الوحدات 3 (تحميل النموذج عند البدء)، 4 (استدعاء predict_proba واحد على المصفوفة كاملة)، 6 (BackgroundTasks للتسجيل الجماعيّ)، 8 (سجلّات غير حاجبة) تلتقي هنا. الخدمة لا تنتظر شيئًا ثقيلًا داخل مسار: النموذج مُحمَّل مسبقًا، الدفعة مُتّجهة، الملفّ الكبير في مهمّة خلفيّة، السجلّ يُكتب بلا مزامنة. غير ذلك، الخدمة تعمل حتّى الحمل الأوّل ثمّ تنهار.
ما لا يُقاس لا يوجد. التسجيل المُهيكل والمقاييس (الوحدة 8) والاختبار بـLocust (الوحدة 10) يبنيان قصّة أداء قابلة للإثبات. لو زعم مطوّر «الخدمة سري عة»، بلا أرقام p95، فذلك ادّعاء عائم. الأرقام تحوّل النقاش من مشاعر إلى قرارات: هل نحتاج نسخة رابعة أم لا؟ الجواب في اختبار الحمل، لا في الحدس.
الأمن ليس اختيارًا لاحقًا. المصادقة (الوحدة 7)، عدم كشف تتبّع الاستثناء (الوحدة 5)، حاوية غير root (الوحدة 9)، عدم تسجيل معلومات شخصيّة (الوحدة 8): هذه ليست تفاصيل. غيابها الأوّل يُبقي الخدمة تعمل، لكنّه يفتح بابًا يدخل منه هجوم أو غرامة GDPR. بناء الخدمة بأمن مُدمج من اليوم الأوّل أرخص من إضافته بعد حادث.
قائمة تحقّق: واجهة نموذج في الإنتاج
قبل النشر، يجب أن تكون كلّ نقطة مُعالجة:
- كلّ مسار يعرض
response_modelصريحًا، لاdictعاريًا. - كلّ حقل مدخل يحمل قيدًا معنويًّا (
ge،le،pattern،Literal). - النموذج يُحمَّل في
lifespan، لا في المسار. - pipeline scikit-learn (أو ما يعادله) يحفظ المعالجة والنموذج معًا.
- مسار الدفعات يحمل
max_lengthمقاسًا بحمل حقيقيّ. - كلّ استثناء داخليّ يُلتقط ويُترجَم إلى
HTTPExceptionبالرمز الصحيح. - تتبّع الاستثناء يُسجَّل داخليًّا، ولا يُرجَع للعميل أبدًا.
- كلّ مسار محميّ بمصادقة (API Key أو JWT)، بلا استثناء لـ
/livezو/readyzفقط. - حدّ المعدّل مطبَّق على مستوى المفتاح وعلى مستوى IP.
- سجلّات JSON بـrequest_id تُبَثّ إلى جامع مركزيّ.
- Prometheus مُفعَّل، وGrafana يعرض p95، p99، معدّل الأخطاء، وتوزيع احتمالات النموذج.
- Dockerfile متعدّد المراحل، مستخدم غير root،
.dockerignoreيُغطّي الأسرار. - إعدادات كلّها في متغيّرات بيئة، أسرار في Secret Manager.
- Locust يُثبت أنّ الخدمة تتحمّل ضعفَي حمل الذروة المتوقّع بهامش أمان.
- خطّة تراجع إلى إصدار سابق بتغيير وسم الصورة، وقد جُرِّبت مرّة على الأقلّ.
خمس عشرة نقطة. أيّ نقطة مفقودة قد تعمل ستّة أشهر بلا مشكلة، ثمّ تصبح سبب حادث الإنتاج الأوّل.
الامتحان النهائيّ
يتضمّن الامتحان 40 سؤالًا تشمل الوحدات العشر: بناء مسار FastAPI صحيح، تصميم مخطّط Pydantic دقيق، تحميل النموذج عند البدء، مسار دفعات محميّ من الاستنزاف، معالجة الأخطاء المُهيكلة، تجنّب فخّ async مع نموذج حاجب، اختيار المصادقة الملائمة، تصميم مجسّات صحّة صادقة، بناء صورة Docker محترفة، وقراءة نتائج اختبار حمل قراءة نقديّة.
كثير من الأسئلة تعرض حالات تشخيصيّة عمليّة: خدمة تُعيد 200 على كلّ شيء بينما التنبّؤات خاطئة، حاوية بحجم 1.5 غيغا نُريد تخفيضها، خدمة تنهار عند 500 مستخدم متزامن ولا نعرف لماذا، أو مسار async def أضاف الفريق await أمام كلّ شيء وصار الأداء أسوأ. المقيَّم هو الحكم العمليّ، لا استظهار توقيعات الدوالّ.
عند النجاح تُمنَح شهادة الإتمام فورًا، ورقمها قابل للتحقّق بشكل مستقلّ على المنصّة. الشهادة تُثبت الكفاءة أمام مسؤول توظيف أو عميل: أنّك تعرف فعلًا كيف تُنشر خدمة نموذج في الإنتاج بلا كارثة في الأسبوع الأوّل.
استعِد جدو ل الوحدات أعلاه، واسأل نفسك عن كلّ سطر: «كيف سأشرح هذا لمهندس جديد يوم عمله الأوّل؟». إن استطعت شرح لماذا async def قد يبطئ الخدمة، ولماذا /health يُعيد 200 OK قد يكون كذبة، ولماذا مصفوفة واحدة أسرع من ألف طلب فرديّ، فأنت مستعدّ. حظًّا موفّقًا!
الامتحان النهائي
هل أنت مستعدّ لاعتماد هذه الدورة؟
40 سؤالًا تُختار عشوائيًّا من بنك أسئلة الدورة · حدّ النجاح 70 % · شهادة PDF قابلة للتحقّق تُصدَر فورًا عند النجاح.
ابدأ الامتحانيلزم تسجيل الدخول إلى حسابك في InSkillML مع اشتراك نشط. يمكنك أيضًا بدء الامتحان من دوراتي.