اذهب إلى المحتوى

تعلم بناء موقعك الإلكتروني الأول باستخدام إطار عمل فلاسك Flask بلغة بايثون


محمد الخضور

يُعد فلاسك إطار عمل للويب مبني بلغة بايثون، ويتميز بكونه صغير الحجم وسهل المعالجة، ويوفّر أيضًا عدة أدوات وميزات من شأنها جعل إنشاء تطبيقات الويب في لغة بايثون أسهل، مانحًا المطورين مرونةً في العمل، كما أنّه أبسط للاستخدام من قِبل المطورين المبتدئين نظرًا لإمكانية إنشاء تطبيق ويب كامل بسرعة باستخدام ملفٍ وحيدٍ مكتوب بلغة بايثون. إضافةً لما سبق، يتميز فلاسك بكونه قابلًا للتوسّع والوراثة دون أن يفرض أي بنية هرمية لطريقة عرض الملفات، كما أنّه لا يتطلب أي شيفرات برمجية معقدّة استهلالية قبل البدء باستخدامه.

سيمكِّننا تعلُّم فلاسك من إنشاء تطبيقات ويب بسهولة وسرعة باستخدام لغة بايثون، إذ سنستخدم مكتبات بايثون لإضفاء ميزات إضافية على تطبيق الويب، مثل تخزين البيانات في قواعد البيانات والتحقق من بيانات نماذج الإدخال في الويب.

سنبني في هذا المقال تطبيق ويب صغير يعمل على تصيّير النصوص المكتوبة بلغة HTML ضمن المتصفح، إذ سنثبّت فلاسك، ثمّ سنكتب الشيفرة البرمجية الخاصّة بتطبيق فلاسك ونشغّله في وضع التطوير، وسنستخدم مفهوم التوجيه للتنقّل بين عدة صفحات ويب تؤدي وظائف مختلفة ضمن التطبيق؛ كما سنسمح للمستخدمين من خلال دوال فلاسك بالتفاعل مع التطبيق عبر وجهات routes ديناميكية، ونهايةً سنعمل على حل المشكلات الناتجة عن أي أخطاء باستخدام مُنقّح الأخطاء.

مستلزمات العمل

قبل المتابعة في هذا المقال لا بُدّ من:

  • توفُّر بيئة برمجة بايثون 3 محلية، مثبّتة على حاسوبك، وسنفترض في مقالنا أن اسم مجلد المشروع هو "flask_app".
  • فهم مبادئ بايثون 3، مثل أنماط البيانات والقوائم والدوال، وغيرها من المفاهيم المشابهة في بايثون 3.
  • فهم أساسيات لغة HTML.

الخطوة الأولى – تثبيت فلاسك

سنفعّل في هذه الخطوة بيئة بايثون ونثبّت فلاسك باستخدام مثبِّت الحزم "pip".

بدايةً، سنفعّل بيئة البرمجة في حال كانت غير مفعّلةٍ بعد كما يلي:

$ source env/bin/activate

بعدها نثبّت فلاسك باستخدام الأمر pip install:

(env)user@localhost:$ pip install flask

وحالما ينتهي التثبيت، سيظهر الخرج مُتضمنًا مجموعة الحزم المُثبّتة كما يلي:

...
Installing collected packages: Werkzeug, MarkupSafe, Jinja2, itsdangerous, click, flask
Successfully installed Jinja2-3.0.1 MarkupSafe-2.0.1 Werkzeug-2.0.1 click-8.0.1 flask-2.0.1 itsdangerous-2.0.1

ومنه نلاحظ أنّه أثناء تثبيت فلاسك تُثبّت أيضًا عدة حزم ومستلزمات خاصة يستخدمها فلاسك في تنفيذ العديد من الدوال المختلفة.

