Jak korzystać z biblioteki blobstore w App Engine (moduł 15)

1. Przegląd

Seria ćwiczeń z programowania Serverless Migration Station (samodzielne, praktyczne samouczki) i powiązane filmy mają na celu pomóc deweloperom bezserwerowych rozwiązań Google Cloud w modernizacji aplikacji przez przeprowadzenie ich przez co najmniej 1 migrację, głównie odchodząc od starszych usług. Dzięki temu aplikacje są bardziej przenośne, a Ty masz więcej opcji i większą elastyczność, co umożliwia integrację z szerszą gamą usług Cloud i dostęp do nich, a także łatwiejsze uaktualnianie do nowszych wersji językowych. Chociaż początkowo skupiamy się na najwcześniejszych użytkownikach Cloud, głównie deweloperach App Engine (środowisko standardowe), ta seria jest na tyle szeroka, że obejmuje inne platformy bezserwerowe, takie jak Cloud Functions i Cloud Run, lub inne, jeśli ma to zastosowanie.

To ćwiczenie z modułu 15 wyjaśnia, jak dodać korzystanie z App Engine blobstore do przykładowej aplikacji z modułu 0. Następnie w module 16 dowiesz się, jak przenieść to wykorzystanie do Cloud Storage.

Dowiesz się, jak:

  • Dodanie interfejsu API lub biblioteki Blobstore w App Engine
  • Przechowuj pliki przesyłane przez użytkowników w usłudze blobstore
  • Przygotowanie do kolejnego kroku migracji do Cloud Storage

Czego potrzebujesz

Ankieta

Jak będziesz korzystać z tego samouczka?

Tylko przeczytam Przeczytam i wykonam ćwiczenia

Jak oceniasz swoje doświadczenie z Pythonem?

Początkujący Średnio zaawansowany Zaawansowany

Jak oceniasz swoje wrażenia z korzystania z usług Google Cloud?

Początkujący Średnio zaawansowany Zaawansowany

2. Tło

Aby przeprowadzić migrację z interfejsu Blobstore API w App Engine, dodaj jego użycie do istniejącej podstawowej aplikacji App Engine ndb z modułu 0. Przykładowa aplikacja wyświetla 10 ostatnich wizyt użytkownika. Modyfikujemy aplikację, aby prosiła użytkownika o przesłanie artefaktu (pliku) odpowiadającego jego „wizycie”. Jeśli użytkownik nie chce tego zrobić, może wybrać opcję „Pomiń”. Niezależnie od decyzji użytkownika na następnej stronie wyświetlane są te same dane wyjściowe co w aplikacji z modułu 0 (i wielu innych modułów z tej serii). Po wdrożeniu integracji App Engine z blobstore możemy przeprowadzić migrację do Cloud Storage w następnym ćwiczeniu (moduł 16).

App Engine zapewnia dostęp do systemów szablonów Django i Jinja2. Jedną z rzeczy, które odróżniają ten przykład (oprócz dodania dostępu do Blobstore), jest to, że w module 15 przechodzi on z Django w module 0 na Jinja2. Kluczowym krokiem w modernizacji aplikacji App Engine jest migracja platform internetowych z webapp2 do Flask. Ten ostatni używa Jinja2 jako domyślnego systemu szablonów, więc zaczynamy zmierzać w tym kierunku, wdrażając Jinja2, ale pozostając przy webapp2 w celu uzyskania dostępu do Blobstore. Flask domyślnie używa Jinja2, więc w module 16 nie trzeba będzie wprowadzać żadnych zmian w szablonie.

3. Konfiguracja/przygotowanie

Zanim przejdziemy do głównej części samouczka, skonfiguruj projekt, pobierz kod i wdróż aplikację bazową, aby zacząć od działającego kodu.

1. Konfigurowanie projektu

Jeśli aplikacja z modułu 0 została już wdrożona, zalecamy ponowne użycie tego samego projektu (i kodu). Możesz też utworzyć zupełnie nowy projekt lub użyć innego istniejącego projektu. Sprawdź, czy projekt ma aktywne konto rozliczeniowe i czy usługa App Engine jest włączona.

2. Pobieranie przykładowej aplikacji bazowej

Jednym z wymagań wstępnych tego ćwiczenia jest działająca przykładowa aplikacja z modułu 0. Jeśli jej nie masz, możesz ją pobrać z folderu „START” modułu 0 (link poniżej). W tym ćwiczeniu przeprowadzimy Cię przez każdy krok, a na koniec otrzymasz kod podobny do tego, który znajduje się w folderze „FINISH” modułu 15.

