1. مقدمة

بايثون هي لغة برمجة شائعة مفتوحة المصدر يستخدمها علماء البيانات ومطوّرو تطبيقات الويب ومشرفو الأنظمة وغيرهم.
Cloud Functions هي منصة حوسبة بدون خادم مستنِدة إلى الأحداث. تتيح لك Cloud Functions كتابة الرمز بدون القلق بشأن توفير الموارد أو توسيع نطاقها للتعامل مع المتطلبات المتغيرة.
هناك نوعان من Cloud Functions:
- تستجيب دوال HTTP لطلبات HTTP. ستنشئ زوجًا من هذه النماذج في هذا الدرس التطبيقي حول الترميز.
- يتم تشغيل الدوال البرمجية التي تعمل في الخلفية من خلال أحداث، مثل نشر رسالة إلى Cloud Pub/Sub أو تحميل ملف إلى Cloud Storage. لا نتناول هذا الموضوع في هذا المختبر، ولكن يمكنك الاطّلاع على مزيد من المعلومات في المستندات.

سيرشدك هذا الدرس التطبيقي العملي خلال عملية إنشاء دوال Cloud Functions الخاصة بك في Python.
ما ستنشئه
في هذا الدرس التطبيقي حول الترميز، ستنشر Cloud Function تعرض شعار"تعمل بواسطة Python" عند استدعائها عبر HTTP:

أهداف الدورة التعليمية
- كيفية كتابة دالة Cloud Function تستند إلى HTTP
- كيفية كتابة دالة Cloud Function تستخدم HTTP وتقبل وسيطات
- كيفية اختبار دالة Cloud Function تستخدم بروتوكول HTTP
- كيفية تشغيل خادم HTTP محلي في Python لتجربة الدالة
- كيفية كتابة دالة سحابية لبروتوكول نقل الروابط النصية (HTTP) تعرض صورة
2. الإعداد والمتطلبات
إعداد البيئة بوتيرة ذاتية
- سجِّل الدخول إلى Google Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.



- اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديلها في أي وقت.
- رقم تعريف المشروع هو معرّف فريد في جميع مشاريع Google Cloud ولا يمكن تغييره بعد ضبطه. تنشئ Cloud Console تلقائيًا سلسلة فريدة، ولا يهمّك عادةً ما هي. في معظم دروس البرمجة، عليك الرجوع إلى رقم تعريف مشروعك (يُشار إليه عادةً باسم
PROJECT_ID). إذا لم يعجبك المعرّف الذي تم إنشاؤه، يمكنك إنشاء معرّف عشوائي آخر. يمكنك بدلاً من ذلك تجربة اسم مستخدم من اختيارك ومعرفة ما إذا كان متاحًا. لا يمكن تغيير هذا الخيار بعد هذه الخطوة وسيظل ساريًا طوال مدة المشروع. - للعلم، هناك قيمة ثالثة، وهي رقم المشروع، تستخدمها بعض واجهات برمجة التطبيقات. يمكنك الاطّلاع على مزيد من المعلومات عن كل هذه القيم الثلاث في المستندات.
- بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد/واجهات برمجة تطبيقات Cloud. لن تكلفك تجربة هذا الدرس التطبيقي حول الترميز الكثير، إن وُجدت أي تكلفة على الإطلاق. لإيقاف الموارد وتجنُّب تحمّل تكاليف تتجاوز هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع. يمكن لمستخدمي Google Cloud الجدد الاستفادة من برنامج الفترة التجريبية المجانية بقيمة 300 دولار أمريكي.
بدء Cloud Shell
على الرغم من إمكانية تشغيل Google Cloud عن بُعد من الكمبيوتر المحمول، ستستخدم في هذا الدرس العملي Cloud Shell، وهي بيئة سطر أوامر تعمل في السحابة الإلكترونية.
تفعيل Cloud Shell
- من Cloud Console، انقر على تفعيل Cloud Shell
.

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

يستغرق توفير Cloud Shell والاتصال به بضع لحظات فقط.