ومع نهاية هذه الخطوة نكون قد أنشأنا مجلد للتطبيق وفعّلنا البيئة الافتراضية وثبّتنا فلاسك، وبذلك نكون مستعدين للانتقال إلى الخطوة التالية المُتمثّلة بإنشاء تطبيق بسيط.

الخطوة الثانية – إنشاء تطبيق بسيط

يمكننا الآن البدء باستخدام فلاسك بعدما أصبحت البيئة البرمجية جاهزة، إذ سننشئ في هذه الخطوة تطبيق ويب مُصغّر باستخدام فلاسك وذلك ضمن ملف بايثون، الذي سنكتب فيه أيضًا شيفرات HTML لإظهارها عند التشغيل ضمن المتصفح.

الآن، سنفتح الملف المسمى "app.py" الموجود ضمن المجلد "flask_app" بهدف التعديل عليه وذلك باستخدام محرر النصوص نانو nano، أو أي محرّر آخر تفضّله:

(env)user@localhost:$ nano app.py

ونكتب الشيفرة التالية ضمن الملف app.py:

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return '<h1>Hello, World!</h1>'

نحفظ الملف ونغلقه. استوردنا في الجزء السابق من الشيفرة كائن فلاسك من حزمة فلاسك، ثم استخدمناه لإنشاء نسخةٍ instance فعليةٍ موجودةٍ في الذاكرة لتطبيق فلاسك Flask application instance باسم app، وليست مجرد كائن برمجي، ثمّ مررنا المتغير الخاص __name__، الذي سيخزّن اسم وحدة بايثون الحالية ليُعلم تطبيق فلاسك بمكان وجود هذه الوحدة، إذ لا بُدّ من إجراء هذه الخطوة كون فلاسك يهيّئ بعض المسارات اللازمة في الخلفية. وبمجرد إنشاء هذا التطبيق "app"، يمكنك استخدامه في معالجة طلبات الويب القادمة وإرسال الردود إلى المُستخدم.

يكون المزخرف app.route@ مسؤولًا عن تعديل دوال بايثون المألوفة لتصبح دوال عرض view في فلاسك، والتي تحوّل القيمة المُعادة من قِبل الدالة إلى استجابةٍ من نوع HTTP تُعرض لدى عميل HTTP، الذي قد يكون متصفحًا مثلًا؛ فبمجرد تمرير "/" للدالة ()app.route@، سينشئ الردود على طلبات الويب الواردة إلى الرابط "/"، والذي يمثّل الرابط الرئيسي في التطبيق، وبذلك ستعيد الدالة ()hello السلسلة النصية "!Hello, World" ردًا على الطلب.

وبذلك أصبح لدينا تطبيق فلاسك بسيط موجود ضمن ملف بايثون المُسمّى "app.py"، سنشغّل فيما يلي هذا التطبيق لتصيير نتيجة دالة العرض ()hello ضمن متصفح ويب.

الخطوة الثالثة – تشغيل التطبيق

بعد إنشائنا الملف الذي يحتوي على تطبيق فلاسك، سنشغّله باستخدام واجهة أوامر فلاسك وذلك لتشغيل خادم التطوير وتصيير شيفرة HTML ضمن المتصفح والتي كتبناها لتكون القيمة المعادة من الدالة ()hello في الخطوة السابقة.

ولتشغيل تطبيق الويب الذي أنشأناه، وبعد التأكّد من وجودنا ضمن المجلد "flask_app" مع تفعيل البيئة الافتراضية، لا بُدّ من إرشاد فلاسك إلى موقع التطبيق (في حالتنا الملف ذو الاسم "app.py") وذلك باستخدام متغير بيئة فلاسك FLASK_APP على النحو التالي (مع ملاحظة أنّنا نستخدم الأمر set في بيئة ويندوز عوضًا عن الأمر export):

(env)user@localhost:$ export FLASK_APP=app

ثم نحدد وضع تشغيل التطبيق ليكون بوضع التطوير، وذلك باستخدام متغير بيئة فلاسك Flask_ENV على النحو التالي:

