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

สรุป

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีทําให้เว็บแอปพลิเคชัน Python Flask ใช้งานได้ในสภาพแวดล้อมที่ยืดหยุ่นของ App Engine แอปพลิเคชันตัวอย่างช่วยให้ผู้ใช้อัปโหลดรูปภาพใบหน้าของบุคคลดังกล่าวและดูความเป็นไปได้ที่บุคคลนั้นจะพอใจ แอปพลิเคชันนี้ใช้ Google Cloud API สําหรับ Vision, Storage และ Datastore

เกี่ยวกับ App Engine

แอปพลิเคชัน Google App Engine นั้นสร้าง ดูแลรักษาได้ง่าย และปรับขนาดได้ง่ายเมื่อความต้องการด้านพื้นที่เก็บข้อมูลและพื้นที่เก็บข้อมูลของคุณมีการเปลี่ยนแปลง App Engine ไม่ช่วยให้เซิร์ฟเวอร์มีการบํารุงรักษาใดๆ ได้เลย เพียงอัปโหลดแอปพลิเคชันของคุณก็พร้อมใช้งานแล้ว

แอปพลิเคชันของ App Engine จะปรับสัดส่วนโดยอัตโนมัติตามการเข้าชมขาเข้า การจัดสรรภาระงาน, Microservice, การให้สิทธิ์, ฐานข้อมูล SQL และ NoSQL, การแยกการเข้าชม, การบันทึก, การค้นหา, การกําหนดเวอร์ชัน, การเปิดตัวและย้อนกลับ และการสแกนความปลอดภัยล้วนมีการรองรับในตัวและปรับแต่งได้อย่างละเอียด

สภาพแวดล้อมที่ยืดหยุ่นของ App Engine รองรับภาษาการเขียนโปรแกรมทั้งหมดต่อไปนี้ C#, Go, Java, Node.js, PHP, Python และ Ruby App Engine Flexible เรียกใช้แอปพลิเคชันภายในคอนเทนเนอร์ Docker ที่ทํางานบนเครื่องเสมือนของ Google Compute Engine สภาพแวดล้อมมาตรฐานของ App Engine&#39 เป็นตัวเลือกทางเลือกสําหรับบางภาษา ซึ่งรวมถึง Python App Engine Standard จะเรียกใช้แอปพลิเคชันในสภาพแวดล้อมแซนด์บ็อกซ์ที่มีการจํากัดมากขึ้น อ่านข้อมูลเพิ่มเติมที่หัวข้อการเลือกสภาพแวดล้อม 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 ทั้งหมด (ชื่อข้างต้นมีผู้อื่นนําไปใช้แล้ว ขออภัยในความไม่สะดวก) และจะเรียกใน Codelab นี้ว่า PROJECT_ID ในภายหลัง

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

