Cara menggunakan blobstore App Engine (Modul 15)

1. Ringkasan

Seri codelab Serverless Migration Station (tutorial interaktif mandiri) dan video terkait bertujuan untuk membantu developer serverless Google Cloud memodernisasi aplikasi mereka dengan memandu mereka melalui satu atau beberapa migrasi, terutama beralih dari layanan lama. Dengan begitu, aplikasi Anda akan lebih portabel dan Anda akan memiliki lebih banyak opsi dan fleksibilitas, sehingga Anda dapat berintegrasi dengan dan mengakses berbagai produk Cloud yang lebih luas serta lebih mudah mengupgrade ke rilis bahasa yang lebih baru. Meskipun awalnya berfokus pada pengguna Cloud paling awal, terutama developer App Engine (lingkungan standar), seri ini cukup luas untuk mencakup platform serverless lainnya seperti Cloud Functions dan Cloud Run, atau di tempat lain jika berlaku.

Codelab Modul 15 ini menjelaskan cara menambahkan penggunaan blobstore App Engine ke aplikasi contoh dari Modul 0. Kemudian, Anda akan siap untuk memigrasikan penggunaan tersebut ke Cloud Storage di Modul 16.

Anda akan mempelajari cara

  • Menambahkan penggunaan App Engine Blobstore API/library
  • Menyimpan upload pengguna ke layanan blobstore
  • Bersiap untuk langkah berikutnya guna bermigrasi ke Cloud Storage

Yang Anda butuhkan

Survei

Bagaimana Anda akan menggunakan tutorial ini?

Hanya membacanya Membacanya dan menyelesaikan latihan

Bagaimana penilaian Anda terhadap pengalaman dengan Python?

Pemula Menengah Mahir

Bagaimana penilaian Anda terhadap pengalaman menggunakan layanan Google Cloud?

Pemula Menengah Mahir

2. Latar belakang

Untuk bermigrasi dari App Engine Blobstore API, tambahkan penggunaannya ke aplikasi ndb App Engine dasar yang ada dari Modul 0. Aplikasi contoh menampilkan sepuluh kunjungan terbaru kepada pengguna. Kami memodifikasi aplikasi untuk meminta pengguna akhir mengupload artefak (file) yang sesuai dengan "kunjungan" mereka. Jika pengguna tidak ingin melakukannya, ada opsi "lewati". Terlepas dari keputusan pengguna, halaman berikutnya akan merender output yang sama dengan aplikasi dari Modul 0 (dan banyak modul lainnya dalam seri ini). Setelah integrasi blobstore App Engine ini diterapkan, kita dapat memigrasikannya ke Cloud Storage di codelab berikutnya (Modul 16).

App Engine menyediakan akses ke sistem template Django dan Jinja2, dan satu hal yang membuat contoh ini berbeda (selain menambahkan akses Blobstore) adalah beralih dari penggunaan Django di Modul 0 ke Jinja2 di Modul 15 ini. Langkah penting dalam memodernisasi aplikasi App Engine adalah memigrasikan framework web dari webapp2 ke Flask. Framework yang kedua menggunakan Jinja2 sebagai sistem template default-nya, jadi kita mulai beralih ke arah tersebut dengan menerapkan Jinja2 sambil tetap menggunakan webapp2 untuk akses Blobstore. Karena Flask menggunakan Jinja2 secara default, berarti tidak ada perubahan pada template yang akan diperlukan di Modul 16.

3. Penyiapan/Prakerja

Sebelum kita masuk ke bagian utama tutorial, siapkan project Anda, dapatkan kodenya, dan deploy aplikasi dasar pengukuran untuk memulai dengan kode yang berfungsi.

1. Siapkan project

Jika Anda sudah men-deploy aplikasi Modul 0, sebaiknya gunakan kembali project (dan kode) yang sama. Atau, Anda dapat membuat project baru atau menggunakan kembali project lain yang sudah ada. Pastikan project memiliki akun penagihan yang aktif dan App Engine diaktifkan.

2. Dapatkan aplikasi contoh dasar pengukuran

Salah satu prasyarat untuk codelab ini adalah memiliki aplikasi contoh Modul 0 yang berfungsi. Jika belum memilikinya, Anda bisa mendapatkannya dari folder "START" Modul 0 (link di bawah). Codelab ini akan memandu Anda melalui setiap langkah, yang diakhiri dengan kode yang mirip dengan yang ada di folder "FINISH" Modul 15.

Direktori file START Modul 0 akan terlihat seperti ini:

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