(env)user@localhost:$ export FLASK_ENV=development

وبذلك نتمكّن من استخدام المنقّح لالتقاط الأخطاء.

نهايةً، نشغّل التطبيق باستخدام الأمر flask run:

(env)user@localhost:$ flask run

حالما يعمل التطبيق، يظهر الخرج على النحو التالي:

 * Serving Flask app "app" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 296-353-699

يحتوي الخرج السابق على عدة معلومات، مثل:

  • اسم التطبيق المُشغَّل.
  • بيئة التشغيل الحالية التي يعمل عليها التطبيق.
  • عبارة Debug mode:on التي تشير إلى أن مُنقّح أخطاء فلاسك قيد التشغيل، وهو ذو فوائد عديدة أثناء عملية التطوير كونه يقدم رسائل خطأ مفصّلة عندما يحدث أي خلل، وهذا ما يجعل عملية تنقيح الأخطاء أسهل وأيسر.
  • التطبيق يعمل على الحاسب المحلي وذلك على الرابط /http://127.0.0.1:5000، إذ أن "127.0.0.1" هو عنوان IP الذي يمثِّل الخادم المحلي localhost على حاسبك، و "5000:" هو رقم المنفذ.

افتح المتصفح واكتب عنوان URL التالي "/http://127.0.0.1:5000"، ستظهر عبارة "!Hello, World" (ضمن تنسيق عنوان من المستوى الأوّل <h1>) استجابةً لهذا العنوان، وهذا ما يؤكد أن التطبيق يعمل بنجاح.

First Hello world.png

وإذا أردنا إيقاف خادم التطوير، نضغط على "CTRL+C".

تنبيه: يستخدم فلاسك خادم ويب مبسّط لاستضافة تطبيق الويب في بيئة التطوير، ما يعني أن مُنقّح أخطاء فلاسك قيد التشغيل أيضًا كي يجعل التقاط الأخطاء أسهل، ولا ينبغي استخدام خادم التطوير هذا عندما يُنقل التطبيق إلى مرحلة التشغيل الفعلي أي نشر المنتج.

يمكن في هذه المرحلة الإبقاء على خادم التطوير قيد التشغيل في الطرفية terminal الخاصة به، ومن ثم فتح نافذة طرفية جديدة وتغيير المسار فيها إلى مسار مجلد المشروع حيث يتواجد ملف "hello.py"، ثم بعد ذلك تفعيل البيئة الافتراضية (السبب مبيّنٌ في الملاحظة أدناه)، وتهيّئة متغيرات البيئة FLASK_ENV و FLASK_APP، ومتابعة الخطوات التالية. (ذُكرت هذه الأوامر سابقًا في هذه الخطوة).

ملاحظة: من الضروري تفعيل البيئة الافتراضية لدى فتح طرفية جديدة، أو إغلاق الطرفية الحالية التي تشغّل خادم التطوير عليها وتود إعادة تشغيله، ولا بدّ من إعداد متغيرات البيئة FLASK_ENV و FLASK_APP ليعمل الأمر flask run بصورةٍ صحيحة.

كل ما عليك فعله هو تشغيل الخادم مرةً واحدةً في نافذة طرفية واحدة.

لا يمكن تشغيل تطبيق فلاسك آخر باستخدام الأمر flask run نفسه خلال فترة عمل خادم تطوير تطبيقات فلاسك، كونه يستخدم المنفذ رقم 5000 افتراضيًا، وحالما يُحجَز هذا المنفذ يصبح غير متاحًا لتشغيل أي تطبيقٍ آخر، وفي حال فعلت ذلك ستظهر رسالة خطأ مشابهةٍ لما يلي:

OSError: [Errno 98] Address already in use

ويمكن حل لهذه المشكلة، إمّا بإيقاف الخادم العامل حاليًا عن طريق الضغط على "CTRL+C" ومن ثم تنفيذ الأمر flask run مجدّدًا، أو في حال رغبتك بتشغيل كلا التطبيقين في نفس الوقت، فمن الممكن تمرير رقم منفذٍ مختلف باستخدام الوسيط p-.