จากนั้นคุณจะต้องเปิดใช้การเรียกเก็บเงินใน 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 ช่วยเพิ่มประสิทธิภาพและการตรวจสอบสิทธิ์ของเครือข่ายได้อย่างมาก ซึ่งหมายความว่า เพียงแค่ใช้ Codelab นี้ คุณก็สามารถใช้เบราว์เซอร์ได้ (ใช่บนอุปกรณ์ 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/fl_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 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

การเริ่มต้นสภาพแวดล้อมเสมือนและการติดตั้งทรัพยากร Dependency

สร้างสภาพแวดล้อม Python 3 แยกต่างหากที่ชื่อ env โดยใช้ virtualenv ดังนี้

virtualenv -p python3 env

ป้อน virtualenv ที่สร้างขึ้นใหม่ชื่อ env ดังนี้

source env/bin/activate

ใช้ pip เพื่อติดตั้งทรัพยากร Dependency สําหรับโปรเจ็กต์ของคุณ โดยใช้ไฟล์ requirements.txt ดังนี้

pip install -r requirements.txt

ไฟล์ requirements.txt คือรายการทรัพยากร Dependency ของแพ็กเกจที่จําเป็นสําหรับโปรเจ็กต์ คําสั่งข้างต้นจะดาวน์โหลดทรัพยากร Dependency ของแพ็กเกจทั้งหมดที่ระบุไปยัง virtualenv

การสร้างแอป App Engine

ต่อไปให้สร้างอินสแตนซ์ App Engine โดยใช้วิธีต่อไปนี้

gcloud app create

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

ขั้นแรก ให้กําหนดตัวแปรสภาพแวดล้อม CLOUD_STORAGE_BUCocket ซึ่งเท่ากับชื่อของ 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 เวลา 19:22.50 น.

ลองอัปโหลดรูปภาพที่มีใบหน้ามนุษย์ คลิกปุ่มเลือกไฟล์ เลือกรูปภาพจากคอมพิวเตอร์ แล้วคลิกส่ง

หลังจากอัปโหลดรูปภาพ คุณควรจะเห็นรูปภาพดังนี้

Screen Shot 2017-02-23 เวลา 19:32.08 น.

ตัวอย่างเลย์เอาต์โค้ด

ตัวอย่างมีเลย์เอาต์ต่อไปนี้

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 สําหรับพื้นที่เก็บข้อมูล, Datastore และ Vision ไลบรารีของไคลเอ็นต์เหล่านี้ช่วยให้เข้าถึง Cloud API จากภาษาโปรแกรมที่คุณชื่นชอบได้อย่างง่ายดาย

มาดูตัวอย่างบางส่วนของโค้ดกัน

ส่วนการนําเข้าที่ด้านบนเป็นส่วนที่เรานําเข้าแพ็กเกจต่างๆ ที่จําเป็นสําหรับโค้ดของเรา ต่อไปนี้คือวิธีนําเข้าไลบรารีของไคลเอ็นต์ Google Cloud สําหรับ Datastore, พื้นที่เก็บข้อมูล และ 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&#39 ซึ่งข้อมูลจะจัดเก็บไว้ในออบเจ็กต์ที่เรียกว่าเอนทิตี เอนทิตีแต่ละรายการจะได้รับสตริงคีย์ระบุที่ไม่ซ้ํากัน ซึ่งสร้างได้โดยใช้สตริงประเภทและชื่อคีย์ ประเภท คือที่เก็บข้อมูลขององค์กรสําหรับประเภทของเอนทิตี ตัวอย่างเช่น เราอาจต้องการตั้งค่าชนิดสําหรับรูปภาพ บุคคล และสัตว์

เอนทิตีแต่ละรายการมีพร็อพเพอร์ตี้ที่กําหนดโดยนักพัฒนาแอปได้หลายรายการ ซึ่งอาจมีค่าหลายประเภท เช่น จํานวนเต็ม เลขทศนิยม สตริง วันที่ หรือข้อมูลไบนารี

    # 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/

home.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 เวลา 16.47.12 น.

พิมพ์ตัวอักษร y แล้วกดแป้น ENTER อีกครั้งเพื่อยืนยันชื่อไฟล์สําหรับข้อความแจ้งต่อไปนี้

Screen Shot 2017-02-24 เวลา 16.18.23 น.

ทําให้แอปของคุณใช้งานได้ใน App Engine โดยใช้ gcloud:

gcloud app deploy

หลังจากทําให้แอปพลิเคชันใช้งานได้แล้ว คุณจะเปิดได้ด้วยการเปิด URL https://< PROJECT_ID >.appspot.com ในเว็บเบราว์เซอร์

สรุป

ในขั้นตอนนี้ คุณสามารถตั้งค่าเว็บแอปพลิเคชัน Python และทําให้แอปพลิเคชันนั้นใช้สภาพแวดล้อมของ App Engine Flexible ได้

คุณได้เรียนรู้วิธีเขียนและทําให้เว็บแอปพลิเคชัน App Engine Flexible รายการแรกใช้งานได้แล้ว

บริการทําความสะอาด

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

  • ไปที่คอนโซล Cloud Platform
  • เลือกโปรเจ็กต์ที่ต้องการปิด แล้วคลิก "ลบ&#39" ที่ด้านบน เพื่อตั้งเวลาลบโปรเจ็กต์

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

ใบอนุญาต

ผลงานนี้ได้รับอนุญาตภายใต้สัญญาอนุญาตทั่วไปของ Creative Commons Attribution 2.0