Katalog plików START modułu 0 powinien wyglądać tak:

$ ls
README.md               index.html
app.yaml                main.py

3. (Ponowne) wdrażanie aplikacji bazowej

Pozostałe czynności przygotowawcze, które należy wykonać:

  1. Przypomnij sobie, jak działa narzędzie wiersza poleceń gcloud.
  2. Ponowne wdrażanie przykładowej aplikacji za pomocą gcloud app deploy
  3. Sprawdzanie, czy aplikacja działa w App Engine bez problemów

Gdy wykonasz te czynności i zobaczysz, że aplikacja internetowa działa (z danymi wyjściowymi podobnymi do poniższych), możesz dodać do niej pamięć podręczną.

a7a9d2b80d706a2b.png

4. Aktualizowanie plików konfiguracji

app.yaml

Nie ma żadnych istotnych zmian w konfiguracji aplikacji, ale jak wspomnieliśmy wcześniej, przechodzimy z szablonów Django (domyślnych) na Jinja2. Aby dokonać zmiany, użytkownicy powinni określić najnowszą wersję Jinja2 dostępną na serwerach App Engine, dodając ją do sekcji wbudowanych bibliotek innych firm w pliku app.yaml.

PRZED:

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

Zmodyfikuj plik app.yaml, dodając nową sekcję libraries, jak pokazano poniżej:

AFTER:

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

libraries:
- name: jinja2
  version: latest

Nie trzeba aktualizować żadnych innych plików konfiguracji, więc przejdźmy do plików aplikacji.

5. Modyfikowanie plików aplikacji

Obsługa importu i Jinja2

Pierwszy zestaw zmian w aplikacji main.py obejmuje dodanie interfejsu Blobstore API i zastąpienie szablonów Django szablonami Jinja2. Co się zmienia:

  1. Moduł os służy do tworzenia ścieżki do pliku szablonu Django. Przechodzimy na Jinja2, gdzie jest to obsługiwane, więc użycie os oraz mechanizmu renderowania szablonów Django, google.appengine.ext.webapp.template, nie jest już potrzebne, dlatego zostaną one usunięte.
  2. Zaimportuj interfejs Blobstore API: google.appengine.ext.blobstore
  3. Zaimportuj moduły obsługi Blobstore znalezione w pierwotnej platformie webapp – nie są one dostępne w webapp2: google.appengine.ext.webapp.blobstore_handlers
  4. Zaimportuj obsługę Jinja2 z pakietu webapp2_extras.

PRZED:

import os
import webapp2
from google.appengine.ext import ndb
from google.appengine.ext.webapp import template

Wprowadź zmiany z listy powyżej, zastępując bieżącą sekcję importu w pliku main.py poniższym fragmentem kodu.

AFTER:

import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers

Po importach dodaj powtarzalny kod, który umożliwi korzystanie z Jinja2 zgodnie z opisem w dokumentacji webapp2_extras. Poniższy fragment kodu opakowuje standardową klasę modułu obsługi żądań webapp2 funkcjami Jinja2, więc dodaj ten blok kodu do pliku main.py zaraz po importach:

class BaseHandler(webapp2.RequestHandler):
    'Derived request handler mixing-in Jinja2 support'
    @webapp2.cached_property
    def jinja2(self):
        return jinja2.get_jinja2(app=self.app)

    def render_response(self, _template, **context):
        self.response.write(self.jinja2.render_template(_template, **context))

Dodawanie obsługi Blobstore

W przeciwieństwie do innych migracji z tej serii, w których zachowujemy funkcjonalność lub dane wyjściowe przykładowej aplikacji (lub prawie takie same) bez (większych) zmian w UX, ten przykład jest bardziej radykalnym odejściem od normy. Zamiast natychmiast rejestrować nową wizytę, a następnie wyświetlać 10 ostatnich, aktualizujemy aplikację, aby prosiła użytkownika o plik, za pomocą którego zarejestruje wizytę. Użytkownicy mogą przesłać odpowiedni plik lub wybrać „Pomiń”, aby nic nie przesyłać. Po wykonaniu tego kroku wyświetli się strona „Ostatnie wizyty”.

Dzięki tej zmianie nasza aplikacja może używać usługi Blobstore do przechowywania (i ewentualnie późniejszego renderowania) tego obrazu lub innego typu pliku na stronie ostatnich wizyt.

