هل إطار العمل Reflex هو الأفضل لتطوير تطبيقات الويب المتكاملة بلغة Python؟

BBetter Stack
컴퓨터/소프트웨어창업/스타트업AI/미래기술

Transcript

00:00:00هل أنت من عشاق لغة بايثون المخلصين؟ أعني، هل أنت من الأشخاص الذين يريدون فقط كتابة كود بايثون
00:00:05ولا شيء غيره؟ حسنًا، إذا كنت كذلك، فلدي الحل الأمثل لك. إنه إطار عمل يسمى
00:00:11Reflex، وهو يهدف إلى حل التعقيدات والعقبات المتعلقة بتحويل كود بايثون للبرمجة كاملة المسار
00:00:17إلى تطبيقات ويب جاهزة للإنتاج. في هذا الفيديو، سنلقي نظرة على ماهية
00:00:22Reflex، وكيفية عمله، ولنرى سر الضجة المثارة حوله.
00:00:30المشكلة الأساسية التي يحاول Reflex حلها هي حاجة مطوري بايثون لتعلم
00:00:36تقنيات مختلفة تمامًا، بما في ذلك JavaScript وReact والتوجيه وأدوات التجميع، فقط ليتمكنوا
00:00:43من بناء واجهة ويب فعالة لأكوادهم. يسمح Reflex للمطورين ببناء تطبيقات كاملة المسار
00:00:50بلغة بايثون بنسبة 100%، لذا يمكنك التركيز على استخدام لغة واحدة للمسار بالكامل دون الحاجة
00:00:56لتشتيت انتباهك بين لغات مختلفة. يزعمون أيضًا أنه منذ انطلاقهم، قام المطورون ببناء أكثر من مليون تطبيق
00:01:03باستخدام إطار العمل هذا، كما يزعمون أن 30% من شركات Fortune 500 تستخدمه في
00:01:10أدواتها الداخلية. ومؤخرًا، بدأوا في التركيز بقوة على الذكاء الاصطناعي وأطلقوا
00:01:15أداة تسمى Reflex Build، والتي تتيح لك برمجة تطبيقك بمجرد إعطاء أمر نصي واحد.
00:01:21بالإضافة إلى ذلك، يدعمون التكامل مع مجموعات تطوير البرامج (SDKs) والأدوات الأخرى التي تتيح لك ربط تطبيقك
00:01:26بخدمات شهيرة أخرى مثل Databricks وOkta وStripe وAWS وما إلى ذلك. كل هذا يبدو مثيرًا للإعجاب،
00:01:34لكنني أريد أن أبدأ العمل العملي وأجرب هذا الكود بنفسي لأرى كيف يعمل فعليًا.
00:01:40لنبدأ بإنشاء مجلد جديد باسم ReflexTest، ثم ندخل إليه. من هنا،
00:01:44تقول الوثائق أنه يمكننا تشغيل هذه الأوامر الثلاثة لبدء مشروع Reflex الخاص بنا. لذا لنبدأ
00:01:48بتشغيل pip install reflex ثم reflex init. وهنا يُعرض علينا البدء باستخدام أحد
00:01:53القوالب الجاهزة لديهم. ولكن في هذا العرض التوضيحي، سنبقي الأمر بسيطًا ونختار خيار
00:01:57تطبيق reflex فارغ. بمجرد الانتهاء، يمكننا فتح المشروع في محرر الكود الخاص بنا. وإذا فتحنا
00:02:02مجلد reflex test، فسنرى أن تطبيقنا بالكامل موجود في ملف reflex_test.py. يمكننا أن نرى
00:02:09أنه يحتوي على قسم لمكونات RX وفئة الحالة (State class). لنقم بتشغيل reflex run في الطرفية لإطلاق
00:02:15تطبيقنا. وسيعمل التطبيق على المنفذ 3000. ويمكننا رؤية النتيجة هنا في المتصفح.
00:02:20الآن دعونا نرى كيف يدير Reflex الحالة. يمكننا البدء بإضافة متغير عداد بسيط.
00:02:25ولتغيير هذه القيمة، نحتاج أيضًا إلى تعريف وظيفة تقوم بذلك. لذا أسفل
00:02:29متغير العداد، يمكننا تعريف وظيفة increment تزيد العداد بمقدار واحد. ويُنصح
00:02:34بإضافة مزخرف (decorator) باسم RX event في الأعلى، والذي يسمح بالتحقق الثابت من النوع
00:02:39ويضمن استلام معالجات الأحداث للعدد والأنواع الصحيحة من المعاملات. وبعد ذلك يمكننا إضافة
00:02:44زر بسيط في جملة الإرجاع (return) الخاصة بمكون RX. حيث سيظهر لنا العداد في حقل
00:02:48النص وسيقوم بتشغيل وظيفة الزيادة عند النقر. ويدعم Reflex التحديث الفوري (Hot Reloading). لذا إذا
00:02:53قمنا الآن بحفظ الملف وفتح المتصفح، سنرى زر العداد الذي يزيد القيمة
00:02:58في كل مرة نضغط فيها عليه. الآن دعونا نجرب شيئًا أكثر إثارة. لنقم بإنشاء مصفوفة من العناصر
00:03:02في حالتنا البرمجية. ومن الناحية النظرية، يجب أن نكون قادرين على عرض هذه العناصر كقائمة عن طريق القيام
00:03:08بهذه الحلقة التكرارية (for loop) المضمنة. لكن هذا لن يعمل لأن هذه القيمة غير معروفة وقت التجميع. كما ترون،
00:03:13فإن طريقة عمل Reflex هي أنه عند تشغيل تطبيقك، يتم تجميع الواجهة الأمامية إلى كود JavaScript
00:03:18يعمل في المتصفح، وهذا ما يسمى “وقت التجميع” (Compile Time) في مصطلحات Reflex. أما الواجهة الخلفية فتبقى
00:03:23بلغة بايثون وتعمل على الخادم طوال فترة تشغيل التطبيق. وهذا ما يسمى “وقت التشغيل” (Runtime)
00:03:27في مصطلحات Reflex. لذا لا يمكننا استخدام حلقة for بلغة بايثون صرفة داخل عرض المكون، ولكن يمكننا القيام
00:03:32بعمليات بايثون الصرفة خارج كتلة عرض المكون. ولكن كيف نقوم بالتكرار عبر العناصر في
00:03:37كتلة المكون؟ حسنًا، في هذه الحالة، نحتاج إلى تعريف وظيفة عرض عناصر بسيطة تقوم
00:03:42بعرض عنصرنا بهذا الشكل. ثم نحتاج إلى استخدام وظيفة Rx.foreach في كتلة
00:03:47عرض المكون للقيام بالحلقة التكرارية. والآن نرى عناصرنا تُعرض بشكل صحيح في التطبيق. وينطبق الشيء نفسه على
00:03:53العرض الشرطي. لا يمكننا استخدام جمل if-else العادية في كتلة الإرجاع بهذا الشكل. بدلاً من ذلك،
00:03:58نحتاج إلى استخدام وظيفة Rx.cond بهذا الشكل. وإذا قمنا الآن بالنقر على الزر أكثر من خمس
00:04:02مرات، فسيظهر النص الخاص بنا على تطبيقنا. آخر شيء سننظر إليه هو كيف يمكننا جلب
00:04:08وعرض البيانات. في هذا العرض، سنقوم بجلب حقيقة عشوائية وغير مفيدة من واجهة برمجة تطبيقات
00:04:12الحقائق العشوائية ونعرضها في مربع نص. أولاً، لنضف متغيرًا منطقيًا (boolean) يوضح ما إذا كانت
00:04:17بياناتنا قيد الجلب، وسلسلة نصية فارغة بسيطة ستحمل الحقيقة. وبعد ذلك يمكننا تعريف
00:04:22وظيفة جلب بيانات غير متزامنة ستجعل حالة جلب البيانات “صحيحة”. ثم ستستخدم
00:04:27مكتبة HTTPX لجلب حقيقتنا العشوائية وتخزينها في متغير حالة الحقيقة. وسأضيف أيضًا
00:04:33تأخيرًا بسيطًا لمدة ثانية واحدة باستخدام asyncio حتى نتمكن من رؤية جلب البيانات في الوقت
00:04:38الفعلي. بعد اكتمال العملية، نقوم بإرجاع قيمة جلب البيانات المنطقية إلى “خاطئة”. ولاحظ كيف
00:04:43أضفنا عملية yield هنا. ففي أي وقت نريد فيه تحديث واجهة المستخدم عدة مرات في معالج
00:04:48حدث ما، يمكننا استخدام yield عندما نريد إرسال تحديث إلى المعالج. لذا في هذه الحالة، بمجرد
00:04:52تغير حالة جلب البيانات، نريد تحديث واجهة المستخدم لتعكس ذلك التغيير. ودعونا لا ننسى
00:04:57إضافة استيرادات HTTPX وasyncio في الأعلى. وأخيرًا، في وظيفة العرض، يمكننا استخدام وظيفة
00:05:03Rx.cond بسيطة لإظهار مؤشر تحميل أو الحقيقة بناءً على الحالة الحالية. وإذا
00:05:08أردنا تشغيل هذه الوظيفة في كل مرة نقوم فيها بتحميل الصفحة، فنحن بحاجة لإضافة مزخرف لمكون RX
00:05:12سيقوم بتشغيل وظيفة جلب البيانات عند تحميل الصفحة. والآن إذا أعدنا تحميل صفحتنا، فسنرى
00:05:18الحقيقة العشوائية يتم جلبها وعرضها على الصفحة. آخر شيء أريد القيام به
00:05:22هنا هو إلقاء نظرة على مجلد .web. كما نرى هنا، كل ما كتبناه للتو تم تجميعه
00:05:27وعرضه في تطبيق React في الخفاء، والذي يستخدم Vite وTailwind. كما أنه
00:05:33يحتوي على React Router لمعالجة المسارات. ولأكون صريحًا، بمجرد رؤيتي لهذا، شعرت
00:05:38بخيبة أمل كبيرة. كنت أعتقد أنهم قاموا ببناء مترجم JavaScript مخصص أو شيء أصيل.
00:05:42لكن هذا يعني فقط أن Reflex هو مجرد طبقة تجريد أخرى فوق React. لذا فلدي
00:05:47مشاعر مختلطة تجاه Reflex. فمن ناحية، الفكرة رائعة حقًا بوجود إطار عمل بايثون واحد
00:05:53كامل المسار يتيح لك كتابة كل شيء بلغة بايثون صرفة. ولكن خاب أملي عندما
00:05:59اكتشفت أنه في الخفاء، هو مجرد غلاف لتطبيق React ولا يستخدم بايثون بشكل أصلي. وهذا
00:06:05يجعل الأمر أكثر تعقيدًا، لأنك الآن مضطر لإعادة تعلم بنية جديدة وفهم
00:06:11كيفية تعامل Reflex مع إدارة الحالة، ناهيك عن كل الحالات الاستثنائية التي قد تحدث، لذا قد يكون من
00:06:16الأفضل البقاء مع React لأنه إطار عمل صلب ومُجرب. لذا إذا كنت سأقوم بإنشاء
00:06:22مشروع بواجهة خلفية بلغة بايثون، فسأظل أستخدم إطار عمل JavaScript لواجهتي الأمامية.
00:06:28لم يقنعني Reflex بالاعتماد كليًا على بايثون في كامل المسار. ولكن هذا مجرد رأيي المتواضع. ما
00:06:34رأيك في Reflex؟ هل تعجبك فكرة إطار عمل بايثون كامل المسار مثل هذا؟
00:06:39أنا مهتم حقًا بمعرفة رأيكم. ويا رفاق، إذا استمتعتم بهذا الفيديو، فلا تترددوا
00:06:44في إخبارنا من خلال الضغط على زر الإعجاب أسفل الفيديو. ولا تنسوا الاشتراك في قناتنا.
00:06:50كان معكم أندريس من Better Stack وأراكم في الفيديوهات القادمة.