سنستخدم الأمر التالي لتشغيل تطبيقٍ آخر يستخدم المنفذ "5001" مثالًا حول طريقة الحل هذه:

(env)user@localhost:$ flask run -p 5001

وبذلك يصبح لدينا تطبيق أوّل يعمل على الرايط "/http://172.0.0.1:5000" وآخر يعمل على الرابط "/http://172.0.0.1:5001" إن احتجنا لذلك.

وبذلك يكون قد أصبح لدينا مع نهاية هذه الخطوة تطبيق ويب صغير باستخدام فلاسك، وبعد أن شغّلنا وعرضنا المعلومات في متصفح الويب، سنتعلم فيما يلي كيفية إنشاء وجهات واستخدامها لتخديم عدّة صفحات ويب.

الخطوة الرابعة – الوجهات ودوال العرض في فلاسك

سنضيف في هذه الخطوة بضع وجهات للتطبيق لإظهار صفحات مختلفة اعتمادًا على الرابط المطلوب، وسنتعرف أيضًا على دوال العرض في فلاسك وكيفية استخدامها.

تُعرّف الوجهة route بأنها رابطٌ يُستخدم لتحديد ما سيستقبله المستخدم لدى زيارة تطبيق الويب على متصفحه، فمثلًا يشير الرابط "/http://127.0.0.1:5000" إلى الوجهة الرئيسية التي يمكن استخدامها لعرض الصفحة الرئيسية للتطبيق، بينما يشير الرابط "http://127.0.0.1:5000/about" إلى وجهةٍ أخرى وهو صفحة المعلومات التي تعطي الزوار معلومات حول تطبيق الويب، وعلى نحوٍ مشابه يمكن إنشاء وجهة تسمح للمستخدمين بتسجيل الدخول إلى تطبيق الويب عبر الرابط "http://127.0.0.1:5000/login" مثلًا.

يستخدم تطبيق فلاسك الذي أنشأناه حاليًا وجهةً واحدةً تخدّم الزوار الذين يطلبون الرابط الرئيسي "/http://127.0.0.1:5000". الآن، ولنبين كيفية إضافة صفحة ويب جديدة إلى تطبيقنا، سنعدّل ملف التطبيق لإضافة وجهةٍ جديدة تؤمن معلومات حول التطبيق عبر الرابط "http://127.0.0.1:5000/about".

لذا سنفتح الملف "app.py" من أجل التعديل:

(env)user@localhost:$ nano app.py

ثمّ نعدّل الملف من خلال إضافة الشيفرة التالية:

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return '<h1>Hello, World!</h1>'


@app.route('/about/')
def about():
    return '<h3>This is a Flask web application.</h3>'

نحفظ الملف ونغلقه.

أضفنا في الشيفرة السابقة دالةً جديدةً باسم ()about، والتي صمّمناها باستخدام المًزخرف ()app.route@، الذي يحوّلها إلى دالة عرض قادرة على التعامل مع الطلبات الواردة إلى الرابط "http://127.0.0.1:5000/about".

بعد التأكد من كون خادم التطوير ما يزال قيد التشغيل، نزور الرابط التالي في المتصفح:

http://127.0.0.1:5000/about

فيظهر النص "This is a Flask web application" مصّيرًا ضمن تنسيق عنوان من المستوى الثالث <h3> في HTML؛ كما من الممكن استخدام عدّة وجهات في دالة فلاسك الواحدة، فمثلًا من الممكن تخديم الصفحة الرئيسية للتطبيق بكل من الوجهتين "/" و "/index/"، ولتنفيذ ذلك سنفتح الملف "app.py" لتعديله:

(env)user@localhost:$ nano app.py