Zaktualizuj model danych i wdroż jego użycie

Przechowujemy więcej danych, a konkretnie aktualizujemy model danych, aby przechowywać identyfikator (nazywany „BlobKey”) pliku przesłanego do Blobstore i dodajemy odwołanie, aby zapisać go w store_visit(). Te dodatkowe dane są zwracane wraz z innymi danymi w odpowiedzi na zapytanie, więc fetch_visits() pozostaje bez zmian.

Oto porównanie przed i po wprowadzeniu tych zmian na przykładzie file_blob, ndb.BlobKeyProperty:

PRZED:

class Visit(ndb.Model):
    'Visit entity registers visitor IP address & timestamp'
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)

def store_visit(remote_addr, user_agent):
    'create new Visit entity in Datastore'
    Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

def fetch_visits(limit):
    'get most recent visits'
    return Visit.query().order(-Visit.timestamp).fetch(limit)

AFTER:

class Visit(ndb.Model):
    'Visit entity registers visitor IP address & timestamp'
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)
    file_blob = ndb.BlobKeyProperty()

def store_visit(remote_addr, user_agent, upload_key):
    'create new Visit entity in Datastore'
    Visit(visitor='{}: {}'.format(remote_addr, user_agent),
            file_blob=upload_key).put()

def fetch_visits(limit):
    'get most recent visits'
    return Visit.query().order(-Visit.timestamp).fetch(limit)

Oto graficzne przedstawienie zmian, które zostały wprowadzone do tej pory:

2270783776759f7f.png

Obsługa przesyłania plików

Najważniejszą zmianą w funkcjonalności jest obsługa przesyłania plików, niezależnie od tego, czy chodzi o proszenie użytkownika o plik, obsługę funkcji „pomiń” czy renderowanie pliku odpowiadającego wizycie. Wszystko to jest częścią obrazu. Aby umożliwić przesyłanie plików, musisz wprowadzić te zmiany:

  1. Żądanie głównego modułu obsługi GET nie pobiera już najnowszych wizyt do wyświetlenia. Zamiast tego prosi użytkownika o przesłanie pliku.
  2. Gdy użytkownik przesyła plik lub pomija ten proces, POST z formularza przekazuje kontrolę do nowego UploadHandler, pochodzącego z google.appengine.ext.webapp.blobstore_handlers.BlobstoreUploadHandler.
  3. Metoda POST klasy UploadHandler przesyła plik, wywołuje metodę store_visit(), aby zarejestrować wizytę, i wyzwala przekierowanie HTTP 307, aby odesłać użytkownika z powrotem do „/”, gdzie…
  4. Metoda POST głównego modułu obsługi wysyła zapytanie (za pomocą fetch_visits()) i wyświetla ostatnie wizyty. Jeśli użytkownik wybierze „Pomiń”, plik nie zostanie przesłany, ale wizyta zostanie zarejestrowana, a następnie nastąpi przekierowanie.
  5. Wyświetlane ostatnie wizyty zawierają nowe pole, które jest widoczne dla użytkownika. Jest to hiperlink „Wyświetl”, jeśli plik do przesłania jest dostępny, lub „Brak”, jeśli nie jest dostępny. Te zmiany zostaną wprowadzone w szablonie HTML wraz z dodaniem formularza przesyłania (więcej informacji na ten temat: Już wkrótce).
  6. Jeśli użytkownik kliknie link „Wyświetl” w przypadku wizyty z przesłanym filmem, wysyła żądanie GET do nowego ViewBlobHandler, pochodzącego z google.appengine.ext.webapp.blobstore_handlers.BlobstoreDownloadHandler, które renderuje plik, jeśli jest to obraz (w przeglądarce, jeśli jest obsługiwany), wyświetla prośbę o pobranie, jeśli nie, lub zwraca błąd HTTP 404, jeśli nie zostanie znaleziony.
  7. Oprócz nowej pary klas modułów obsługi i nowej pary tras do wysyłania do nich ruchu główny moduł obsługi potrzebuje nowej metody POST, aby otrzymywać opisane powyżej przekierowanie 307.

Przed wprowadzeniem tych zmian aplikacja z modułu 0 zawierała tylko główny moduł obsługi z metodą GET i jedną trasą:

PRZED:

class MainHandler(webapp2.RequestHandler):
    'main application (GET) handler'
    def get(self):
        store_visit(self.request.remote_addr, self.request.user_agent)
        visits = fetch_visits(10)
        tmpl = os.path.join(os.path.dirname(__file__), 'index.html')
        self.response.out.write(template.render(tmpl, {'visits': visits}))