3. Deploy (ulang) aplikasi dasar pengukuran

Langkah prakerja yang tersisa untuk dijalankan sekarang:

  1. Biasakan kembali diri Anda dengan alat command-line gcloud
  2. Deploy kembali aplikasi contoh dengan gcloud app deploy
  3. Konfirmasikan bahwa aplikasi berjalan di App Engine tanpa masalah

Setelah berhasil menjalankan langkah-langkah tersebut dan melihat aplikasi web Anda berfungsi (dengan output yang mirip dengan di bawah), Anda siap menambahkan penggunaan caching ke aplikasi Anda.

a7a9d2b80d706a2b.png

4. Update file konfigurasi

app.yaml

Tidak ada perubahan signifikan pada konfigurasi aplikasi, tetapi seperti yang disebutkan sebelumnya, kami beralih dari template Django (default) ke Jinja2. Jadi, untuk beralih, pengguna harus menentukan versi terbaru Jinja2 yang tersedia di server App Engine, dan Anda melakukannya dengan menambahkannya ke bagian library pihak ketiga bawaan di app.yaml.

BEFORE:

runtime: python27
threadsafe: yes
api_version: 1

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

Edit file app.yaml Anda dengan menambahkan bagian libraries baru seperti yang Anda lihat di sini:

AFTER:

runtime: python27
threadsafe: yes
api_version: 1

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

libraries:
- name: jinja2
  version: latest

Tidak ada file konfigurasi lain yang perlu diperbarui, jadi mari kita lanjutkan ke file aplikasi.

5. Mengubah file aplikasi

Dukungan impor dan Jinja2

Kumpulan perubahan pertama untuk main.py mencakup penambahan penggunaan Blobstore API dan penggantian template Django dengan Jinja2. Berikut yang akan berubah:

  1. Tujuan modul os adalah membuat nama jalur file ke template Django. Karena kita beralih ke Jinja2 tempat hal ini ditangani, penggunaan os serta perender template Django, google.appengine.ext.webapp.template, tidak lagi diperlukan, sehingga dihapus.
  2. Impor Blobstore API: google.appengine.ext.blobstore
  3. Impor pengendali Blobstore yang ditemukan di framework webapp asli—pengendali tersebut tidak tersedia di webapp2: google.appengine.ext.webapp.blobstore_handlers
  4. Impor dukungan Jinja2 dari paket webapp2_extras

BEFORE:

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

Terapkan perubahan dalam daftar di atas dengan mengganti bagian impor saat ini di main.py dengan cuplikan kode di bawah.

AFTER:

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

Setelah impor, tambahkan beberapa kode boilerplate untuk mendukung penggunaan Jinja2 seperti yang ditentukan dalam dokumen webapp2_extras. Cuplikan kode berikut menggabungkan class pengendali permintaan webapp2 standar dengan fungsi Jinja2, jadi tambahkan blok kode ini ke main.py tepat setelah impor:

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

Menambahkan dukungan Blobstore

Tidak seperti migrasi lain dalam seri ini yang mempertahankan fungsi atau output aplikasi contoh yang identik (atau hampir sama) tanpa (banyak) perubahan pada UX, contoh ini mengambil langkah yang lebih radikal dari biasanya. Daripada langsung mendaftarkan kunjungan baru lalu menampilkan sepuluh kunjungan terbaru, kami mengupdate aplikasi untuk meminta artefak file kepada pengguna guna mendaftarkan kunjungan mereka. Kemudian, pengguna akhir dapat mengupload file yang sesuai atau memilih "Lewati" untuk tidak mengupload apa pun. Setelah langkah ini selesai, halaman "kunjungan terbaru" akan ditampilkan.

Perubahan ini memungkinkan aplikasi kita menggunakan layanan Blobstore untuk menyimpan (dan mungkin nantinya merender) gambar atau jenis file lainnya di halaman kunjungan terbaru.

Memperbarui model data dan menerapkan penggunaannya

Kita akan menyimpan lebih banyak data, khususnya memperbarui model data untuk menyimpan ID (disebut "BlobKey") file yang diupload ke Blobstore dan menambahkan referensi untuk menyimpannya di store_visit(). Karena data tambahan ini ditampilkan bersama dengan data lainnya saat kueri, fetch_visits() tetap sama.

Berikut adalah tampilan sebelum dan sesudah pembaruan ini yang menampilkan file_blob, seorang ndb.BlobKeyProperty:

BEFORE:

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)

