การทําให้เว็บแอปพลิเคชัน Python Flask ใช้งานได้ในสภาพแวดล้อมที่ยืดหยุ่นของ App Engine

สรุป

ในโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีทำให้เว็บแอปพลิเคชัน Python Flask ใช้งานได้กับสภาพแวดล้อมที่ยืดหยุ่นของ App Engine แอปพลิเคชันตัวอย่างช่วยให้ผู้ใช้อัปโหลดรูปภาพใบหน้าของบุคคลและดูความเป็นไปได้ที่บุคคลนั้นจะมีความสุข แอปพลิเคชันใช้ Google Cloud API สำหรับ 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 ในภายหลังใน Codelab นี้

การเรียกเก็บเงิน

จากนั้นคุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร Google Cloud

การทำตาม Codelab นี้ไม่น่าจะมีค่าใช้จ่ายเกิน 2-3 ดอลลาร์ แต่ก็อาจมีค่าใช้จ่ายมากกว่านี้หากคุณตัดสินใจใช้ทรัพยากรเพิ่มเติมหรือปล่อยให้ทรัพยากรทำงานต่อไป

ผู้ใช้ใหม่ของ Google Cloud Platform มีสิทธิ์ทดลองใช้ฟรี$300

แม้ว่าคุณจะใช้งาน Google Cloud จากแล็ปท็อประยะไกลได้ แต่ใน Codelab นี้เราจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์ เครื่องเสมือนที่ใช้ Debian นี้มาพร้อมเครื่องมือพัฒนาทั้งหมดที่คุณต้องการ (gcloud, python, virtualenv, pip และอื่นๆ) มีไดเรกทอรีแรกถาวรขนาด 5 GB และทำงานบน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก ซึ่งหมายความว่าคุณจะต้องมีเพียงเบราว์เซอร์เท่านั้นสำหรับโค้ดแล็บนี้ (ใช่แล้ว โค้ดแล็บนี้ใช้ได้ใน Chromebook)

หากต้องการเปิดใช้งาน Google Cloud Shell จากคอนโซลนักพัฒนาแอป ให้คลิกปุ่มที่ด้านขวาบน (ระบบจะจัดสรรและเชื่อมต่อกับสภาพแวดล้อมในเวลาเพียงไม่กี่นาที)

เมื่อเชื่อมต่อกับ 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 API ได้ คุณต้องเปิดใช้ API ด้วยคำสั่งต่อไปนี้

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

หากต้องการส่งคำขอไปยัง Vision, Storage และ Datastore API คุณจะต้องมีข้อมูลเข้าสู่ระบบของบัญชีบริการ คุณสร้างข้อมูลเข้าสู่ระบบของบัญชีบริการจากโปรเจ็กต์ได้โดยใช้เครื่องมือ gcloud

ตั้งค่าตัวแปรสภาพแวดล้อมสำหรับ PROJECT_ID โดยแทนที่ [YOUR_PROJECT_ID] ด้วยรหัสโปรเจ็กต์ของคุณเอง

export PROJECT_ID=[YOUR_PROJECT_ID]

สร้างบัญชีบริการเพื่อเข้าถึง Google Cloud API เมื่อทดสอบในเครื่อง

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

การสร้างที่เก็บข้อมูล

ก่อนอื่น ให้ตั้งค่าตัวแปรสภาพแวดล้อม 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>

นี่คือการกำหนดค่าพื้นฐานที่จำเป็นในการทำให้แอปพลิเคชัน App Engine Flex ของ Python 3 ใช้งานได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่า 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 Flexible ตัวแรกใช้งานได้แล้ว

ล้างข้อมูล

เพื่อเลี่ยงไม่ให้เกิดการเรียกเก็บเงินกับบัญชี Google Cloud Platform สำหรับทรัพยากรที่ใช้ในการเริ่มต้นอย่างรวดเร็วนี้ ควรทำดังนี้

  • ไปที่คอนโซล Cloud Platform
  • เลือกโปรเจ็กต์ที่ต้องการปิด แล้วคลิก "ลบ" ที่ด้านบน ซึ่งจะเป็นการกำหนดเวลาให้ลบโปรเจ็กต์

ดูข้อมูลเพิ่มเติม

ใบอนุญาต

ผลงานนี้ได้รับอนุญาตภายใต้สัญญาอนุญาตครีเอทีฟคอมมอนส์สำหรับยอมรับสิทธิของผู้สร้าง (Creative Commons Attribution License) 2.0 แบบทั่วไป