نشر تطبيق ويب Python Flask في بيئة App Engine المرنة

ملخّص

في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية نشر تطبيق ويب Python Flask في بيئة App Engine المرنة. يتيح التطبيق النموذجي للمستخدم تحميل صورة لوجه شخص ومعرفة مدى احتمال أن يكون هذا الشخص سعيدًا. يستخدم التطبيق واجهات برمجة تطبيقات Google Cloud لكلّ من Vision وStorage وDatastore.

لمحة عن App Engine

تطبيقات Google App Engine سهلة الإنشاء والصيانة والتوسيع حسب تغيُّر احتياجاتك من حيث عدد الزيارات ومساحة تخزين البيانات. باستخدام App Engine، لن تحتاج إلى صيانة أي خوادم. ما عليك سوى تحميل تطبيقك وسيكون جاهزًا للاستخدام.

تتوسّع تطبيقات App Engine تلقائيًا استنادًا إلى عدد الزيارات الواردة. تتوفّر جميع الميزات التالية بشكلٍ أصلي وقابلة للتخصيص بدرجة كبيرة: موازنة التحميل، والخدمات المصغّرة، والأذونات، وقواعد بيانات SQL وNoSQL، وتقسيم عدد الزيارات، والتسجيل، والبحث، والتحكّم في الإصدارات، وعمليات الطرح والتراجع، وفحص الأمان.

يتوافق البيئة المرنة في App Engine مع جميع لغات البرمجة التالية: C#‎ وGo وJava وNode.js وPHP وPython وRuby. تشغّل "بيئة App Engine المرنة" تطبيقك داخل حاويات Docker تعمل على أجهزة Google Compute Engine الافتراضية. البيئة العادية في App Engine هي خيار بديل لبعض اللغات، بما في ذلك Python. تتيح لك بيئة App Engine العادية تشغيل تطبيقك في بيئة وضع الحماية أكثر تقييدًا. لمزيد من المعلومات، يُرجى الاطّلاع على مقالة اختيار بيئة App Engine.

ما ستتعرّف عليه

  • كيفية نشر تطبيق ويب بسيط في "بيئة App Engine المرنة"
  • كيفية الوصول إلى مكتبات برامج Google Cloud لخدمات Vision وStorage وDatastore
  • كيفية استخدام Google Cloud Console وGoogle Cloud SDK لإدارة موارد السحابة الإلكترونية المختلفة
  • كيفية استخدام Cloud Shell

المتطلبات

  • الإلمام بلغة Python
  • الإلمام بأدوات تحرير النصوص القياسية في Linux، مثل Vim أو Emacs أو Nano

إنشاء مشروع

إذا لم يكن لديك حساب على Google (Gmail أو Google Apps)، عليك إنشاء حساب. سجِّل الدخول إلى "وحدة تحكّم Google Cloud Platform" (console.cloud.google.com) وأنشِئ مشروعًا جديدًا:

تذكَّر معرّف المشروع، وهو اسم فريد في جميع مشاريع Google Cloud (الاسم أعلاه مستخدَم حاليًا ولن يكون متاحًا لك، نأسف لذلك). سيتم الرجوع إليه لاحقًا في هذا الدرس العملي باسم PROJECT_ID.

الفوترة

بعد ذلك، عليك تفعيل الفوترة في Cloud Console من أجل استخدام موارد Google Cloud.

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

يمكن للمستخدمين الجدد في Google Cloud Platform الاستفادة من فترة تجريبية مجانية بقيمة 300 دولار أمريكي.

على الرغم من إمكانية تشغيل Google Cloud عن بُعد من الكمبيوتر المحمول، سنستخدم في هذا الدرس العملي Google Cloud Shell، وهي بيئة سطر أوامر تعمل في السحابة الإلكترونية. يتم تحميل هذا الجهاز الافتراضي المستند إلى Debian بجميع أدوات التطوير التي تحتاج إليها (gcloud وpython وvirtualenv وpip وغيرها)، كما يوفّر دليلًا رئيسيًا دائمًا بسعة 5 غيغابايت، ويعمل على Google Cloud، ما يؤدي إلى تحسين أداء الشبكة والمصادقة بشكل كبير. وهذا يعني أنّ كل ما تحتاج إليه في هذا الدرس العملي هو متصفّح (نعم، يعمل على جهاز Chromebook).