Key Takeaway

يوفر Reflex وسيلة قوية لمطوري بايثون لبناء تطبيقات متكاملة بسرعة، ولكنه يظل طبقة تجريد فوق تقنيات JavaScript مما يفرض بعض القيود التعليمية والتقنية.

Highlights

يعد إطار العمل Reflex حلاً لمطوري بايثون لبناء تطبيقات ويب متكاملة (Full-stack) باستخدام لغة بايثون بنسبة 100% دون الحاجة لتعلم JavaScript.

تعتمد بنية Reflex على فصل المهام، حيث يتم تجميع الواجهة الأمامية إلى React بينما تظل الواجهة الخلفية تعمل بلغة بايثون على الخادم.

يوفر الإطار ميزات متقدمة مثل Reflex Build المدعوم بالذكاء الاصطناعي لإنشاء التطبيقات عبر الأوامر النصية وتكامل واسع مع خدمات مثل Stripe وAWS.

يتطلب العمل مع Reflex استخدام دوال خاصة مثل Rx.foreach وRx.cond بدلاً من حلقات التكرار والجمل الشرطية التقليدية في بايثون داخل مكونات الواجهة.

أعرب المحلل عن خيبة أمله بعد اكتشاف أن Reflex هو مجرد طبقة تجريد فوق React وVite وليس محركاً أصيلاً للغة بايثون في المتصفح.

