Wdrażanie aplikacji internetowej Python Flask w elastycznym środowisku App Engine

Podsumowanie

Z tego modułu dowiesz się, jak wdrożyć aplikację internetową w języku Python Flask do elastycznego środowiska App Engine. Przykładowa aplikacja umożliwia użytkownikowi przesłanie zdjęcia danej osoby i poznanie prawdopodobieństwa, że ta osoba jest zadowolony(a). Aplikacja korzysta z interfejsów Google Cloud API na potrzeby Vision, Storage i Datastore.

Informacje o App Engine

Aplikacje Google App Engine są łatwe w tworzeniu, obsłudze i łatwym skalowaniu w zależności od zmian natężenia ruchu i ilości danych. Dzięki App Engine nie musisz utrzymywać serwerów. Po prostu prześlij aplikację.

Aplikacje App Engine automatycznie skalują się w zależności od ruchu przychodzącego. Równoważenie obciążenia, mikroserwisy, autoryzacja, bazy danych SQL i NoSQL, podział ruchu, logowanie, wyszukiwanie, obsługa wersji, wdrażanie i wycofywanie oraz skanowanie zabezpieczeń są wspierane natywnie i można je dostosować.

Elastyczne środowisko App Engine obsługuje wszystkie te języki programowania: C#, Go, Java, Node.js, PHP, Python i Ruby. Elastyczne oprogramowanie App Engine uruchamia Twoją aplikację w kontenerach Dockera, które działają na maszynach wirtualnych Google Compute Engine. Środowisko standardowe App Engine jest alternatywną opcją dla niektórych języków, w tym Pythona. App Engine Standard uruchamia aplikację w bardziej restrykcyjnym środowisku piaskownicy. Więcej informacji znajdziesz w sekcji Wybieranie środowiska App Engine.

Czego się nauczysz:

  • Jak wdrożyć prostą aplikację internetową w elastycznym środowisku App Engine
  • Jak uzyskać dostęp do bibliotek klienta Google Cloud dla Vision, Storage i Datastore
  • Jak zarządzać różnymi zasobami w chmurze za pomocą Google Cloud Console i pakietu SDK Google Cloud
  • Jak korzystać z Cloud Shell

Czego potrzebujesz

  • Znajomość Pythona
  • Znajomość standardowych edytorów tekstu systemu Linux, takich jak Vim, Emacs lub Nano

Utworzenie projektu

Jeśli nie masz jeszcze konta Google (Gmail lub Google Apps), musisz je utworzyć. Zaloguj się w konsoli Google Cloud Platform (console.cloud.google.com) i utwórz nowy projekt:

Zapamiętaj identyfikator projektu, unikalną nazwę we wszystkich projektach Google Cloud (powyższa nazwa została już użyta i nie będzie działać). W ćwiczeniach kodowych nazywamy go później PROJECT_ID.

Płatności

Aby móc używać zasobów Google Cloud, musisz najpierw włączyć płatności w Cloud Console.

Ćwiczenia z programowania nie powinny kosztować więcej niż kilka dolarów, ale mogą być większe, jeśli zdecydujesz się wykorzystać więcej zasobów lub pozostawisz to uruchomione.

Nowi użytkownicy Google Cloud Platform mogą skorzystać z bezpłatnej wersji próbnej o wartości 300 USD.

Google Cloud można uruchomić zdalnie z laptopa, ale podczas tego ćwiczenia wykorzystamy Google Cloud Shell – środowisko wiersza poleceń działające w chmurze. Ta maszyna wirtualna oparta na Debianie jest wyposażona we wszystkie narzędzia dla programistów, których potrzebujesz (gcloud, python, virtualenv oraz pip), ma trwały katalog domowy o pojemności 5 GB oraz działa w Google Cloud, co znacznie zwiększa wydajność sieci i uwierzytelnia. Oznacza to, że do wykonania tych ćwiczeń z programowania wystarczy przeglądarka (tak, to działa na Chromebooku).

Aby aktywować Google Cloud Shell, w konsoli administracyjnej kliknij przycisk w prawym górnym rogu ekranu. Udostępnienie środowiska i połączenie się z nim powinno potrwać kilka minut:

Po połączeniu się z Cloud Shell zobaczysz, że uwierzytelniono już projekt, a projekt jest już ustawiony na PROJECT_ID:

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

Jeśli z jakiegoś powodu projekt nie jest skonfigurowany, uruchom to polecenie:

gcloud config set project <PROJECT_ID>

Szukasz swojego projektu PROJECT_ID? Sprawdź identyfikator projektu użyty w krokach konfiguracji lub sprawdź go w panelu konsoli:

W wierszu poleceń uruchom w Cloud Shell następujące polecenie, aby skopiować repozytorium GitHub:

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