يتم تحميل هذا الجهاز الافتراضي بجميع أدوات التطوير اللازمة. توفّر هذه الخدمة دليلًا رئيسيًا دائمًا بسعة 5 غيغابايت وتعمل في Google Cloud، ما يؤدي إلى تحسين أداء الشبكة والمصادقة بشكل كبير. يمكن إنجاز معظم عملك في هذا الدرس التطبيقي حول الترميز، إن لم يكن كله، باستخدام متصفح.
بعد الاتصال بـ Cloud Shell، من المفترض أن يظهر لك أنّه تم إثبات هويتك وأنّه تم ضبط المشروع على رقم تعريف مشروعك.
- نفِّذ الأمر التالي في Cloud Shell للتأكّد من إكمال عملية المصادقة:
gcloud auth list
ناتج الأمر
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- نفِّذ الأمر التالي في Cloud Shell للتأكّد من أنّ أمر gcloud يعرف مشروعك:
gcloud config list project
ناتج الأمر
[core] project = <PROJECT_ID>
إذا لم يكن كذلك، يمكنك تعيينه من خلال هذا الأمر:
gcloud config set project <PROJECT_ID>
ناتج الأمر
Updated property [core/project].
التأكّد من تفعيل واجهتَي Cloud Functions وCloud Build API
نفِّذ الأمر التالي من Cloud Shell للتأكّد من تفعيل واجهتَي برمجة التطبيقات Cloud Functions وCloud Build:
gcloud services enable \ cloudfunctions.googleapis.com \ cloudbuild.googleapis.com
ملاحظة: سيتم استدعاء Cloud Build من خلال الأمر gcloud functions deploy، وسيتم إنشاء الرمز تلقائيًا في صورة حاوية.
تنزيل رمز المصدر
من وحدة Cloud Shell الطرفية، شغِّل الأوامر التالية:
REPO_NAME="codelabs" REPO_URL="https://github.com/GoogleCloudPlatform/$REPO_NAME" SOURCE_DIR="cloud-functions-python-http" git clone --no-checkout --filter=blob:none --depth=1 $REPO_URL cd $REPO_NAME git sparse-checkout set $SOURCE_DIR git checkout cd $SOURCE_DIR
اطّلِع على محتوى دليل ملفات المصدر:
ls
يجب أن تتوفّر لديك الملفات التالية:
main.py python-powered.png test_main.py web_app.py
3- نقدّم لك وظائف HTTP السحابية
تتم كتابة دوال HTTP في Cloud Functions بلغة Python كدوال Python عادية. يجب أن تقبل الدالة وسيطة flask.Request واحدة، ويُطلق عليها عادةً اسم request.
main.py
import flask
def hello_world(request: flask.Request) -> flask.Response:
"""HTTP Cloud Function.
Returns:
- "Hello World! 👋"
"""
response = "Hello World! 👋"
return flask.Response(response, mimetype="text/plain")
# ...
يمكنك فتح الملف باستخدام محرّر سطر الأوامر المفضّل لديك (nano أو vim أو emacs). يمكنك أيضًا فتحها في "محرّر Cloud Shell" بعد ضبط دليل ملفات المصدر كمساحة عمل:
cloudshell open-workspace .
لننفّذ هذه الدالة كدالة HTTP Cloud Function باستخدام الأمر gcloud functions deploy:
FUNCTION_NAME="hello_world" gcloud functions deploy $FUNCTION_NAME \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
ناتج الأمر:
... Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 256 ... entryPoint: FUNCTION_NAME httpsTrigger: url: https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME ...
ملاحظات حول خيارات gcloud functions deploy:
-
--runtime: تحدّد هذه السمة وقت تشغيل اللغة. بالنسبة إلى Python، يمكن أن يكون ذلك حاليًاpython37أوpython38أوpython39أوpython310أوpython312. اطّلِع على وقت التشغيل. -
--trigger-http: سيتم تعيين نقطة نهاية للدالة. ستؤدي طلبات HTTP (POST وPUT وGET وDELETE وOPTIONS) إلى نقطة النهاية إلى تشغيل الدالة. -
--allow-unauthenticated: ستكون الدالة عامة، ما يسمح لجميع المتصلين باستخدامها بدون التحقّق من المصادقة. - لمزيد من المعلومات، يُرجى الاطّلاع على gcloud functions deploy.
لاختبار الدالة، يمكنك النقر على عنوان URL httpsTrigger.url المعروض في ناتج الأمر أعلاه. يمكنك أيضًا استرداد عنوان URL بشكل آلي واستدعاء الدالة باستخدام الأوامر التالية:
URL=$(gcloud functions describe $FUNCTION_NAME --format "value(httpsTrigger.url)") curl -w "\n" $URL
من المفترض أن تحصل على النتيجة التالية:
Hello World! 👋
4. كتابة دالة HTTP Cloud تقبل وسيطات
تكون الدوال أكثر تنوعًا عندما تقبل وسيطات. لنعرّف دالة جديدة hello_name تقبل المَعلمة name:
main.py
# ...
def hello_name(request: flask.Request) -> flask.Response:
"""HTTP Cloud Function.
Returns:
- "Hello {NAME}! 🚀" if "name=NAME" is defined in the GET request
- "Hello World! 🚀" otherwise
"""
name = request.args.get("name", "World")
response = f"Hello {name}! 🚀"
return flask.Response(response, mimetype="text/plain")
# ...
لننفّذ هذه الدالة الجديدة:
FUNCTION_NAME="hello_name" gcloud functions deploy $FUNCTION_NAME \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
ناتج الأمر:
... Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 256 ... entryPoint: FUNCTION_NAME httpsTrigger: url: https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME ...
لاختبار الدالة، يمكنك النقر على عنوان URL httpsTrigger.url المعروض في ناتج الأمر أعلاه. يمكنك أيضًا استرداد عنوان URL بشكل آلي واستدعاء الدالة باستخدام الأوامر التالية:
URL=$(gcloud functions describe $FUNCTION_NAME --format "value(httpsTrigger.url)") curl -w "\n" $URL
من المفترض أن تظهر لك النتيجة التلقائية:
Hello World! 🚀
تظهر لك النتيجة التلقائية لأنّ الوسيطة name لم يتم ضبطها. أضِف مَعلمة إلى عنوان URL:
curl -w "\n" $URL?name=YOUR%20NAME
في هذه المرة، ستحصل على الردّ المخصّص:
Hello YOUR NAME! 🚀
الخطوة التالية هي إضافة اختبارات الوحدات لضمان استمرار عمل وظائفك على النحو المنشود عند تعديل الرمز المصدر.
5- اختبارات الكتابة
يتم اختبار دوال HTTP Cloud Functions في Python باستخدام الوحدة unittest من المكتبة العادية. ليس عليك تشغيل محاكي أو أي محاكاة أخرى لاختبار وظيفتك، بل يمكنك استخدام رمز Python العادي.
في ما يلي مثال على اختبار الدالتَين hello_world وhello_name:
test_main.py
import unittest
import unittest.mock
import main
class TestHello(unittest.TestCase):
def test_hello_world(self):
request = unittest.mock.Mock()
response = main.hello_world(request)
assert response.status_code == 200
assert response.get_data(as_text=True) == "Hello World! 👋"
def test_hello_name_no_name(self):
request = unittest.mock.Mock(args={})
response = main.hello_name(request)
assert response.status_code == 200
assert response.get_data(as_text=True) == "Hello World! 🚀"
def test_hello_name_with_name(self):
name = "FirstName LastName"
request = unittest.mock.Mock(args={"name": name})
response = main.hello_name(request)
assert response.status_code == 200
assert response.get_data(as_text=True) == f"Hello {name}! 🚀"
- تتم كتابة اختبارات Python بالطريقة نفسها التي تتم بها كتابة ملفات Python الأخرى. تبدأ بمجموعة من عمليات الاستيراد، ثم تحدّد الفئات والدوال.
- يكون بيان الاختبار بالتنسيق
class TestHello(TestCase). يجب أن يكون صفًا موروثًا منunittest.TestCase. - تحتوي فئة الاختبار على طرق، يجب أن يبدأ كل منها بـ
test_، والتي تمثّل حالات اختبار فردية. - يختبر كل سيناريو اختبار إحدى دوالنا من خلال محاكاة المَعلمة
request(أي استبدالها بكائن مزيّف يتضمّن البيانات المحدّدة المطلوبة للاختبار). - بعد استدعاء كل دالة، يتحقّق الاختبار من استجابة HTTP للتأكّد من أنّها كانت على النحو المتوقّع.
بما أنّ main.py يعتمد على flask، تأكَّد من تثبيت إطار عمل Flask في بيئة الاختبار:
pip install flask
يؤدي تثبيت Flask إلى ظهور نتيجة مشابهة لما يلي:
Collecting flask ... Successfully installed ... flask-3.0.2 ...
نفِّذ الاختبارات التالية محليًا:
python -m unittest
يجب أن تجتاز اختبارات الوحدات الثلاثة ما يلي:
... ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK
بعد ذلك، ستنشئ دالة جديدة تعرض شعار "Python Powered".
6. كتابة "دالة السحابة الإلكترونية المستندة إلى HTTP" بلغة Python
لننشئ دالة جديدة أكثر تسلية من خلال عرض صورة "Python Powered" لكل طلب:

تعرض القائمة التالية الرمز البرمجي اللازم لتنفيذ ذلك:
main.py
# ...
def python_powered(request: flask.Request) -> flask.Response:
"""HTTP Cloud Function.
Returns:
- The official "Python Powered" logo
"""
return flask.send_file("python-powered.png")
نشر دالة python_powered جديدة:
FUNCTION_NAME="python_powered" gcloud functions deploy $FUNCTION_NAME \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
ناتج الأمر:
... Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 256 ... entryPoint: FUNCTION_NAME httpsTrigger: url: https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME ...
لاختبار الدالة، انقر على عنوان URL httpsTrigger.url المعروض في ناتج الأمر أعلاه. إذا كان كل شيء يعمل بشكل صحيح، سيظهر لك شعار "Python Powered" في علامة تبويب متصفّح جديدة!
بعد ذلك، ستنشئ تطبيقًا لتتمكّن من تشغيل وظيفتك وتجربتها محليًا قبل نشرها.
7. تشغيل الدالة محليًا
يمكنك تشغيل دالة HTTP محليًا من خلال إنشاء تطبيق ويب واستدعاء الدالة في مسار. يمكنك إضافته في الدليل نفسه الذي توجد فيه الدالة. يحتوي الملف الذي يحمل الاسم web_app.py على المحتوى التالي:
web_app.py
import flask
import main
app = flask.Flask(__name__)
@app.get("/")
def index():
return main.python_powered(flask.request)
if __name__ == "__main__":
# Local development only
# Run "python web_app.py" and open http://localhost:8080
app.run(host="localhost", port=8080, debug=True)
- ينشئ هذا الملف تطبيق Flask.
- تسجّل هذه الدالة مسارًا في عنوان URL الأساسي يتم التعامل معه باستخدام دالة باسم
index(). - تستدعي الدالة
index()بعد ذلك الدالةpython_powered، وتمرّر إليها الطلب الحالي.
تأكَّد من تثبيت إطار عمل Flask في بيئة التطوير:
pip install flask
يؤدي تثبيت Flask إلى ظهور نتيجة مشابهة لما يلي:
Collecting flask ... Successfully installed ... flask-3.0.2 ...
لتشغيل هذا التطبيق محليًا، نفِّذ الأمر التالي:
python web_app.py
الآن، استخدِم "معاينة الويب" في Cloud Shell لاختبار تطبيق الويب في متصفّحك. في Cloud Shell، انقر على الزر "معاينة الويب" (Web Preview) واختَر "معاينة على المنفذ 8080" (Preview on port 8080):

يفتح Cloud Shell عنوان URL الخاص بالمعاينة على خدمة الخادم الوكيل في نافذة متصفّح جديدة. تقتصر إمكانية الوصول إلى معاينة الويب عبر HTTPS على حسابك فقط. إذا كان كل شيء يعمل بشكل صحيح، من المفترض أن يظهر لك شعار "Python Powered".

8. تهانينا!

لقد نشرت دوال HTTP Cloud Functions، باستخدام دوال اصطلاحية تعالج طلبات الويب باستخدام إطار عمل Flask.
تستند أسعار Cloud Functions إلى عدد المرات التي يتم فيها استدعاء الدالة، بما في ذلك فئة مجانية للدوال التي لا يتم تشغيلها بشكل متكرر. بعد الانتهاء من اختبار وظائف Cloud Functions، يمكنك حذفها باستخدام gcloud:
gcloud functions delete hello_world --quiet gcloud functions delete hello_name --quiet gcloud functions delete python_powered --quiet
يمكنك أيضًا حذف الدوال من وحدة تحكّم Google Cloud.
نتمنى لك الاستفادة من استخدام Cloud Functions في Python.