app = webapp2.WSGIApplication([
    ('/', MainHandler),
], debug=True)

Po wprowadzeniu tych zmian mamy teraz 3 moduły obsługi: 1) moduł obsługi przesyłania z metodą POST, 2) moduł obsługi pobierania „view blob” z metodą GET oraz 3) główny moduł obsługi z metodami GET i POST. Wprowadź te zmiany, aby reszta aplikacji wyglądała tak jak poniżej.

AFTER:

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    'Upload blob (POST) handler'
    def post(self):
        uploads = self.get_uploads()
        blob_id = uploads[0].key() if uploads else None
        store_visit(self.request.remote_addr, self.request.user_agent, blob_id)
        self.redirect('/', code=307)

class ViewBlobHandler(blobstore_handlers.BlobstoreDownloadHandler):
    'view uploaded blob (GET) handler'
    def get(self, blob_key):
        self.send_blob(blob_key) if blobstore.get(blob_key) else self.error(404)

class MainHandler(BaseHandler):
    'main application (GET/POST) handler'
    def get(self):
        self.render_response('index.html',
                upload_url=blobstore.create_upload_url('/upload'))

    def post(self):
        visits = fetch_visits(10)
        self.render_response('index.html', visits=visits)

app = webapp2.WSGIApplication([
    ('/', MainHandler),
    ('/upload', UploadHandler),
    ('/view/([^/]+)?', ViewBlobHandler),
], debug=True)

W dodanym kodzie znajduje się kilka kluczowych wywołań:

  • W funkcji MainHandler.get znajduje się wywołanie funkcji blobstore.create_upload_url. To wywołanie generuje adres URL, do którego formularz wysyła żądanie POST, wywołując moduł obsługi przesyłania, aby wysłać plik do Blobstore.
  • W funkcji UploadHandler.post znajduje się wywołanie funkcji blobstore_handlers.BlobstoreUploadHandler.get_uploads. To jest prawdziwa magia, która umieszcza plik w Blobstore i zwraca unikalny i trwały identyfikator tego pliku, czyli BlobKey.
  • W ViewBlobHandler.get wywołanie blobstore_handlers.BlobstoreDownloadHandler.send z BlobKey pliku powoduje pobranie pliku i przekazanie go do przeglądarki użytkownika

Te wywołania stanowią większość dostępu do funkcji dodanych do aplikacji. Oto graficzne przedstawienie drugiego i ostatniego zestawu zmian w aplikacji main.py:

da2960525ac1b90d.png

Aktualizowanie szablonu HTML

Niektóre aktualizacje głównej aplikacji wpływają na jej interfejs, dlatego w szablonie internetowym trzeba wprowadzić odpowiednie zmiany. Są to 2 modyfikacje:

  1. Wymagany jest formularz przesyłania pliku z 3 elementami wejściowymi: plikiem i parą przycisków przesyłania, odpowiednio do przesyłania pliku i pomijania.
  2. Zaktualizuj dane wyjściowe dotyczące ostatnich wizyt, dodając link „Wyświetl” w przypadku wizyt z odpowiednim przesłanym plikiem lub „Brak” w przeciwnym razie.

PRZED:

<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>

<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
    <li>{{ visit.timestamp.ctime }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>

</body>
</html>

Wprowadź zmiany z listy powyżej, aby utworzyć zaktualizowany szablon:

AFTER:

<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>

<h1>VisitMe example</h1>
{% if upload_url %}

<h3>Welcome... upload a file? (optional)</h3>
<form action="{{ upload_url }}" method="POST" enctype="multipart/form-data">
    <input type="file" name="file"><p></p>
    <input type="submit"> <input type="submit" value="Skip">
</form>

{% else %}

<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }}
    <i><code>
    {% if visit.file_blob %}
        (<a href="/view/{{ visit.file_blob }}" target="_blank">view</a>)
    {% else %}
        (none)
    {% endif %}
    </code></i>
    from {{ visit.visitor }}
</li>
{% endfor %}
</ul>

{% endif %}

</body>
</html>

Ten obraz przedstawia wymagane aktualizacje index.html:

8583e975f25aa9e7.png

Ostatnia zmiana polega na tym, że Jinja2 preferuje szablony w folderze templates, więc utwórz ten folder i przenieś do niego plik index.html. To ostatnia zmiana, którą musisz wprowadzić, aby dodać Blobstore do przykładowej aplikacji z modułu 0.