سنعدّل الملف بإضافة مُزخرف آخر إلى دالة فلاسك ()hello:

from flask import Flask

app = Flask(__name__)

@app.route('/')
@app.route('/index/')
def hello():
    return '<h1>Hello, World!</h1>'

@app.route('/about/')
def about():
    return '<h3>This is a Flask web application.</h3>'

نحفظ الملف ونغلقه.

وبعد إضافة المُزخرف الثاني أصبح بالإمكان الوصول إلى الصفحة الرئيسية للتطبيق من خلال أي من الرابطين "/http://127.0.0.1:5000" أو "http://127.0.0.1:5000/index".

تعرّفنا فيما سبق على الوجهات وكيفية استخدامها لإنشاء دوال عرض في فلاسك وكيفية إضافة وجهات جديدة إلى التطبيق. فيما يلي سنستخدم الوجهات الديناميكية المرنة للسماح للمستخدمين بالتحكم باستجابة التطبيق.

الخطوة الخامسة - الوجهات الديناميكية

سنستخدم في هذه الخطوة الوجهات الديناميكية لنمكّن المستخدمين من التفاعل مع التطبيق، إذ سننشئ وجهةً تجعل الكلمات المُمرّرة عبر الرابط مكتوبةً بأحرف كبيرة، كما سننشئ وجهةً تجمع رقمين مع بعضهما وتظهر النتيجة.

لا يتفاعل المستخدمون عادةً مع تطبيق الويب من خلال التعديل اليدوي للرابط، بل يتفاعلون مع عناصر موجودة في الصفحة تؤدي إلى روابط مختلفة بناءً على مدخلاتهم وتصرفاتهم ضمن الصفحة، ولكن وبهدف التبسيط في هذا المقال، سنعدّل الرابط لنبيّن كيفية جعل التطبيق يستجيب بصورةٍ مختلفة بروابط مختلفة.

سنفتح بدايةً الملف app.py لتعديله:

(env)user@localhost:$ nano app.py

مع ملاحظة انّه إذا سمحنا للمستخدم بإدخال شيءٍ ما إلى التطبيق، مثل إدخال قيمة في الرابط كما سنفعل في التعديل التالي، فيجب الانتباه إلى أنّ التطبيق يجب ألا يُظهر بيانات غير موثوقة (البيانات التي أدخلها المستخدم)، ولكي نعرض بيانات المستخدم بصورةٍ آمنة، سنستخدم الدالة "()escape" الموجودة ضمن حزمة البناء الآمن "markupsafe" المُثبتة بالتوازي مع تثبيت فلاسك.

الأن، سنعدّل الملف "app.py" بإضافة السطر التالي في بدايته أعلى أمر استيراد Flask كما يلي:

from markupsafe import escape
from flask import Flask

# ...

ثمّ سنضيف الوجهة التالية إلى نهاية الملف:

# ...

@app.route('/capitalize/<word>/')
def capitalize(word):
    return '<h1>{}</h1>'.format(escape(word.capitalize()))

نحفظ الملف ونغلقه.

تملك الوجهة الجديدة قسمًا متغيرًا مُضمّنًا في الوسم <word>، والذي يسمح لفلاسك بأخذ القيمة المُدخلة من الرابط وتمريرها إلى دالة فلاسك، إذ يُمرّر متغير الرابط <word> الكلمة مثل وسيط إلى دالة فلاسك ()capitalize. وفي حالتنا فإنّ الوسيط هذا يملك نفس اسم متغير الرابط (وهو word في حالتنا)، وبذلك يمكننا الوصول إلى الكلمة المُمررة عبر الرابط وإنشاء استجابة بنفس الكلمة المُمررة ولكن بأحرف كبيرة وذلك باستخدام دالة العرض ()capitalize العاملة أصلًا في بايثون.