Berikut adalah representasi bergambar dari perubahan yang telah dilakukan sejauh ini:

2270783776759f7f.png

Mendukung upload file

Perubahan fungsi yang paling signifikan adalah mendukung upload file, baik meminta file kepada pengguna, mendukung fitur "lewati", atau merender file yang sesuai dengan kunjungan. Semua ini adalah bagian dari gambaran besarnya. Berikut adalah perubahan yang diperlukan untuk mendukung upload file:

  1. Permintaan pengendali utama GET tidak lagi mengambil kunjungan terbaru untuk ditampilkan. Namun, aplikasi akan meminta pengguna untuk mengupload.
  2. Saat pengguna akhir mengirimkan file untuk diupload atau melewati proses tersebut, POST dari formulir akan meneruskan kontrol ke UploadHandler baru, yang berasal dari google.appengine.ext.webapp.blobstore_handlers.BlobstoreUploadHandler.
  3. Metode POST UploadHandler melakukan upload, memanggil store_visit() untuk mendaftarkan kunjungan, dan memicu pengalihan HTTP 307 untuk mengirim pengguna kembali ke "/", tempat...
  4. Metode POST pengendali utama membuat kueri untuk (melalui fetch_visits()) dan menampilkan kunjungan terbaru. Jika pengguna memilih "lewati", tidak ada file yang diupload, tetapi kunjungan tetap didaftarkan, diikuti dengan pengalihan yang sama.
  5. Tampilan kunjungan terbaru menyertakan kolom baru yang ditampilkan kepada pengguna, baik "lihat" yang di-hyperlink jika file upload tersedia atau "tidak ada" jika tidak tersedia. Perubahan ini diwujudkan dalam template HTML bersama dengan penambahan formulir upload (selengkapnya akan segera hadir).
  6. Jika pengguna akhir mengklik link "lihat" untuk kunjungan apa pun dengan video yang diupload, link tersebut akan membuat permintaan GET ke ViewBlobHandler baru, yang berasal dari google.appengine.ext.webapp.blobstore_handlers.BlobstoreDownloadHandler , baik merender file jika berupa gambar (di browser jika didukung), meminta untuk mendownload jika tidak, atau menampilkan error HTTP 404 jika tidak ditemukan.
  7. Selain pasangan class pengendali baru serta pasangan rute baru untuk mengirim traffic ke class tersebut, pengendali utama memerlukan metode POST baru untuk menerima pengalihan 307 yang dijelaskan di atas.

Sebelum update ini, aplikasi Modul 0 hanya menampilkan pengendali utama dengan metode GET dan satu rute:

BEFORE:

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)

Setelah update tersebut diterapkan, kini ada tiga pengendali: 1) pengendali upload dengan metode POST, 2) pengendali download "lihat blob" dengan metode GET, dan 3) pengendali utama dengan metode GET dan POST. Lakukan perubahan ini agar bagian lain aplikasi Anda sekarang terlihat seperti di bawah ini.

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)

Ada beberapa panggilan kunci dalam kode yang baru saja kita tambahkan:

  • Di MainHandler.get, ada panggilan ke blobstore.create_upload_url. Panggilan ini menghasilkan URL yang menjadi tujuan POST formulir, yang memanggil pengendali upload untuk mengirim file ke Blobstore.
  • Di UploadHandler.post, ada panggilan ke blobstore_handlers.BlobstoreUploadHandler.get_uploads. Ini adalah keajaiban sesungguhnya yang menempatkan file ke Blobstore dan menampilkan ID unik dan persisten untuk file tersebut, yaitu BlobKey.
  • Di ViewBlobHandler.get, memanggil blobstore_handlers.BlobstoreDownloadHandler.send dengan BlobKey file akan menghasilkan pengambilan file dan meneruskannya ke browser pengguna akhir

Panggilan ini mewakili sebagian besar akses ke fitur yang ditambahkan ke aplikasi. Berikut adalah representasi bergambar dari kumpulan perubahan kedua dan terakhir pada main.py:

da2960525ac1b90d.png

Memperbarui template HTML

Beberapa update pada aplikasi utama memengaruhi antarmuka pengguna (UI) aplikasi, sehingga perubahan yang sesuai diperlukan dalam template web, tepatnya ada dua:

  1. Formulir upload file diperlukan dengan 3 elemen input: file dan sepasang tombol kirim untuk upload file dan lewati.
  2. Perbarui output kunjungan terbaru dengan menambahkan link "lihat" untuk kunjungan dengan upload file yang sesuai atau "tidak ada" jika tidak ada.