يدعم الإطار التحديث الفوري (Hot Reloading) وإدارة الحالة (State Management) من خلال فئات ومزخرفات (Decorators) مخصصة لضمان سلامة أنواع البيانات.

Timeline

مقدمة عن إطار العمل Reflex ومشكلة تطوير الويب

يبدأ الفيديو بمخاطبة عشاق لغة بايثون الذين يفضلون عدم التعامل مع لغات برمجة أخرى في مشاريعهم. يطرح المتحدث إطار العمل Reflex كحل مثالي لتبسيط عملية تحويل كود بايثون إلى تطبيقات ويب جاهزة للإنتاج الفعلي. تهدف هذه الأداة إلى إزالة التعقيدات المرتبطة بالبرمجة كاملة المسار (Full-stack) وجعلها أكثر سلاسة للمبرمجين. يشير التمهيد إلى أن الفيديو سيغطي ماهية الأداة وآلية عملها التقنية والسبب وراء شهرتها الواسعة مؤخراً. يعتبر هذا القسم مدخلاً أساسياً لفهم الغرض من وجود مثل هذه الأطر البرمجية في بيئة تطوير الويب الحديثة.

المميزات والانتشار والتوجه نحو الذكاء الاصطناعي

يوضح المتحدث أن المشكلة الرئيسية هي حاجة المطورين لتعلم تقنيات معقدة مثل React والتوجيه وأدوات التجميع لبناء واجهات الويب. يدعي مطورو Reflex أن المطورين قاموا ببناء أكثر من مليون تطبيق باستخدامه، كما أن 30% من شركات Fortune 500 تعتمد عليه داخلياً. تم إطلاق أداة Reflex Build مؤخراً، والتي تتيح للمستخدمين برمجة تطبيقات كاملة باستخدام أوامر نصية بسيطة بفضل الذكاء الاصطناعي. كما يتميز الإطار بقدرته على التكامل مع حزم تطوير البرمجيات الشهيرة مثل AWS وStripe وDatabricks. يركز هذا الجزء على القيمة التجارية والتقنية التي يقدمها الإطار للمطورين والشركات الكبرى.