استخدمنا الدالة ()escape التي استوردناها سابقًا لتصيير السلسلة التي أدخلها المُستخدم والموجودة ضمن المتغير word مثل نص وليس شيفرةً للتنفيذ، وهو أمر بالغ الأهمية لتجنب هجمات البرمجة العابرة للمواقع XSS، ففي حال إدخال المستخدم شيفرة JavaScript خبيثة بدلًا من السلسلة النصية، تصيّرها الدالة ()escape على أنها نص عادي وبذلك لن ينفّذها المتصفح، ما يبقي تطبيق الويب آمنًا.

ولعرض الكلمات بأحرف كبيرة ضمن تنسيق عنوان من المستوى الأوّل <h1> في HTML استخدمنا الدالة ()format من دوال بايثون.

الآن وبعد التأكد من أنّ خادم التطوير ما يزال قيد التشغيل، نفتح المتصفح ونذهب إلى الروابط التالية، مع إمكانية تبديل الكلمات "hello" و "flask" و "python" التي تنتهي الروابط بها في مثالنا بأي كلمة تريد:

http://127.0.0.1:5000/capitalize/hello
http://127.0.0.1:5000/capitalize/flask
http://127.0.0.1:5000/capitalize/python

وبذلك تظهر الكلمة ضمن المتصفح بأحرف كبيرة وبتنسيق عنوان من المستوى الأول <h1>.

كما يمكننا استخدام عدّة متغيرات في الوجهة، ولتوضيح ذلك سنضيف وجهةً جديدةً لجمع رقمين صحيحين ويعرض النتيجة.

لذا سنفتح الملف "app.py" لتعديله:

(env)user@localhost:$ nano app.py

ثمّ نضيف الوجهة التالية إلى نهاية الملف:

# ...

@app.route('/add/<int:n1>/<int:n2>/')
def add(n1, n2):
    return '<h1>{}</h1>'.format(n1 + n2)

نحفظ الملف ونغلقه.

نستخدم في هذه الوجهة المحوّل الخاص int مع المتغير الخاص بالرابط (/add/<int:n1>/<int:n2>‎/)؛ ومهمّة هذا المحوّل هي قبول القيم التي تُمثّل أعدادًا صحيحة موجبة فقط والتعامل معها على أنها أعداد، كونه افتراضيًا تُعدّ المتغيرات الآتية من الرابط سلاسلًا محرفية ويجري التعامل معها على هذا الأساس، وهذا أمرٌ غير مناسب لإتمام عملية الجمع العددي.

الآن وبعد التأكد من أنّ خادم التطوير ما يزال قيد التشغيل، نفتح المتصفح ونذهب إلى الرابط التالي:

http://127.0.0.1:5000/add/5/5/

وستكون النتيجة مجموع الرقمين (وهي "10" في حالة مثالنا هذا).

تعرفنا في هذه الخطوة على كيفية استخدام الوجهات الديناميكية لعرض استجابات مُختلفة ضمن الوجهة الواحدة اعتمادًا على الرابط المطلوب، وهذا ما يعزز التجربة التفاعلية للمُستخدم.

سنتعرّف في الخطوة التالية على آليات تنقيح وتصحيح الأخطاء في تطبيق فلاسك في حال حدوثها.

الخطوة السادسة - تنقيح أخطاء تطبيق فلاسك

خلال مراحل تطوير أي تطبيق ويب، من الطبيعي أن نمر بحالات نحصل فيها على أخطاء لدى تشغيل التطبيق عوضًا عن النتيجة المتوقعة، والتي قد تكون ناتجةً مثلًا عن خطأ إملائي بسيط في كتابة اسم أحد المتغيرات أو نتيجة نسيان التصريح عن أو استيراد إحدى الدوال؛ ولإصلاح هذه الأخطاء بسهولة يوفّر فلاسك منقّح أخطاء يعمل لدى تشغيل التطبيق في وضع التطوير، إذ سنتعلّم في هذه الخطوة آلية تصحيح أخطاء التطبيق بالاعتماد على مُنقّح الأخطاء في فلاسك.