Zmień katalog na python-docs-samples/codelabs/flex_and_vision:

cd python-docs-samples/codelabs/flex_and_vision

Zanim będziemy mogli zacząć korzystać z interfejsów Vision, Storage i Datastore, musisz włączyć te interfejsy API za pomocą tych poleceń:

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

Aby wysyłać żądania do interfejsów Vision, Storage i Datastore, potrzebujesz danych logowania do konta usługi. Dane logowania do konta usługi z projektu można wygenerować za pomocą narzędzia gcloud.

Ustaw zmienną środowiskową dla projektu PROJECT_ID, zastępując fragment [YOUR_PROJECT_ID] własnym identyfikatorem projektu:

export PROJECT_ID=[YOUR_PROJECT_ID]

Utwórz konto usługi, aby uzyskać dostęp do interfejsów API Google Cloud podczas testowania lokalnego:

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

Przyznaj nowemu kontu usługi odpowiednie uprawnienia:

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

Po utworzeniu konta usługi utwórz klucz konta usługi:

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

To polecenie generuje klucz konta usługi zapisany w pliku JSON o nazwie key.json w katalogu głównym.

Korzystając ze ścieżki bezwzględnej wygenerowanego klucza, ustaw zmienną środowiskową klucza konta usługi w Cloud Shell:

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

Dowiedz się więcej o uwierzytelnianiu interfejsu Vision API.

Uruchamianie środowiska wirtualnego i instalowanie zależności

Utwórz izolowane środowisko Pythona 3 o nazwie env z virtualenv:

virtualenv -p python3 env

Wpisz nowo utworzony virtualenv o nazwie env:

source env/bin/activate

Użyj pliku pip, aby zainstalować zależności dla swojego projektu w pliku requirements.txt:

pip install -r requirements.txt

Plik requirements.txt zawiera listę zależności pakietów, które są potrzebne w Twoim projekcie. Powyższe polecenie pobrało wszystkie te wymienione zależności pakietu na rozszerzenie virtualenv.

Tworzenie aplikacji App Engine

Następnie utwórz instancję App Engine, używając:

gcloud app create

Tworzenie zasobnika Cloud Storage

Najpierw ustaw zmienną środowiskową CLOUD_STORAGE_BUCKET równą nazwę swojego ID_PROJEKTU. Ogólnie rzecz biorąc, zalecamy używanie tej samej nazwy zasobnika co PROJECT_ID.

export CLOUD_STORAGE_BUCKET=${PROJECT_ID}

Nasza aplikacja wykorzystuje zasobnik Cloud Storage, który należy utworzyć za pomocą narzędzia gsutil z Cloud Shell. Uruchom następujące polecenie, co spowoduje utworzenie zasobnika o tej samej nazwie co Twój PROJECT_ID.

gsutil mb gs://${PROJECT_ID}

Uruchamianie aplikacji

python main.py

Po uruchomieniu aplikacji kliknij ikonę Podgląd w przeglądarce na pasku narzędzi Cloud Shell i wybierz „Podgląd na porcie 8080”."

W przeglądarce otworzy się karta z uruchomionym serwerem. Powinien pojawić się ekran podobny do tego:

Zrzut ekranu 23.02.2017 o 19:22.50.png

Spróbuj przesłać zdjęcie przedstawiające ludzką twarz. Kliknij przycisk Wybierz plik, wybierz obraz z komputera i kliknij Prześlij.

Po przesłaniu zdjęcia powinno wyświetlić się coś takiego:

Zrzut ekranu 2017-02-23 o 19.32.08.png

Przykładowy układ kodu

Oto przykładowy układ:

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

główna.py

Ten plik Pythona jest aplikacją internetową Flask. Aplikacja umożliwia użytkownikom przesyłanie zdjęć (najlepiej twarzy), które są przechowywane w Cloud Storage i analizowane za pomocą funkcji wykrywania twarzy w interfejsie Cloud Vision API. Najważniejsze informacje o każdym zdjęciu są przechowywane w Datastore, bazie danych Google Cloud Platform i otwartej za każdym razem, gdy użytkownik odwiedza witrynę.

Ta aplikacja korzysta z bibliotek klienta Google Cloud Platform do przechowywania danych, Datastore i Vision. Te biblioteki klienta ułatwiają dostęp do interfejsów API Cloud z ulubionych języków programowania.

Przyjrzyjmy się kluczowym fragmentom kodu.

Sekcja „Importuj” u góry służy do importowania różnych pakietów niezbędnych w kodzie. Aby zaimportować nasze biblioteki klienta Google Cloud na potrzeby Datastore, Storage i Vision:

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