البدء العملي وإعداد مشروع Reflex الأول

ينتقل الفيديو إلى الجانب التطبيقي من خلال إنشاء مشروع تجريبي يسمى ReflexTest في بيئة التطوير. يشرح المتحدث كيفية استخدام أوامر تثبيت المكتبة مثل pip install reflex ثم تهيئة المشروع باستخدام أمر reflex init. يتم عرض خيارات القوالب الجاهزة، ولكن الاختيار يقع على قالب فارغ لتبسيط الشرح وتوضيح بنية الملفات الأساسية. تظهر بنية المشروع أن التطبيق يتركز في ملف بايثون واحد يحتوي على المكونات وفئات الحالة. ينتهي هذا القسم بتشغيل التطبيق على المنفذ 3000 واستعراض الواجهة الأولية في المتصفح لرؤية النتائج الفورية.

إدارة الحالة والتعامل مع الأحداث في بايثون

يركز هذا المقطع على كيفية إدارة الحالة داخل التطبيق من خلال إضافة عداد بسيط ووظيفة لزيادة قيمته. يشرح المتحدث ضرورة استخدام مزخرف RX event لضمان التحقق من أنواع البيانات وصحة المعاملات المستلمة. يتم ربط الزر في الواجهة الأمامية بالدالة البرمجية في الخلفية ليعكس التحديثات مباشرة عند النقر. يبرز الفيديو ميزة التحديث الفوري (Hot Reloading) التي تتيح للمطورين رؤية التغييرات في المتصفح بمجرد حفظ ملف الكود. تعتبر هذه العملية جوهرية لفهم كيف يربط Reflex بين منطق البرمجة وواجهة المستخدم التفاعلية.

