1. Omówienie
Ta seria ćwiczeń z programowania (do samodzielnego ukończenia, praktycznych samouczków) ma pomóc deweloperom w modernizacji aplikacji opartych na Google App Engine (w środowisku standardowym) przez przeprowadzenie serii migracji. Najważniejszym krokiem jest odejście od pierwotnych pakietów usług w ramach środowiska wykonawczego, ponieważ środowiska wykonawcze nowej generacji są bardziej elastyczne, co daje użytkownikom większą różnorodność opcji usług. Przejście na środowisko wykonawcze nowej generacji umożliwia łatwiejsze integrację z usługami Google Cloud, korzystanie z szerszego zakresu obsługiwanych usług i obsługę bieżących wersji językowych.
Ten opcjonalny samouczek pokazuje programistom, jak przejść z Cloud NDB do Cloud Datastore jako biblioteki klienta umożliwiającej komunikację z usługą Datastore. Deweloperzy, którzy wolą używać NDB, mogą z niego korzystać, ponieważ jest on zgodny z językiem Python 3, dlatego ta migracja jest opcjonalna. Ta migracja jest przeznaczona tylko dla tych, którzy chcą utworzyć spójną bazę kodu i biblioteki udostępnione innym aplikacjom, które już korzystają z Cloud Datastore. Zostało to wyjaśnione w „tle”. .
Dowiesz się,
- Użyj Cloud NDB (jeśli nie znasz tej usługi)
- Migracja z Cloud NDB do Cloud Datastore
- Przeprowadź migrację aplikacji do Pythona 3
Czego potrzebujesz
- projekt Google Cloud Platform z aktywnym kontem rozliczeniowym GCP,
- Podstawowe umiejętności w języku Python
- praktyczną znajomość podstawowych poleceń systemu Linux;
- Podstawowa wiedza na temat tworzenia i wdrażania aplikacji App Engine
- działającego modułu 2 App Engine 2.x lub 3.x,
Ankieta
Jak będziesz używać tego ćwiczenia z programowania?
2. Tło
Cloud NDB to świetne rozwiązanie Datastore dla wieloletnich programistów App Engine i pomocne w przejściu na Pythona 3, ale nie jedyny sposób, w jaki deweloperzy App Engine mogą uzyskać dostęp do Datastore. Gdy Datastore w 2013 roku w App Engine stał się własną usługą, w Google Cloud Datastore została utworzona nowa biblioteka klienta, dzięki której wszyscy użytkownicy mogą korzystać z Datastore.
Programiści korzystający z Pythona 3 App Engine i spoza App Engine są przekierowywani do używania Cloud Datastore (a nie Cloud NDB). Zachęcamy programistów App Engine korzystających z języka Python 2 do przejścia z ndb
do Cloud NDB i portu na Pythona 3, ale mogą także zdecydować się na dalszą migrację do Cloud Datastore. Jest to logiczna decyzja szczególnie dla programistów, którzy mają już kod w Cloud Datastore (np. omówiliśmy już dziś) i chcą tworzyć biblioteki współdzielone we wszystkich swoich aplikacjach. Ponowne używanie kodu to sprawdzona metoda, ponieważ zapewnia spójność kodu. Oba te elementy przyczyniają się do ogólnego zmniejszenia kosztów konserwacji, jak widać poniżej:
Migracja z Cloud NDB do Cloud Datastore
- Umożliwia programistom skupienie się na pojedynczej bazie kodu dla dostępu do Datastore
- Unikanie obsługi niektórych kodów przy użyciu Cloud NDB, a innych przy użyciu Cloud Datastore
- Zapewnia większą spójność w bazie kodu i lepsze ponowne wykorzystanie kodu
- Umożliwia korzystanie z bibliotek wspólnych lub wspólnych, co przekłada się na niższe ogólne koszty utrzymania.
Ta migracja obejmuje te główne kroki:
- Konfiguracja/praca
- Zastąp Cloud NDB bibliotekami klienta Cloud Datastore
- Aktualizuj aplikację
3. Konfiguracja/praca
Zanim przejdziemy do głównej części samouczka, skonfigurujmy projekt, pobierz kod, a potem wdróż aplikację bazową. Dzięki temu będziemy wiedzieć, że zaczynamy od działającego kodu.
1. Konfigurowanie projektu
Jeśli masz już za sobą moduł 2 z programowania, zalecamy ponowne wykorzystanie tego samego projektu (i kodu). Możesz też utworzyć nowy projekt lub wykorzystać inny istniejący projekt. Sprawdź, czy projekt ma aktywne konto rozliczeniowe i jest włączone (aplikacja) App Engine.
2. Pobierz przykładową aplikację bazową
Jednym z warunków wstępnych jest posiadanie działającej przykładowej aplikacji w module 2. Użyj rozwiązania, jeśli udało Ci się ukończyć samouczek. Możesz to zrobić teraz (link powyżej), a jeśli chcesz je pominąć, skopiuj repozytorium modułu 2 (link poniżej).
Zaczniemy od kodu modułu 2 niezależnie od tego, czy korzystasz z jego własnych czy naszych zasobów reklamowych. W ramach tego ćwiczenia w module 3 dowiesz się, jak wyglądają poszczególne kroki tego procesu. Po jego zakończeniu proces powinien przypominać kod w punkcie FINISH. Ten samouczek jest dostępny w wersjach Python 2 i 3, więc pobierz odpowiednie repozytorium kodu poniżej.
Python 2
- START: Kod modułu 2
- ZAKOŃCZ: Kod modułu 3
- Całe repozytorium (aby sklonować lub pobrać plik ZIP)
Katalog z plikami START (Twoimi lub naszym) modułu 2 w języku Python 2 powinien wyglądać tak:
$ ls
README.md appengine_config.py requirements.txt
app.yaml main.py templates
Jeśli udało Ci się ukończyć samouczek modułu 2, będziesz też mieć folder lib
z platformą Flask i jej zależnościami. Jeśli nie masz folderu lib
, utwórz go za pomocą polecenia pip install -t lib -r requirements.txt
, abyśmy mogli wdrożyć tę podstawową aplikację w następnym kroku. Jeśli masz zainstalowany język Python 2 i 3, zalecamy użycie pip2
zamiast pip
, aby uniknąć nieporozumień z Pythonem 3.
Python 3
- START: Repozytorium modułu 2
- ZAKOŃCZ: Repozytorium modułu 3
- Całe repozytorium (aby sklonować lub pobrać plik ZIP)
Katalog z plikami START (Twoimi lub naszym) modułu 2 w języku Python 3 powinien wyglądać tak:
$ ls
README.md main.py templates
app.yaml requirements.txt
W języku Python 3 nie jest używany ani lib
, ani appengine_config.py
.
3. Wdróż ponownie aplikację Moduł 2
Pozostałe kroki do wykonania:
- Ponownie zapoznaj się z narzędziem wiersza poleceń
gcloud
(w razie potrzeby) - (Ponowne) wdrożenie kodu modułu 1 w App Engine (jeśli to konieczne)
Gdy wykonasz te czynności i potwierdzisz, że wszystko działa, przejdziemy do kolejnego samouczka, zaczynając od plików konfiguracji.
4. Zastąp Cloud NDB bibliotekami klienta Cloud Datastore
Jedyną zmianą w konfiguracji jest drobna zamiana pakietów w pliku requirements.txt
.
1. Zaktualizuj: requirements.txt
Po ukończeniu modułu 2 Twój plik requirements.txt
wyglądał tak:
- PRZED (Python 2 i 3):
Flask==1.1.2
google-cloud-ndb==1.7.1
Zaktualizuj requirements.txt
, zastępując bibliotekę Cloud NDB (google-cloud-ndb
) najnowszą wersją biblioteki Cloud Datastore (google-cloud-datastore
). Pozostaw wpis dla Flask bez zmian. Pamiętaj, że ostateczna wersja Cloud Datastore zgodna z Pythonem 2 to wersja 1.15.3:
- PO (Python 2):
Flask==1.1.2
google-cloud-datastore==1.15.3
- PO (Python 3):
Flask==1.1.2
google-cloud-datastore==2.1.0
Pamiętaj, że repozytorium jest obsługiwane bardziej regularnie niż ten samouczek, więc może się zdarzyć, że plik requirements.txt
będzie odzwierciedlać nowsze wersje. Zalecamy używanie najnowszych wersji każdej biblioteki, ale jeśli to nie pomoże, możesz przywrócić starszą wersję. Powyższe numery wersji pochodzą z najnowszej daty ostatniej aktualizacji tego ćwiczenia z programowania.
2. Inne pliki konfiguracji
Pozostałe pliki konfiguracji (app.yaml
i appengine_config.py
) powinny pozostać niezmienione w porównaniu z poprzednim krokiem migracji:
- Pole
app.yaml
powinno (nadal) odwoływać się do pakietów innych firm (grpcio
isetuptools
). appengine_config.py
powinien (nadal) wskazywaćpkg_resources
igoogle.appengine.ext.vendor
zewnętrzne zasoby wlib
.
Teraz przejdźmy do plików aplikacji.
5. Aktualizacja plików aplikacji
template/index.html
nie ma żadnych zmian, ale mamy kilka aktualizacji dotyczących urządzenia main.py
.
1. Importy
Kod początkowy sekcji importowania powinien wyglądać tak:
- PRZED:
from flask import Flask, render_template, request
from google.cloud import ndb
Zastąp import google.cloud.ndb
jednym z nich dla Cloud Datastore: google.cloud.datastore
. Biblioteka klienta Datastore nie obsługuje automatycznego tworzenia pola sygnatury czasowej w elemencie, dlatego zaimportuj też standardowy moduł datetime
biblioteki, aby utworzyć go ręcznie. Zgodnie z konwencją importy z bibliotek standardowych są większe niż importy pakietów firm zewnętrznych. Po wprowadzeniu zmian powinno to wyglądać mniej więcej tak:
- PO:
from datetime import datetime
from flask import Flask, render_template, request
from google.cloud import datastore
2. Inicjalizacja i model danych
Po zainicjowaniu Flask przykładowa aplikacja z modułu 2 tworzy klasę modelu danych NDB i jej pola w ten sposób:
- PRZED:
app = Flask(__name__)
ds_client = ndb.Client()
class Visit(ndb.Model):
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
Biblioteka Cloud Datastore nie ma takiej klasy, więc usuń deklarację klasy Visit
. Aby komunikować się z Datastore, potrzebujesz klienta, więc zmień ndb.Client()
na datastore.Client()
. Biblioteka Datastore jest bardziej „elastyczna”, umożliwiając tworzenie elementów bez wcześniejszego zgłaszania taką jak NDB. Po tej aktualizacji ta część main.py
powinna wyglądać tak:
- PO:
app = Flask(__name__)
ds_client = datastore.Client()
3. Dostęp do Datastore
Migracja do Cloud Datastore wymaga zmiany sposobu tworzenia i przechowywania elementów Datastore oraz wysyłania do nich zapytań (na poziomie użytkownika). Trudność migracji w przypadku Twoich aplikacji zależy od tego, jak złożony jest kod Datastore. W naszej przykładowej aplikacji postaraliśmy się maksymalnie uprościć aktualizację. Oto nasz kod początkowy:
- PRZED:
def store_visit(remote_addr, user_agent):
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
with ds_client.context():
return (v.to_dict() for v in Visit.query().order(
-Visit.timestamp).fetch_page(limit)[0])
W Cloud Datastore utwórz encję ogólną, identyfikującą zgrupowane obiekty w elemencie za pomocą „klucza”. Utwórz rekord danych z obiektem JSON (Python dict
) zawierającym pary klucz-wartość, a następnie zapisz go w Datastore z oczekiwaną wartością put()
. Zapytania są podobne, ale prostsze w Datastore. Tutaj możesz zobaczyć, czym różni się odpowiedni kod Datastore:
- PO:
def store_visit(remote_addr, user_agent):
entity = datastore.Entity(key=ds_client.key('Visit'))
entity.update({
'timestamp': datetime.now(),
'visitor': '{}: {}'.format(remote_addr, user_agent),
})
ds_client.put(entity)
def fetch_visits(limit):
query = ds_client.query(kind='Visit')
query.order = ['-timestamp']
return query.fetch(limit=limit)
Zaktualizuj treść funkcji store_visit()
i fetch_visits()
w sposób opisany powyżej, zachowując ich podpisy identyczne jak w poprzedniej wersji. Główny moduł obsługi root()
nie ulega zmianie. Po wprowadzeniu tych zmian Twoja aplikacja jest gotowa do użycia w Cloud Datastore i jest gotowa do testów.
6. Podsumowanie/Czyszczenie
Wdróż aplikację
Wdróż ponownie aplikację za pomocą narzędzia gcloud app deploy
i sprawdź, czy działa. Twój kod powinien teraz odpowiadać zawartości folderów repozytorium w module 3:
Jeśli dołączysz do tej serii bez wykonania żadnego z poprzednich ćwiczeń z programowania, aplikacja się nie zmieni. rejestruje wszystkie odwiedziny głównej strony internetowej (/
) i wygląda tak po tym, jak kilka razy odwiedzisz witrynę:
Gratulujemy ukończenia modułu 3 ćwiczenia z programowania. Wiesz już, że aby uzyskać dostęp do Datastore, możesz używać zarówno bibliotek klienta Cloud NDB jak i Cloud Datastore. Przejście na drugą wersję pozwoliło uzyskać korzyści takie jak biblioteki współdzielone oraz powszechny kod i możliwość ponownego wykorzystania kodu, co pozwoli zapewnić spójność i obniżyć koszty utrzymania.
Opcjonalnie: wyczyść
A co z czyszczeniem, aby uniknąć opłat, dopóki nie wszystko będzie gotowe do przejścia do kolejnego ćwiczenia z programowania dotyczącego migracji? Jako obecni deweloperzy pewnie już znasz informacje o cenach w App Engine.
Opcjonalnie: wyłącz aplikację
Jeśli nie chcesz na razie przejść do następnego samouczka, wyłącz aplikację, aby uniknąć naliczania opłat. Gdy uznasz, że chcesz przejść do kolejnego ćwiczenia w programowaniu, możesz je ponownie włączyć. Gdy Twoja aplikacja jest wyłączona, nie generuje ona opłat za ruch, ale opłaty mogą być jednak naliczane za wykorzystanie magazynu danychw przypadku przekroczenia bezpłatnego limitu, więc usuń tyle miejsca, aby nie przekroczyć tego limitu.
Jeśli natomiast nie zamierzasz kontynuować migracji i chcesz całkowicie usunąć wszystko, możesz wyłączyć projekt.
Dalsze kroki
Tutaj możesz zapoznać się z kolejnymi modułami migracji:
- Bonus 3 – Bonus: Przejdź do sekcji poświęconej bonusom, aby dowiedzieć się, jak przenieść kod do Pythona 3 i środowiska wykonawczego App Engine nowej generacji.
- Moduł 7. Kolejki zadań App Engine (wymagane, jeśli korzystasz z kolejek zadań [push])
- Dodaje zadania push
taskqueue
w App Engine do aplikacji w module 1 - Przygotowuje użytkowników do migracji do Cloud Tasks w module 8.
- Dodaje zadania push
- Moduł 4: Migracja do Cloud Run z wykorzystaniem Dockera
- Konteneryzowanie aplikacji w celu uruchamiania jej w Cloud Run za pomocą Dockera
- Pozwala na pozostanie w Pythonie 2
- Moduł 5. Migracja do Cloud Run za pomocą pakietów Cloud Buildpacks
- Konteneryzowanie aplikacji na potrzeby uruchamiania jej w Cloud Run za pomocą pakietów Cloud Buildpack
- Nie muszą niczego wiedzieć o Dockerze, kontenerach ani
Dockerfile
. - Wymaga wcześniejszej migracji aplikacji do Pythona 3
- Moduł 6. Migracja do Cloud Firestore
- Przejdź na Cloud Firestore, aby uzyskać dostęp do funkcji Firebase
- Cloud Firestore obsługuje język Python 2, ale to ćwiczenia z programowania są dostępne tylko w Pythonie 3.
7. BONUS: przejdź na Pythona 3
Aby uzyskać dostęp do najnowszego środowiska wykonawczego i funkcji App Engine, zalecamy przejście na Pythona 3. W naszej przykładowej aplikacji Datastore był jedyną usługą wbudowaną, której użyliśmy, a ponieważ przeszliśmy z ndb
na Cloud NDB, możemy teraz przenieść port do środowiska wykonawczego Pythona 3 App Engine.
Omówienie
Chociaż portowanie do Pythona 3 nie jest częścią samouczka Google Cloud, ta część ćwiczenia w Codelabs pozwala programistom poznać różnice między środowiskiem wykonawczym App Engine w języku Python 3. Wyjątkową cechą środowiska wykonawczego nowej generacji jest uproszczony dostęp do pakietów innych firm: nie trzeba określać wbudowanych pakietów w app.yaml
ani kopiować lub przesyłać niewbudowanych bibliotek. są domyślnie instalowane z poziomu listy requirements.txt
.
Nasz przykład jest tak podstawowy a Cloud Datastore jest zgodny z językiem Python 2–3, więc żaden kod aplikacji nie musi być jawnie przeniesiony do wersji 3.x. Aplikacja działa na platformach 2.x i 3.x bez modyfikacji, co oznacza, że w tym przypadku wymagane zmiany są tylko w konfiguracji:
- Uprość kod
app.yaml
, aby odwoływać się do Pythona 3 i usunąć odniesienia do pakietów z bibliotekami innych firm. - Usuń
appengine_config.py
i folderlib
, ponieważ nie są już potrzebne.
Pliki aplikacji main.py
i templates/index.html
pozostają niezmienione.
Zaktualizuj: requirements.txt
Ostateczna wersja Cloud Datastore obsługująca Pythona 2 to 1.15.3. Zaktualizuj requirements.txt
do najnowszej wersji Pythona 3 (może być już nowsza). Po pisaniu tego samouczka najnowsza wersja to 2.1.0, dlatego zmień ten wiersz tak, aby wyglądał (lub w innej najnowszej wersji):
google-cloud-datastore==2.1.0
Uprość: app.yaml
PRZED:
Jedyną rzeczywistą zmianą w tej przykładowej aplikacji jest znaczne skrócenie wartości app.yaml
. Dla przypomnienia: oto, co wspomnieliśmy w app.yaml
module 3:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
PO:
W Pythonie 3 dyrektywy threadsafe
, api_version
i libraries
zostały wycofane. Wszystkie aplikacje są uznawane za bezpieczne wątkowo, a zasada api_version
nie jest używana w Pythonie 3. W usługach App Engine nie ma już wbudowanych pakietów innych firm, dlatego pakiet libraries
również został wycofany. Więcej informacji o tych zmianach znajdziesz w dokumentacji zmian w app.yaml
. W związku z tym usuń wszystkie 3 elementy z app.yaml
i zaktualizuj je do obsługiwanej wersji Pythona 3 (patrz poniżej).
Opcjonalnie: użycie dyrektywy handlers
Poza tym dyrektywa handlers
, która kieruje ruch do aplikacji App Engine, również została wycofana. Środowisko wykonawcze nowej generacji oczekuje, że platformy internetowe będą zarządzać routingiem aplikacji, dlatego wszystkie „skrypty obsługi” należy zmienić na „auto
”. Po połączeniu powyższych zmian otrzymasz następującą liczbę elementów app.yaml
:
runtime: python38
handlers:
- url: /.*
script: auto
Dowiedz się więcej o script: auto
ze strony referencyjnej app.yaml
.
Usuwam dyrektywę handlers
Ponieważ interfejs handlers
został wycofany, możesz też usunąć całą sekcję, pozostawiając jednowierszowy app.yaml
:
runtime: python38
Domyślnie uruchamiany jest serwer WWW Gunicorn WSGI, który jest dostępny dla wszystkich aplikacji. Jeśli znasz język gunicorn
, oto polecenie wykonywane, gdy jest uruchamiane domyślnie z bonusem app.yaml
:
gunicorn main:app --workers 2 -c /config/gunicorn.py
Opcjonalnie: użycie dyrektywy entrypoint
Jeśli jednak Twoja aplikacja wymaga konkretnego polecenia uruchamiania, można je podać za pomocą dyrektywy entrypoint
. W takim przypadku app.yaml
będzie wyglądać tak:
runtime: python38
entrypoint: python main.py
W tym przykładzie konkretnie zażądano użycia serwera programistycznego Flask zamiast gunicorn
. Kod uruchamiający serwer programistyczny należy również dodać do aplikacji w interfejsie 0.0.0.0
na porcie 8080. W tym celu dodaj tę małą sekcję na dole kodu main.py
:
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
Dowiedz się więcej o entrypoint
ze strony referencyjnej app.yaml
. Więcej przykładów i sprawdzonych metod znajdziesz w dokumentach dotyczących uruchamiania standardowego środowiska w App Engine oraz w dokumentach dotyczących uruchamiania elastycznego środowiska App Engine.
Usuń appengine_config.py
i lib
Usuń plik appengine_config.py
i folder lib
. Podczas migracji do Pythona 3 App Engine pozyskuje i instaluje pakiety wymienione w regionie requirements.txt
.
Plik konfiguracyjny appengine_config.py
służy do rozpoznawania bibliotek/pakietów innych firm, niezależnie od tego, czy zostały one skopiowane przez Ciebie, czy też używasz już istniejących na serwerach App Engine (wbudowanych). Podsumowanie najważniejszych zmian po przejściu do Pythona 3:
- Nie pakuję skopiowanych bibliotek innych firm (wymienionych w regionie
requirements.txt
) - Brak elementów
pip install
do folderulib
, co oznacza brak okresu folderulib
- Brak informacji o wbudowanych bibliotekach innych firm w
app.yaml
- Nie trzeba odwoływać się do bibliotek innych firm, więc nie ma pliku
appengine_config.py
Wystarczy, że umieścisz w pliku requirements.txt
listę wszystkich wymaganych bibliotek innych firm.
Wdróż aplikację
Wdróż aplikację ponownie, aby sprawdzić, czy działa. Możesz też sprawdzić, jak blisko Twojego rozwiązania jest przykładowy kod w module 3 w Pythonie 3. Aby zwizualizować różnice w stosunku do języka Python 2, porównaj ten kod z jego wersją w języku Python 2.
Gratulacje! Udało Ci się ukończyć bonusowy krok w module 3. Zapoznaj się z dokumentacją dotyczącą przygotowywania plików konfiguracji na potrzeby środowiska wykonawczego Pythona 3. Przejrzyj wcześniejsze podsumowanie powyżej, aby dowiedzieć się, co zrobić dalej i jak wyczyścić dane.
Przygotowywanie Twojej aplikacji
Przy migrowaniu swojej aplikacji trzeba będzie przenieść main.py
i inne pliki aplikacji do wersji 3.x, więc najlepiej jest postarać się, aby aplikacja 2.x była „zgodna do przekazywania dalej”. jak to tylko możliwe.
W internecie znajdziesz wiele materiałów, które Ci w tym pomogą. Oto kilka najważniejszych wskazówek:
- Sprawdź, czy wszystkie zależności aplikacji są w pełni zgodne z wersją 3.x
- Upewnij się, że aplikacja działa w wersji 2.6 (najlepiej 2.7).
- Sprawdź, czy aplikacja przeszła cały pakiet testów (i co najmniej 80% pokrycia)
- Używaj bibliotek zgodności, takich jak
six
, Future lub Modernize - Zdobądź wiedzę na temat niekompatybilności wstecznej kluczy w wersjach 2.x i 3.x
- Każde wejście/wyjście prawdopodobnie prowadzi do niezgodności z Unicode i ciągami bajtów.
Właśnie dlatego została opracowana przykładowa aplikacja, dlatego działa na 2.x i 3.x.
8. Dodatkowe materiały
Problemy/opinie dotyczące modułu migracji App Engine
Jeśli podczas korzystania z tych ćwiczeń z programowania zauważysz jakiekolwiek problemy, najpierw je wyszukaj. Linki do wyszukiwania i tworzenia nowych problemów:
Zasoby migracji
Linki do folderów repozytorium w modułach 2 (START) i modułach 3 (FINISH) znajdziesz w tabeli poniżej. Dostęp do nich możesz też uzyskać z repozytorium wszystkich migracji App Engine, które możesz sklonować lub pobrać w postaci pliku ZIP.
Codelab | Python 2 | Python 3 |
Część 3 |
Zasoby App Engine
Poniżej znajdziesz dodatkowe materiały na temat tej migracji:
- Odwołania do Pythona Cloud NDB i Cloud Datastore:
- Migracja do środowiska wykonawczego nowej generacji w Pythonie 3 i GAE
- Ogólne