لتفعيل Google Cloud Shell، ما عليك سوى النقر على الزرّ في أعلى يسار صفحة "وحدة تحكّم المطوّرين" (يستغرق توفير البيئة والاتصال بها بضع لحظات فقط):

بعد الاتصال بواجهة سطر الأوامر، من المفترض أن تلاحظ أنّه تمّت مصادقتك وأنّه تمّ ضبط المشروع على PROJECT_ID:

gcloud auth list
Credentialed accounts:
- <myaccount>@<mydomain>.com (active)
gcloud config list project
[core]
Project = <PROJECT_ID>

إذا لم يتم ضبط المشروع لسبب ما، ما عليك سوى تنفيذ الأمر التالي:

gcloud config set project <PROJECT_ID>

هل تبحث عن PROJECT_ID؟ تحقَّق من معرّف المشروع الذي استخدمته في خطوات الإعداد أو ابحث عنه في لوحة بيانات وحدة التحكّم:

في Cloud Shell على سطر الأوامر، نفِّذ الأمر التالي لاستنساخ مستودع Github:

git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

انتقِل إلى الدليل python-docs-samples/codelabs/flex_and_vision:

cd python-docs-samples/codelabs/flex_and_vision

قبل أن نتمكّن من بدء استخدام واجهات برمجة التطبيقات Vision وStorage وDatastore، يجب تفعيلها باستخدام الأوامر التالية:

gcloud services enable vision.googleapis.com
gcloud services enable storage-component.googleapis.com
gcloud services enable datastore.googleapis.com

لتقديم طلبات إلى واجهات برمجة التطبيقات Vision وStorage وDatastore، ستحتاج إلى بيانات اعتماد حساب الخدمة. يمكن إنشاء بيانات اعتماد حساب الخدمة من مشروعك باستخدام أداة gcloud.

اضبط متغيّر بيئة PROJECT_ID، واستبدِل [YOUR_PROJECT_ID] برقم تعريف مشروعك:

export PROJECT_ID=[YOUR_PROJECT_ID]

إنشاء حساب خدمة للوصول إلى واجهات برمجة تطبيقات Google Cloud عند الاختبار محليًا:

gcloud iam service-accounts create codelab \
  --display-name "My Codelab Service Account"

امنح حساب الخدمة الذي تم إنشاؤه حديثًا الأذونات المناسبة:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:codelab@${PROJECT_ID}.iam.gserviceaccount.com \
--role roles/owner

بعد إنشاء حساب الخدمة، أنشئ مفتاح حساب الخدمة باتّباع الخطوات التالية:

gcloud iam service-accounts keys create ~/key.json \
--iam-account codelab@${PROJECT_ID}.iam.gserviceaccount.com

ينشئ هذا الأمر مفتاح حساب خدمة يتم تخزينه في ملف JSON باسم key.json في الدليل الرئيسي.

باستخدام المسار المطلق للمفتاح الذي تم إنشاؤه، اضبط متغيّر بيئة لمفتاح حساب الخدمة في Cloud Shell:

export GOOGLE_APPLICATION_CREDENTIALS="/home/${USER}/key.json"

يمكنك الاطّلاع على مزيد من المعلومات حول مصادقة Vision API.

بدء البيئة الافتراضية وتثبيت التبعيات

أنشئ بيئة Python 3 معزولة باسم env باستخدام virtualenv:

virtualenv -p python3 env

أدخِل virtualenv الذي أنشأته حديثًا باسم env:

source env/bin/activate

استخدِم pip لتثبيت التبعيات لمشروعك من الملف requirements.txt:

pip install -r requirements.txt

ملف requirements.txt هو قائمة بحِزم التبعيات التي تحتاج إليها لمشروعك. أدّى الأمر أعلاه إلى تنزيل جميع تبعيات الحزمة المدرَجة إلى virtualenv.

إنشاء تطبيق App Engine

بعد ذلك، أنشئ مثيلاً من App Engine باستخدام:

gcloud app create

إنشاء حزمة Storage

أولاً، اضبط متغيّر البيئة CLOUD_STORAGE_BUCKET ليساوي اسم PROJECT_ID. (يُنصح عمومًا بتسمية الحزمة بالاسم نفسه الذي يحمله PROJECT_ID لتسهيل الأمر).

export CLOUD_STORAGE_BUCKET=${PROJECT_ID}

يستخدم تطبيقنا حزمة Cloud Storage، وعليك إنشاؤها من Cloud Shell باستخدام أداة تُسمى gsutil. نفِّذ الأمر التالي الذي ينشئ حزمة بالاسم نفسه الذي يحمله PROJECT_ID.