BEFORE:

<!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>

Terapkan perubahan dalam daftar di atas untuk menyertakan template yang diperbarui:

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>

Gambar ini mengilustrasikan update yang diperlukan untuk index.html:

8583e975f25aa9e7.png

Satu perubahan terakhir adalah Jinja2 lebih memilih templatenya berada di folder templates, jadi buat folder tersebut dan pindahkan index.html ke dalamnya. Dengan langkah terakhir ini, Anda telah menyelesaikan semua perubahan yang diperlukan untuk menambahkan penggunaan Blobstore ke aplikasi contoh Modul 0.

(opsional) "Peningkatan" Cloud Storage

Penyimpanan Blobstore akhirnya berkembang menjadi Cloud Storage. Artinya, upload Blobstore dapat dilihat di Konsol Cloud, khususnya browser Cloud Storage. Pertanyaannya adalah di mana. Jawabannya adalah bucket Cloud Storage default aplikasi App Engine Anda. Namanya adalah nama domain lengkap aplikasi App Engine Anda, PROJECT_ID.appspot.com. Hal ini sangat memudahkan karena semua project ID bersifat unik, bukan?

Update yang dilakukan pada aplikasi contoh akan menempatkan file yang diupload ke dalam bucket tersebut, tetapi developer memiliki opsi untuk memilih lokasi yang lebih spesifik. Bucket default dapat diakses secara terprogram melalui google.appengine.api.app_identity.get_default_gcs_bucket_name(), yang memerlukan impor baru jika Anda ingin mengakses nilai ini, misalnya untuk digunakan sebagai awalan untuk mengatur file yang diupload. Misalnya, mengurutkan menurut jenis file:

f61f7a23a1518705.png

Misalnya, untuk menerapkan hal seperti itu pada gambar, Anda akan memiliki kode seperti ini beserta beberapa kode yang memeriksa jenis file untuk memilih nama bucket yang diinginkan:

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

Anda juga akan memvalidasi gambar yang diupload menggunakan alat seperti modul imghdr Library Standar Python untuk mengonfirmasi jenis gambar. Terakhir, Anda mungkin ingin membatasi ukuran upload untuk mengantisipasi pelaku kejahatan.

Misalnya, semua itu sudah dilakukan. Bagaimana cara mengupdate aplikasi kita untuk mendukung penentuan tempat penyimpanan file yang diupload? Kuncinya adalah mengubah panggilan ke blobstore.create_upload_url di MainHandler.get untuk menentukan lokasi yang diinginkan di Cloud Storage untuk upload dengan menambahkan parameter gs_bucket_name seperti ini:

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

Karena ini adalah update opsional jika Anda ingin menentukan tujuan upload, update ini bukan bagian dari file main.py di repo. Sebagai gantinya, alternatif bernama main-gcs.py tersedia untuk Anda tinjau di repositori. Daripada menggunakan "folder" bucket terpisah, kode di main-gcs.py menyimpan upload di bucket "root" (PROJECT_ID.appspot.com) seperti main.py, tetapi menyediakan scaffolding yang Anda perlukan jika ingin mendapatkan sampel menjadi sesuatu yang lebih seperti yang diisyaratkan di bagian ini. Berikut adalah ilustrasi "perbedaan" antara main.py dan main-gcs.py.

256e1ea68241a501.png

6. Ringkasan/Pembersihan

Bagian ini mengakhiri codelab dengan men-deploy aplikasi, memverifikasi bahwa aplikasi berfungsi sebagaimana mestinya dan dalam output yang ditampilkan. Setelah validasi aplikasi, lakukan langkah-langkah pembersihan dan pertimbangkan langkah berikutnya.

Men-deploy dan memverifikasi aplikasi

Deploy ulang aplikasi Anda dengan gcloud app deploy, dan pastikan aplikasi berfungsi seperti yang diiklankan, berbeda dalam pengalaman pengguna (UX) dari aplikasi Modul 0. Sekarang ada dua layar berbeda di aplikasi Anda, yang pertama adalah perintah formulir upload file kunjungan:

f5b5f9f19d8ae978.pngDari sana, pengguna akhir dapat mengupload file dan mengklik "Kirim" atau mengklik "Lewati" untuk tidak mengupload apa pun. Dalam kedua kasus tersebut, hasilnya adalah layar kunjungan terbaru, yang kini dilengkapi dengan link "view" atau "none" di antara stempel waktu kunjungan dan informasi pengunjung:

f5ac6b98ee8a34cb.png

Selamat karena telah menyelesaikan codelab ini yang menambahkan penggunaan Blobstore App Engine ke aplikasi contoh Modul 0. Kode Anda sekarang akan cocok dengan yang ada di folder FINISH (Modul 15). main-gcs.py alternatif juga ada di folder tersebut.

Pembersihan

Umum

Jika Anda sudah selesai, sebaiknya nonaktifkan aplikasi App Engine untuk menghindari tagihan. Namun, jika Anda ingin menguji atau bereksperimen lebih lanjut, platform App Engine memiliki kuota gratis, dan selama Anda tidak melebihi tingkat penggunaan tersebut, Anda tidak akan dikenai biaya. Biaya tersebut adalah untuk komputasi, tetapi mungkin juga ada biaya untuk layanan App Engine yang relevan, jadi periksa halaman harganya untuk mengetahui informasi selengkapnya. Jika migrasi ini melibatkan layanan Cloud lainnya, layanan tersebut akan ditagih secara terpisah. Dalam kedua kasus tersebut, jika ada, lihat bagian "Khusus untuk codelab ini" di bawah.

Sebagai informasi, men-deploy ke platform komputasi serverless Google Cloud seperti App Engine akan dikenai biaya build dan penyimpanan yang kecil. Cloud Build memiliki kuota gratisnya sendiri, begitu juga dengan Cloud Storage. Penyimpanan gambar tersebut akan menggunakan sebagian kuota tersebut. Namun, Anda mungkin tinggal di wilayah yang tidak memiliki paket gratis tersebut, jadi perhatikan penggunaan penyimpanan Anda untuk meminimalkan potensi biaya. "Folder" Cloud Storage tertentu yang harus Anda tinjau meliputi:

  • 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
  • Link penyimpanan di atas bergantung pada PROJECT_ID dan *LOC*ation Anda, misalnya, "us" jika aplikasi Anda dihosting di Amerika Serikat.

Di sisi lain, jika Anda tidak akan melanjutkan aplikasi ini atau codelab migrasi terkait lainnya dan ingin menghapus semuanya sepenuhnya, nonaktifkan project Anda.

Khusus untuk codelab ini

Layanan yang tercantum di bawah ini unik untuk codelab ini. Lihat dokumentasi setiap produk untuk mengetahui informasi selengkapnya:

Langkah berikutnya

Migrasi logis berikutnya yang perlu dipertimbangkan dibahas dalam Modul 16, yang menunjukkan kepada developer cara bermigrasi dari layanan Blobstore App Engine ke penggunaan library klien Cloud Storage. Manfaat upgrade mencakup kemampuan untuk mengakses lebih banyak fitur Cloud Storage, memahami library klien yang berfungsi untuk aplikasi di luar App Engine, baik di Google Cloud, cloud lain, atau bahkan di infrastruktur lokal. Jika Anda merasa tidak memerlukan semua fitur yang tersedia dari Cloud Storage atau khawatir dengan dampaknya terhadap biaya, Anda bebas untuk tetap menggunakan Blobstore App Engine.

Selain Modul 16, ada banyak kemungkinan migrasi lainnya seperti Cloud NDB dan Cloud Datastore, Cloud Tasks, atau Cloud Memorystore. Ada juga migrasi lintas produk ke Cloud Run dan Cloud Functions. Repositori migrasi menampilkan semua contoh kode, menautkan Anda ke semua codelab dan video yang tersedia, serta memberikan panduan tentang migrasi yang perlu dipertimbangkan dan "urutan" migrasi yang relevan.

7. Referensi lainnya

Masalah/masukan codelab

Jika Anda menemukan masalah dengan codelab ini, telusuri masalah Anda terlebih dahulu sebelum mengajukan masalah. Link untuk menelusuri dan membuat masalah baru:

Referensi migrasi

Link ke folder repo untuk Modul 0 (START) dan Modul 15 (FINISH) dapat ditemukan dalam tabel di bawah. Kode tersebut juga dapat diakses dari repo untuk semua migrasi codelab App Engine yang dapat Anda clone atau download file ZIP-nya.

Codelab

Python 2

Python 3

Modul 0

kode

T/A

Modul 15 (codelab ini)

kode

T/A

Referensi online

Berikut adalah referensi online yang mungkin relevan untuk tutorial ini:

App Engine

Google Cloud

Python

Video

Lisensi

Karya ini dilisensikan berdasarkan Lisensi Umum Creative Commons Attribution 2.0.