Oto kod pokazujący, co się dzieje, gdy użytkownik odwiedza główny URL strony. Tworzymy obiekt klienta Datastore, który pozwala uzyskać dostęp do biblioteki klienta Datastore. Następnie uruchamiamy w Datastore zapytanie dotyczące encji Faces. Na koniec renderujemy szablon HTML, przekazując jako zmienną image_entities wyodrębnione z 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)

Przyjrzyjmy się, jak elementy są zapisywane w Datastore. Datastore to rozwiązanie baz danych Google Cloud NoSQL. Dane są przechowywane w obiektach zwanych elementami. Każdemu elementowi jest przypisywany unikalny klucz, który można utworzyć za pomocą ciągu rodzaj, a następnie nazwy klucza. Rodzaj to zasobnik organizacyjny dla danego typu jednostki. Możemy na przykład skonfigurować rodzaje zdjęć, osób i zwierząt.

Każdy element entity może mieć wiele właściwości zdefiniowanych przez dewelopera, które mogą mieć wartości różnych typów, w tym liczby całkowite, zmiennoprzecinkowe, ciągi znaków, daty lub dane binarne.

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

Dostęp do bibliotek klienta Cloud Storage i Vision można uzyskać programowo w sposób podobny do Datastore. Aby poznać cały przykładowy kod, możesz otworzyć plik main.py przy użyciu vim, emacs lub nano.

Więcej informacji o Flask znajdziesz na http://flask.pocoo.org/.

Więcej informacji o bibliotekach klienta znajdziesz na stronie https://googlecloudplatform.github.io/google-cloud-python/.

strona główna.html

Platforma internetowa Flask wykorzystuje Jinja2 jako szablon szablonu. Pozwala to przekazywać zmienne i wyrażenia z pliku main.py do pliku homepage.html, które są zastępowane wartościami po wyrenderowaniu strony.

Więcej informacji o Jinja2 znajdziesz na http://jinja.pocoo.org/docs/2.9/templates/.

Ten szablon HTML Jinja2 wyświetla formularz, za pomocą którego użytkownicy mogą przesyłać zdjęcia do bazy danych. Na liście są też wyświetlane wszystkie przesłane wcześniej zdjęcia wraz z nazwą pliku, datą i godziną przesłania oraz prawdopodobieństwom, że twarz jest wykrywana przez Vision API.

strona główna.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>

Do opisania konfiguracji wdrożenia aplikacji służy elastyczne środowisko App Engine z plikiem app.yaml. Jeśli nie ma tego pliku, App Engine spróbuje odgadnąć konfigurację wdrożenia. Warto jednak przesłać ten plik.

Następnie zmodyfikujesz plik app.yaml przy użyciu wybranego edytora vim, nano lub emacs. Użyjemy edytora 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>

To podstawowa konfiguracja potrzebna do wdrożenia aplikacji Flex App Engine w języku Python 3. Więcej o konfigurowaniu App Engine dowiesz się tutaj.

Po otwarciu pliku app.yaml zastąp fragment < twój-zasobnik-chmury > nazwą zasobnika Cloud Storage. Jeśli nie pamiętasz nazwy zasobnika Cloud Storage, skopiuj identyfikator projektu GCP z Qwiklabs. W sekcji env_variables konfigurujesz zmienne środowiskowe, które będą używane w pliku main.py po wdrożeniu aplikacji.

Możesz teraz zapisać i zamknąć plik w narzędziu nano, naciskając (Ctrl + x):

Zrzut ekranu 2017-02-17 o 14:47.12.png

Wpisz literę y, a następnie jeszcze raz naciśnij klawisz ENTER, aby potwierdzić nazwę pliku w przypadku tego komunikatu:

Zrzut ekranu 24.02.2017 o 14:18.23.png

Wdróż aplikację w App Engine przy użyciu gcloud:

gcloud app deploy

Po wdrożeniu aplikacji możesz ją otworzyć, otwierając w przeglądarce adres URL https://< PROJECT_ID >.appspot.com.

Podsumowanie

W tym kroku skonfigurujesz aplikację internetową w języku Python i wdrożysz ją w elastycznym środowisku App Engine.

Wiesz już, jak pisać i wdrażać pierwszą aplikację elastyczną App Engine.

Czyszczenie

Oto kroki, które musisz wykonać, aby uniknąć obciążenia konta Google Cloud Platform opłatami za zasoby zużyte podczas krótkiego wprowadzenia:

  • Otwórz konsolę Cloud Platform.
  • Wybierz projekt, który chcesz wyłączyć, a następnie kliknij „Usuń” u góry ekranu. Spowoduje to zaplanowanie projektu do usunięcia.

Więcej informacji

Licencja

To zadanie jest licencjonowane na podstawie ogólnej licencji Creative Commons Attribution 2.0.