gsutil mb gs://${PROJECT_ID}

تشغيل التطبيق

python main.py

بعد بدء تشغيل التطبيق، انقر على رمز "معاينة الويب" في شريط أدوات Cloud Shell واختَر "المعاينة على المنفذ 8080".

سيتم فتح علامة تبويب في المتصفّح والاتصال بالخادم الذي بدأت تشغيله للتو. ينبغي أن تظهر لك على النحو التالي:

Screen Shot 2017-02-23 at 7.22.50 PM.png

يُرجى محاولة تحميل صورة تحتوي على وجه بشري. انقر على الزر اختيار ملف، واختَر صورة من جهاز الكمبيوتر، ثم انقر على إرسال.

بعد تحميل صورة، من المفترض أن يظهر لك ما يلي:

Screen Shot 2017-02-23 at 7.32.08 PM.png

تنسيق الرمز النموذجي

يتضمّن النموذج التخطيط التالي:

templates/
  homepage.html   /* HTML template that uses Jinja2 */
app.yaml          /* App Engine application configuration file */
main.py           /* Python Flask web application */
requirements.txt  /* List of dependencies for the project */

main.py

ملف Python هذا هو تطبيق ويب Flask. يسمح التطبيق للمستخدمين بإرسال صور (يُفضّل أن تكون صور وجوه)، ويتم تخزينها في Cloud Storage وتحليلها باستخدام ميزة "التعرّف على الوجوه" في Cloud Vision API. يتم تخزين المعلومات الأساسية عن كل صورة في Datastore، وهي قاعدة بيانات NoSQL في Google Cloud Platform، ويتم الوصول إليها في كل مرة يزور فيها المستخدم الموقع الإلكتروني.

يستخدم هذا التطبيق مكتبات برامج Google Cloud Platform لكلّ من Storage وDatastore وVision. تسهّل مكتبات البرامج هذه الوصول إلى واجهات Cloud API من لغات البرمجة المفضّلة لديك.

لنلقِ نظرة على بعض المقتطفات الرئيسية من الرمز.

قسم عمليات الاستيراد في أعلى الصفحة هو المكان الذي نستورد فيه الحِزم المختلفة التي نحتاجها للرمز البرمجي. إليك كيفية استيراد مكتبات برامج Google Cloud لخدمات Datastore وStorage وVision:

from google.cloud import datastore
from google.cloud import storage
from google.cloud import vision

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

@app.route('/')
def homepage():
    # Create a Cloud Datastore client.
    datastore_client = datastore.Client()

    # Use the Cloud Datastore client to fetch information from Datastore about
    # each photo.
    query = datastore_client.query(kind='Faces')
    image_entities = list(query.fetch())

    # Return a Jinja2 HTML template and pass in image_entities as a parameter.
    return render_template('homepage.html', image_entities=image_entities)

لنلقِ نظرة على كيفية حفظ الكيانات في Datastore. ‫Datastore هو حل قاعدة بيانات NoSQL من Google Cloud. يتم تخزين البيانات في عناصر تُعرف باسم الكيانات. يتم تعيين مفتاح تعريف فريد لكل كيان، ويمكن إنشاء هذا المفتاح باستخدام نوع وسلسلة اسم مفتاح. النوع هو تصنيف تنظيمي لنوع العنصر. على سبيل المثال، قد نريد إعداد أنواع للصور والأشخاص والحيوانات.

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

    # Create a Cloud Datastore client.
    datastore_client = datastore.Client()

    # Fetch the current date / time.
    current_datetime = datetime.now()

    # The kind for the new entity.
    kind = 'Faces'

    # The name/ID for the new entity.
    name = blob.name

    # Create the Cloud Datastore key for the new entity.
    key = datastore_client.key(kind, name)

    # Construct the new entity using the key. Set dictionary values for entity
    # keys blob_name, storage_public_url, timestamp, and joy.
    entity = datastore.Entity(key)
    entity['blob_name'] = blob.name
    entity['image_public_url'] = blob.public_url
    entity['timestamp'] = current_datetime
    entity['joy'] = face_joy

    # Save the new entity to Datastore.
    datastore_client.put(entity)

يمكن الوصول إلى مكتبات برامج Storage وVision آليًا بطريقة مشابهة لطريقة الوصول إلى Datastore. يمكنك فتح ملف main.py بنفسك باستخدام vim أو emacs أو nano لاستكشاف كل عيّنات الرموز البرمجية.

