1. مقدمة

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

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

أهداف الدورة التعليمية
- كيفية كتابة دالة Cloud Function عبر بروتوكول HTTP
- كيفية كتابة دالة Cloud Function عبر بروتوكول HTTP تقبل الوسيطات
- كيفية اختبار دالة Cloud Function عبر بروتوكول HTTP
- كيفية تشغيل خادم HTTP محلي بلغة Python لتجربة الدالة
- كيفية كتابة دالة HTTP Cloud تعرض صورة
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- مقدّمة حول دوال Cloud Functions عبر بروتوكول HTTP
تتم كتابة دوال Cloud Functions عبر بروتوكول HTTP بلغة 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.
لاختبار الدالة، يمكنك النقر على عنوان URL الخاص بـ httpsTrigger.url المعروض في ناتج الأمر أعلاه. يمكنك أيضًا استرداد عنوان URL آليًا واستدعاء الدالة باستخدام الأوامر التالية:
URL=$(gcloud functions describe $FUNCTION_NAME --format "value(httpsTrigger.url)") curl -w "\n" $URL
من المفترض أن تحصل على النتيجة التالية:
Hello World! 👋
4. كتابة دالة Cloud Function عبر بروتوكول HTTP تقبل وسيطات
تكون الدوال أكثر تنوعًا عندما تقبل الوسيطات. لنعرّف دالة جديدة باسم 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- كتابة الاختبارات
يتم اختبار دوال Cloud Functions عبر بروتوكول HTTP بلغة 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. كتابة دالة Cloud Function عبر بروتوكول 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، انقر على الزر "معاينة الويب" واختَر "معاينة على المنفذ 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.