(opcjonalnie) „Ulepszenie” Cloud Storage

Z czasem Blobstore przekształcił się w Cloud Storage. Oznacza to, że przesłane pliki Blobstore są widoczne w konsoli Cloud, a konkretnie w przeglądarce Cloud Storage. Pytanie brzmi: gdzie? Odpowiedź brzmi: domyślny zasobnik Cloud Storage aplikacji App Engine. Jego nazwa to pełna nazwa domeny aplikacji App Engine, PROJECT_ID.appspot.com. To bardzo wygodne, ponieważ wszystkie identyfikatory projektów są unikalne.

Aktualizacje wprowadzone w przykładowej aplikacji powodują, że przesłane pliki trafiają do tego zasobnika, ale deweloperzy mogą wybrać bardziej konkretną lokalizację. Domyślny zasobnik jest dostępny programowo przez google.appengine.api.app_identity.get_default_gcs_bucket_name(), co wymaga nowego importu, jeśli chcesz uzyskać dostęp do tej wartości, np. aby użyć jej jako prefiksu do porządkowania przesłanych plików. Na przykład sortowanie według typu pliku:

f61f7a23a1518705.png

Aby zaimplementować coś takiego na przykład w przypadku obrazów, użyj kodu podobnego do tego, który sprawdza typy plików, aby wybrać żądaną nazwę zasobnika:

ROOT_BUCKET = app_identity.get_default_gcs_bucket_name()
IMAGE_BUCKET = '%s/%s' % (ROOT_BUCKET, 'images')

Przesłane obrazy sprawdzisz też za pomocą narzędzia takiego jak moduł imghdr biblioteki standardowej Pythona, aby potwierdzić typ obrazu. Na koniec warto ograniczyć rozmiar przesyłanych plików na wypadek, gdyby ktoś chciał przesłać coś niepożądanego.

Załóżmy, że wszystkie te czynności zostały wykonane. Jak możemy zaktualizować naszą aplikację, aby obsługiwała określanie miejsca przechowywania przesłanych plików? Kluczem jest zmodyfikowanie wywołania blobstore.create_upload_url w MainHandler.get, aby określić żądaną lokalizację w Cloud Storage na potrzeby przesyłania, przez dodanie parametru gs_bucket_name w ten sposób:

blobstore.create_upload_url('/upload', gs_bucket_name=IMAGE_BUCKET))

Jest to opcjonalna aktualizacja, jeśli chcesz określić, gdzie mają być przesyłane pliki, więc nie jest ona częścią pliku main.py w repozytorium. Zamiast tego w repozytorium dostępna jest alternatywa o nazwie main-gcs.py. Zamiast używać osobnego „folderu” zasobnika, kod w main-gcs.py przechowuje przesłane pliki w zasobniku „głównym” (PROJECT_ID.appspot.com) tak jak main.py, ale zapewnia rusztowanie, którego potrzebujesz, jeśli chcesz przekształcić próbkę w coś więcej, jak sugerowano w tej sekcji. Poniżej znajdziesz ilustrację przedstawiającą różnice między main.py a main-gcs.py.

256e1ea68241a501.png

6. Podsumowanie i czyszczenie

W tej sekcji podsumujemy ćwiczenia z programowania, wdrażając aplikację i sprawdzając, czy działa zgodnie z oczekiwaniami i czy dane wyjściowe są prawidłowe. Po sprawdzeniu aplikacji wykonaj czynności związane z czyszczeniem i zastanów się nad kolejnymi krokami.

Wdrażanie i weryfikowanie aplikacji

Ponownie wdróż aplikację za pomocą gcloud app deploy i sprawdź, czy działa zgodnie z opisem, różniąc się od aplikacji z modułu 0 pod względem wrażeń użytkownika. Aplikacja ma teraz 2 różne ekrany. Pierwszy to prośba o przesłanie pliku:

f5b5f9f19d8ae978.pngUżytkownicy mogą przesłać plik i kliknąć „Prześlij” lub kliknąć „Pomiń”, aby nic nie przesyłać. W obu przypadkach wyświetli się ekran ostatniej wizyty, który teraz zawiera linki „Wyświetl” lub „Brak” między sygnaturami czasowymi wizyty a informacjami o użytkowniku:

f5ac6b98ee8a34cb.png