يمكنك الاطّلاع على مزيد من المعلومات حول Flask على http://flask.pocoo.org/.

يمكنك الاطّلاع على مزيد من المعلومات حول مكتبات البرامج على https://googlecloudplatform.github.io/google-cloud-python/.

homepage.html

يستفيد إطار عمل الويب Flask من Jinja2 كمحرّك قوالب. يتيح لنا ذلك تمرير المتغيرات والعبارات من main.py إلى homepage.html التي يتم استبدالها بالقيم عند عرض الصفحة.

يمكنك الاطّلاع على مزيد من المعلومات عن Jinja2 على الرابط http://jinja.pocoo.org/docs/2.9/templates/.

يعرض نموذج HTML هذا المستند إلى Jinja2 نموذجًا يتيح للمستخدمين إرسال الصور إلى قاعدة البيانات. تعرض أيضًا كل صورة تم إرسالها سابقًا مع اسم ملفها وتاريخ/وقت تحميلها واحتمالية أن يكون الوجه الذي رصده Vision API سعيدًا.

homepage.html

<h1>Google Cloud Platform - Face Detection Sample</h1>

<p>This Python Flask application demonstrates App Engine Flexible, Google Cloud
Storage, Datastore, and the Cloud Vision API.</p>

<br>

<html>
  <body>
    <form action="upload_photo" method="POST" enctype="multipart/form-data">
      Upload File: <input type="file" name="file"><br>
      <input type="submit" name="submit" value="Submit">
    </form>
    
  </body>
</html>

يستخدم App Engine Flexible ملفًا باسم app.yaml لوصف إعدادات نشر أحد التطبيقات. إذا لم يكن هذا الملف متوفّرًا، ستحاول App Engine تخمين إعدادات النشر. ومع ذلك، يُستحسَن تقديم هذا الملف.

بعد ذلك، ستعدّل ملف app.yaml باستخدام محرر من اختيارك vim أو nano أو emacs. سنستخدم محرّر النصوص nano:

nano app.yaml

app.yaml

runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
    python_version: 3

env_variables:
    CLOUD_STORAGE_BUCKET: <your-cloud-storage-bucket>

هذا هو الإعداد الأساسي اللازم لنشر تطبيق Python 3 App Engine Flex. يمكنك الاطّلاع على مزيد من المعلومات حول إعداد App Engine هنا.

بعد فتح ملف app.yaml، استبدِل < your-cloud-storage-bucket > باسم حزمة Cloud Storage. (إذا نسيت اسم حزمة Cloud Storage، انسخ معرّف مشروع GCP من Qwiklabs، وهو الاسم نفسه). يضبط القسم env_variables متغيرات البيئة التي سيتم استخدامها في main.py بعد نشر التطبيق.

يمكنك الآن حفظ الملف وإغلاقه في nano باستخدام (Ctrl + x)، ما سيؤدي إلى ظهور الرسالة التالية:

Screen Shot 2017-02-17 at 4.47.12 PM.png

اكتب الحرف y ثم اضغط على المفتاح ENTER مرة أخرى لتأكيد اسم الملف في الطلب التالي:

Screen Shot 2017-02-24 at 4.18.23 PM.png

يمكنك نشر تطبيقك على App Engine باستخدام gcloud باتّباع الخطوات التالية:

gcloud app deploy

بعد نشر التطبيق، يمكنك الانتقال إليه من خلال فتح عنوان URL https://< PROJECT_ID >.appspot.com في متصفّح الويب.

ملخّص

في هذه الخطوة، يمكنك إعداد تطبيق ويب بلغة Python ونشره في "بيئة App Engine المرنة".

لقد تعلّمت كيفية كتابة تطبيق الويب الأول ونشره على "بيئة App Engine المرنة".

تنظيف

لتجنُّب تحمّل رسوم في حسابك على Google Cloud Platform مقابل الموارد المستخدَمة في هذا الدليل السريع، اتّبِع الخطوات التالية:

  • انتقِل إلى وحدة تحكّم Cloud Platform.
  • اختَر المشروع الذي تريد إيقافه، ثم انقر على "حذف" في أعلى الصفحة: يؤدي ذلك إلى تحديد موعد لحذف المشروع.

مزيد من المعلومات

الترخيص

يخضع هذا العمل لترخيص Creative Commons Attribution 2.0 Generic License.