وقت التجميع مقابل وقت التشغيل والقيود البرمجية

يناقش المتحدث فرقاً تقنياً حاسماً بين "وقت التجميع" حيث تتحول الواجهة إلى JavaScript و"وقت التشغيل" حيث تعمل بايثون في الخلفية. يكتشف المطور أنه لا يمكن استخدام حلقات for أو جمل if التقليدية من بايثون مباشرة داخل مكونات العرض لأنها غير معروفة وقت التجميع. كحل لهذه المشكلة، يجب استخدام دوال مخصصة من المكتبة مثل Rx.foreach للتكرار وRx.cond للعرض الشرطي. يوضح هذا القسم التحديات التي قد يواجهها المبرمجون عند محاولة تطبيق منطق بايثون الصرف في واجهة المستخدم. يتم تقديم أمثلة عملية لكيفية عرض العناصر وبناء الشروط التفاعلية بناءً على قيم العداد.

جلب البيانات غير المتزامنة وتحديث واجهة المستخدم

يقدم المتحدث مثالاً متقدماً لجلب بيانات من واجهة برمجة تطبيقات (API) خارجية لعرض حقائق عشوائية. يتم استخدام مكتبة HTTPX وعمليات asyncio غير المتزامنة مع كلمة yield لإرسال تحديثات الحالة إلى واجهة المستخدم بشكل تدريجي. يشرح الفيديو كيفية إظهار مؤشر تحميل (Loading Spinner) أثناء جلب البيانات ثم عرض النتيجة النهائية بعد اكتمال العملية. يتم أيضاً استخدام مزخرف خاص لتشغيل عملية الجلب تلقائياً بمجرد تحميل الصفحة في المتصفح. هذا الجزء يوضح قدرة Reflex على التعامل مع المهام المعقدة التي تتطلب اتصالاً بالإنترنت وإدارة حالات متعددة.

التحليل النهائي وخيبة الأمل في البنية التحتية

في الختام، يقوم المتحدث بفحص المجلد المخفي .web ليكتشف أن كل كود بايثون قد تُرجم إلى تطبيق React وVite وTailwind. يعبر المحلل عن خيبة أمله لأن الإطار ليس محركاً أصيلاً لبايثون بل هو مجرد طبقة تجريد إضافية فوق تقنيات JavaScript الحالية. يرى أن هذا يزيد التعقيد لأنه يجبر المطور على تعلم بنية Reflex الخاصة بدلاً من استخدام React مباشرة. يخلص الفيديو إلى أن المتحدث يفضل البقاء مع React للواجهة الأمامية واستخدام بايثون للخلفية فقط بدلاً من الاعتماد الكلي على Reflex. ينهي أندريس الفيديو بطلب رأي المشاهدين حول ما إذا كانوا يفضلون هذا النوع من أطر العمل الشاملة.

Community Posts

View all posts