لتوضيح كيفية التعامل مع الأخطاء في حال ظهورها، سننشئ وجهةً للترحيب بمستخدم ما من قائمة أسماء مستخدمين موجودة.

لذا سنفتح الملف "app.py" للتعديل عليه:

(env)user@localhost:$ nano app.py

ونضيف الوجهة التالية إلى نهاية الملف:

# ...

@app.route('/users/<int:user_id>/')
def greet_user(user_id):
    users = ['Ahmad', 'Mohammad', 'Adam']
    return '<h2>Hi {}</h2>'.format(users[user_id])

نحفظ الملف ونغلقه.

تستقبل دالة فلاسك ()greet_user في الوجهة السابقة متغير الرابط user_id مثل قيمة للوسيط user_id، إذ استخدمنا المحوّل الخاص int لقبول أعداد صحيحة موجبة فقط، حيث تتضمّن الدالة قائمةً مبنيةً في بايثون باسم users تحتوي على ثلاث سلاسل نصية تمثّل أسماء المستخدمين، وترجع دالة فلاسك السلسة الموافقة من القائمة اعتمادًا على قيمة المتغير user_id المُمرّر والذي يدل على رقم المُستخدم المراد الترحيب به بالنتيجة؛ فإذا كانت قيمة المتغير user_id تساوي "0" مثلًا، ستكون الاستجابة ظهور عبارة "Hi Ahmad" ضمن تنسيق عنوان من المستوى الثاني <h2> لأن Ahmad هو أول عنصر في القائمة المُقابل للقيمة "[user[0".

الآن وبعد التأكد أن خادم التطوير ما يزال قيد التشغيل، سنفتح المتصفح لزيارة الروابط التالية:

http://127.0.0.1:5000/users/0
http://127.0.0.1:5000/users/1
http://127.0.0.1:5000/users/2

فتكون النتيجة على النحو التالي:

Hi Ahmad
Hi Mohammad
Hi Adam

نلاحظ أنّ الأمور تجري على خير ما يرام حتى الآن، ولكن ماذا لو طلبنا الترحيب بمستخدم غير موجود؟ سيظهر خطأ بالتأكيد، ولتوضيح كيفية عمل مُنقّح الأخطاء في فلاسك سنزور الرابط التالي:

http://127.0.0.1:5000/users/3

فتظهر صفحةٌ كما في الصورة أدناه:

second index error.png

نلاحظ أنّ اسم الخطأ الحاصل في بايثون وهو IndexError في حالتنا يُعرض في أعلى الصفحة، ويشير هذا الخطأ إلى وقوع دليل القائمة ("3" في مثالنا) خارج المجال، إذ أن المجال في حالتنا محصورٌ بين "0" و "2" لأنّ القائمة مكونةٌ من ثلاثة عناصر، كما يظهر في مُنقح الأخطاء جميع أسطر الشيفرة التي أدّى تنفيذها إلى ظهور هذا الخطأ.

وعادةً ما يتضمّن آخر سطرين من متتبّع الأخطاء مصدر الخطأ، وفي حالتنا سيبدوان على نحو مشابه لما يلي:

File "/home/USER/flask_app/app.py", line 28, in greet_user
    return '<h2>Hi {}</h2>'.format(users[user_id])

ما يشير إلى أنّ الخطأ ناتج عن دالة الترحيب ()greet_user ضمن الملف "app.py" وتحديدًا في السطر الحاوي غلى القيمة المُعادة return، ومع معرفتنا للسطر الذي تسبّب بالخطأ يصبح تحديد المشكلة وحلها أسهل.

كما يمكننا لتجنّب توقّف عمل التطبيق في حالات مشابهة لهذه الحالة استخدام العبارة "try…except" لإصلاح الخطأ، بحيث إذا احتوى الرابط المطلوب على دليل خارج مجال القائمة يتلقى المستخدم عبارة خطأ "404 Not Found"، وهو خطأ HTTP يشير للمستخدم أن الصفحة التي يطلبها غير متوفرة.