Gratulujemy ukończenia tego ćwiczenia z programowania, w którym dodaliśmy Blobstore w App Engine do przykładowej aplikacji z modułu 0. Twój kod powinien teraz odpowiadać zawartości folderu FINISH (moduł 15). W tym folderze znajduje się też alternatywny plik main-gcs.py.

Czyszczenie danych

Ogólne

Jeśli na razie nie chcesz kontynuować, zalecamy wyłączenie aplikacji App Engine, aby uniknąć naliczania opłat. Jeśli jednak chcesz przeprowadzić więcej testów lub eksperymentów, platforma App Engine ma bezpłatny limit, więc dopóki nie przekroczysz tego poziomu wykorzystania, nie powinny być naliczane opłaty. To są koszty obliczeń, ale mogą też zostać naliczone opłaty za odpowiednie usługi App Engine, więc więcej informacji znajdziesz na stronie z cennikiem. Jeśli migracja obejmuje inne usługi Cloud, są one rozliczane osobno. W obu przypadkach zapoznaj się z sekcją „Informacje dotyczące tego ćwiczenia” poniżej.

Warto wiedzieć, że wdrożenie na bezserwerowej platformie obliczeniowej Google Cloud, takiej jak App Engine, wiąże się z niewielkimi kosztami kompilacji i przechowywania danych. Cloud Build ma własny bezpłatny limit, podobnie jak Cloud Storage. Przechowywanie tego obrazu wykorzystuje część tego limitu. Możesz jednak mieszkać w regionie, w którym nie ma takiego poziomu bezpłatnego, więc zwracaj uwagę na wykorzystanie miejsca na dane, aby zminimalizować potencjalne koszty. Konkretne „foldery” Cloud Storage, które należy sprawdzić, to:

  • console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
  • console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
  • Linki do miejsca przechowywania powyżej zależą od PROJECT_ID i *LOC*ation, na przykład „us”, jeśli aplikacja jest hostowana w USA.

Jeśli jednak nie zamierzasz kontynuować pracy z tą aplikacją ani innymi powiązanymi z nią programami do migracji i chcesz usunąć wszystko, zamknij projekt.

Dotyczy tego ćwiczenia

Usługi wymienione poniżej są unikalne dla tego ćwiczenia z programowania. Więcej informacji znajdziesz w dokumentacji poszczególnych usług:

Dalsze kroki

Kolejna logiczna migracja, którą warto rozważyć, jest opisana w module 16. Pokazuje ona deweloperom, jak przejść z usługi Blobstore w App Engine na bibliotekę klienta Cloud Storage. Korzyści z uaktualnienia obejmują dostęp do większej liczby funkcji Cloud Storage, zapoznanie się z biblioteką klienta, która działa w aplikacjach poza App Engine, zarówno w Google Cloud, innych chmurach, jak i lokalnie. Jeśli nie potrzebujesz wszystkich funkcji dostępnych w Cloud Storage lub obawiasz się, że wpłynie to na koszty, możesz pozostać przy blobstore w App Engine.

Po module 16 dostępnych jest wiele innych możliwych migracji, takich jak Cloud NDB i Cloud Datastore, Cloud Tasks czy Cloud Memorystore. Dostępne są też migracje między usługami do Cloud Run i Cloud Functions. Repozytorium migracji zawiera wszystkie przykładowe kody, linki do wszystkich dostępnych ćwiczeń programistycznych i filmów, a także wskazówki dotyczące migracji, które warto rozważyć, oraz odpowiednią „kolejność” migracji.

7. Dodatkowe materiały

Problemy z ćwiczeniami w Codelabs / opinie na ich temat

Jeśli znajdziesz jakieś problemy z tym ćwiczeniem, najpierw wyszukaj je, zanim je zgłosisz. Linki do wyszukiwania i tworzenia nowych zgłoszeń:

Materiały dotyczące migracji

Linki do folderów repozytorium dla modułu 0 (START) i modułu 15 (FINISH) znajdziesz w tabeli poniżej. Możesz też uzyskać do nich dostęp z repozytorium wszystkich migracji w ramach programu App Engine codelab, które możesz sklonować lub pobrać jako plik ZIP.

Codelab

Python 2

Python 3

Część 0.

kod

Nie dotyczy

Moduł 15 (to ćwiczenie)

kod

Nie dotyczy

Zasoby internetowe

Poniżej znajdziesz zasoby online, które mogą być przydatne w tym samouczku:

App Engine

Google Cloud

Python

Filmy

Licencja

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