פריסת אפליקציית אינטרנט ב-Python Flask בסביבה גמישה של App Engine

סיכום

במעבדה זו של הקוד תלמדו איך לפרוס אפליקציית אינטרנט ב-Python Flask בסביבה הגמישה של App Engine. האפליקציה לדוגמה מאפשרת למשתמש להעלות תמונה של פנים של אדם ולהבין עד כמה סביר שהאדם הזה שמח. האפליקציה משתמשת בממשקי Google Cloud APIs ל-Vision, לאחסון ול-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 Standard מפעיל את האפליקציה שלך בסביבת ארגז חול מגבילה יותר. מידע נוסף זמין במאמר בחירת סביבה של App Engine.

מה תלמדו

  • כיצד לפרוס אפליקציית אינטרנט פשוטה בסביבה גמישה של App Engine
  • איך ניגשים לספריות לקוח ב-Google Cloud עבור ראייה, אחסון ו-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 (השם הקודם כבר תפוס, והוא לא יעבוד בשבילך.) נתייחס אליה מאוחר יותר ב-codelab הזה בתור PROJECT_ID.

חיוב

לאחר מכן, עליך להפעיל חיוב ב-Cloud Console כדי להשתמש במשאבים של Google Cloud.

התהליך של קוד Lab זה לא אמור לעלות יותר מדולר אחד, אבל אם החלטתם להשתמש במשאבים נוספים או להשאיר אותם, ייתכן שהסכום יהיה גבוה יותר.

משתמשים חדשים ב-Google Cloud Platform זכאים לתקופת ניסיון בחינם בשווי 300$.

ניתן להפעיל את Google Cloud מרחוק מהמחשב הנייד שלך, אבל במעבדה זו נעשה שימוש ב-Google Cloud Shell, סביבת שורת פקודה שפועלת ב-Cloud. המכונה הווירטואלית המבוססת על Debian נטענת באמצעות כל כלי הפיתוח הדרושים לך (gcloud, python, virtualenv, pip ועוד). היא מציעה ספריית בית בנפח עקבי של 5GB והיא פועלת ב-Google Cloud, וכך משפרת באופן משמעותי את הביצועים ואת האימות של הרשת. כלומר, כל מה שדרוש לכם עבור קוד Lab זה הוא דפדפן (כן, הוא פועל ב-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, באחסון וב-API של Datastore, עליך להפעיל את ממשקי ה-API עם הפקודות הבאות:

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

כדי לשלוח בקשות ל-Vision, לאחסון ול-API של Datastore, תצטרכו פרטי כניסה לחשבון שירות. ניתן ליצור פרטי כניסה של חשבון שירות מהפרויקט באמצעות הכלי gcloud.

מגדירים משתנה סביבה עבור PROJECT_ID, ומחליפים את [YOUR_PROJECT_ID] במזהה הפרויקט שלכם.

export PROJECT_ID=[YOUR_PROJECT_ID]

כדי לגשת ל-Google Cloud APIs במהלך בדיקה מקומית, צריך ליצור חשבון שירות:

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 הוא רשימה של תלויות חבילה הדרושות לפרויקט שלכם. הפקודה שלמעלה הורדה של כל תלויות החבילה שברשימה ל-virtualen.

יצירת App Engine

בשלב הבא, יוצרים מופע של App Engine באמצעות:

gcloud app create

יצירת קטגוריית אחסון

תחילה, מגדירים את משתנה הסביבה 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."

כרטיסייה בדפדפן תיפתח ותתחבר לשרת שהתחלת עכשיו. אתם אמורים לראות משהו כזה:

צילום מסך 2017-02-23 בשעה 19:22

אפשר לנסות להעלות תמונה שמכילה פנים של אנשים. לוחצים על הלחצן בחירת קובץ, בוחרים תמונה מהמחשב ולאחר מכן לוחצים על שליחה.

לאחר העלאת תמונה, אתה אמור לראות משהו כזה:

צילום מסך 2017-02-23 בשעה 19:32

פריסת קוד לדוגמה

לפריסה יש את הפריסה הבאה:

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. מידע חשוב לגבי כל תמונה מאוחסן במאגר הנתונים של Google Cloud Platform, במסד הנתונים NoSQL, שאליו ניתן לגשת בכל פעם שמשתמש נכנס לאתר.

האפליקציה הזו משתמשת בספריות הלקוח של Google Cloud Platform לאחסון, ל-Datastore ול-Vision. ספריות הלקוח האלה מאפשרות לכם לגשת בקלות אל Cloud APIs בשפות התכנות האהובות עליכם.

בואו נבחן כמה קטעי קוד חשובים.

בקטע 'ייבוא' בחלק העליון הוא המקום שבו אנחנו מייבאים את החבילות השונות הדרושות לנו עבור הקוד. כדי לייבא את ספריות הלקוחות של Google Cloud ל-Datastore, לאחסון ול-Vision:

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

הנה הקוד שמתרחש כאשר משתמש מבקר בכתובת האתר הבסיסית (root) של האתר. אנחנו יוצרים אובייקט לקוח מסוג 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 Vision בצורה פרוגרמטית באופן דומה ל-Datastore. אתם יכולים לפתוח את הקובץ main.py בעצמכם באמצעות vim, emacs או nano כדי לסקור את כל הקוד לדוגמה.

מידע נוסף על Flask זמין בכתובת http://flask.pocoo.org/.

מידע נוסף על ספריות לקוח זמין בכתובת https://googlecloudplatform.github.io/google-cloud-python/ .

דף הבית.html

מסגרת האינטרנט של Flask משתמשת ב-Jinja2 כמנוע תבנית. כך אנחנו יכולים להעביר משתנים וביטויים מ-main.py ל-homepage.html, שיוחלפו בערכים לאחר עיבוד הדף.

מידע נוסף על Jinja2 זמין בכתובת http://jinja.pocoo.org/docs/2.9/templates/.

בתבנית ה-HTML של Jinja2 מוצג טופס למשתמשים שמאפשר לשלוח תמונות למסד הנתונים. כמו כן, כל תמונה שנשלחה נשלחת בצירוף שם הקובץ, תאריך/שעת ההעלאה והסבירות שהפנים שזוהו על ידי ה-Vision API יהיו מרוצים.

דף הבית.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 משתמש בקובץ בשם 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, שתופיע:

צילום מסך 2017-02-17 בשעה 16.47.12

מקלידים אות y ואז מקישים על מקש ENTER שוב כדי לאשר את שם הקובץ של הבקשה הבאה:

צילום מסך 2017-02-24 בשעה 16:18

פריסת האפליקציה ב-App Engine באמצעות gcloud:

gcloud app deploy

אחרי שפורסים את האפליקציה אפשר להיכנס אליה בכתובת https://< PROJECT_ID >.appspot.com בדפדפן האינטרנט.

סיכום

בשלב זה תגדיר אפליקציית אינטרנט של Python ופרוס אותה בסביבת ה-App Engine הגמיש.

למדת איך לכתוב ולפרוס את יישום האינטרנט הגמיש הראשון שלך ב-App Engine!

ניקיון

כדי להימנע מצבירה של חיובים בחשבון Google Cloud Platform עבור המשאבים ששימשו להתחלה המהירה הזו:

  • נכנסים ל-Cloud Platform Console.
  • בוחרים את הפרויקט שרוצים להשבית ולוחצים על ‘מחיקה&#39’; בחלק העליון: מתזמנים את הפרויקט למחיקה.

מידע נוסף

רישיון

היצירה הזו ברישיון תחת רישיון Creative Commons Attribution 2.0.