لذا سنفتح الملف "app.py" للتعديل عليه:

(env)user@localhost:$ nano app.py

وحتى تحدث الاستجابة بخطأ من النوع HTTP 404 سنستخدم دالة فلاسك ()abort التي يمكن استخدامها لانشاء استجابات مكونة من أخطاء HTTP، لذا سنغير السطر الثاني في الملف ليصبح كما يلي:

from markupsafe import escape
from flask import Flask, abort

ثمّ سنعدّل الدالة ()greet_user لتصبح كما يلي:

# ...

@app.route('/users/<int:user_id>/')
def greet_user(user_id):
    users = ['Ahmad', 'Mohammad', 'Adam']
    try:
        return '<h2>Hi {}</h2>'.format(users[user_id])
    except IndexError:
        abort(404)

استخدمنا try لاختبار التعبير return والتأكّد من خلوه من الأخطاء، فإذا لم يكن هناك خطأ، بمعنى أنّ قيمة المتغير user_id المُمرّرة صحيحةٌ ومن ضمن مجال قائمة users، فسيستجيب التطبيق بالترحيب المناسب، وإلّا وفي حال كون قيمة user_id خارج مجال القائمة، سيُفعَّل الاستثناء IndexError، ونستخدم الأمر except للتعامل مع الخطأ وبالتالي الاستجابة بخطأ من نوع HTTP 404 باستخدام دالة فلاسك المساعدة ()abort.

الآن وبعد التأكد من كون خادم التطوير قيد التشغيل، نزور الرابط مجددًا مع تمرير القيمة 3 لرقم المُستخدم المطلوب:

http://127.0.0.1:5000/users/3

فتظهر في هذه الحالة صفحة الخطأ 404 التقليدية لتشير للمستخدم أن الصفحة المطلوبة غير موجودة.

ومع نهاية تطبيق الخطوات الواردة في هذا المقال، سيبدو الملف "app.py" على النحو التالي:

from markupsafe import escape
from flask import Flask, abort

app = Flask(__name__)


@app.route('/')
@app.route('/index/')
def hello():
    return '<h1>Hello, World!</h1>'


@app.route('/about/')
def about():
    return '<h3>This is a Flask web application.</h3>'

@app.route('/capitalize/<word>/')
def capitalize(word):
    return '<h1>{}</h1>'.format(escape(word.capitalize()))

@app.route('/add/<int:n1>/<int:n2>/')
def add(n1, n2):
    return '<h1>{}</h1>'.format(n1 + n2)

@app.route('/users/<int:user_id>/')
def greet_user(user_id):
    users = ['Ahmad', 'Mohammad', 'Adam']
    try:
        return '<h2>Hi {}</h2>'.format(users[user_id])
    except IndexError:
        abort(404)

وبذلك أصبح لديك تصوّر عام عن كيفية استخدام مُنقّح الأخطاء في فلاسك لالتقاط الأخطاء وتحديد الآلية المُثلى لإصلاحها والتعامل معها.

الخاتمة

تعرفنا في هذا المقال بصورة عامة على فلاسك وكيفية تثبيته واستخدامه لإنشاء تطبيق ويب، كما تعرفنا على آلية تشغيل خادم التطوير واستخدام الوجهات ودوال فلاسك لعرض صفحات ويب مختلفة تخدّم وظائفًا محددة، كما تعلمنا كيفية استخدام الوجهات الديناميكية للسماح للمستخدم بالتفاعل مع تطبيق ويب عن طريق تعديل الرابط المطلوب، وفي النهاية تعلمنا كيفية استخدام مُنقّح الأخطاء لتحديد المشاكل.

ترجمة -وبتصرف- للمقال How To Create Your First Web Application Using Flask and Python3 لصاحبه Abdelhadi Dyouri.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...