App Engine blobstore'u kullanma (Modül 15)

1. Genel Bakış

Serverless Migration Station codelab serisi (kendi hızınızda ilerleyebileceğiniz uygulamalı eğitimler) ve ilgili videolar, Google Cloud sunucusuz geliştiricilerinin bir veya daha fazla taşıma işleminde (özellikle eski hizmetlerden uzaklaşma) onlara rehberlik ederek uygulamalarını modernize etmelerine yardımcı olmayı amaçlar. Böylece uygulamalarınız daha taşınabilir hale gelir ve daha fazla seçenek ve esneklik elde edersiniz. Bu sayede daha geniş bir Cloud ürünleri yelpazesiyle entegrasyon yapabilir ve bunlara erişebilir, ayrıca daha yeni dil sürümlerine daha kolay yükseltme yapabilirsiniz. Başlangıçta en eski Cloud kullanıcılarına, özellikle de App Engine (standart ortam) geliştiricilerine odaklanan bu seri, Cloud Functions ve Cloud Run gibi diğer sunucusuz platformları veya uygun olan diğer platformları da kapsayacak kadar geniştir.

Bu Modül 15 codelab'inde, Modül 0'daki örnek uygulamaya App Engine blobstore kullanımının nasıl ekleneceği açıklanmaktadır. Ardından, 16. modülde bu kullanımı Cloud Storage'a taşımaya hazır olacaksınız.

Demoda aşağıdaki işlemleri yapmayı öğreneceksiniz:

  • App Engine Blobstore API'sinin/kitaplığının kullanımını ekleme
  • Kullanıcı yüklemelerini blobstore hizmetinde depolama
  • Cloud Storage'a geçiş için sonraki adıma hazırlanma

İhtiyacınız olanlar

Anket

Bu eğitimden nasıl yararlanacaksınız?

Yalnızca okuyun Okuyun ve alıştırmaları tamamlayın

Python deneyiminizi nasıl değerlendirirsiniz?

Başlangıç düzeyi Orta düzey İleri düzey

Google Cloud hizmetlerini kullanma deneyiminizi nasıl değerlendirirsiniz?

Başlangıç düzeyi Orta düzey İleri düzey

2. Arka plan

App Engine Blobstore API'den geçiş yapmak için bu API'nin kullanımını 0. modüldeki mevcut temel App Engine ndb uygulamasına ekleyin. Örnek uygulama, kullanıcıya en son on ziyareti gösterir. Uygulamayı, son kullanıcıdan "ziyaretine" karşılık gelen bir öğe (dosya) yüklemesini isteyecek şekilde değiştiriyoruz. Kullanıcı bunu yapmak istemezse "atla" seçeneği sunulur. Kullanıcının kararı ne olursa olsun, sonraki sayfa Modül 0'daki (ve bu serideki diğer modüllerin çoğundaki) uygulamayla aynı çıkışı oluşturur. Bu App Engine blobstore entegrasyonu uygulandığında, bir sonraki (16. Modül) codelab'de bunu Cloud Storage'a taşıyabiliriz.

App Engine, Django ve Jinja2 şablon sistemlerine erişim sağlar. Bu örneği farklı kılan bir nokta (Blobstore erişimi eklemenin yanı sıra), 0. Modül'de Django'yu kullanırken 15. Modül'de Jinja2'ye geçmesidir. App Engine uygulamalarını modernize etmenin önemli bir adımı, web çerçevelerini webapp2'ten Flask'e taşımaktır. Flask, varsayılan şablon sistemi olarak Jinja2'yi kullanır. Bu nedenle, Blobstore erişimi için webapp2 kullanmaya devam ederken Jinja2'yi uygulayarak bu yönde ilerlemeye başlarız. Flask varsayılan olarak Jinja2'yi kullandığından, Modül 16'da şablonda herhangi bir değişiklik yapılması gerekmez.

3. Kurulum/Ön çalışma

Eğitimin ana bölümüne geçmeden önce projenizi oluşturun, kodu alın ve çalışan kodla başlamak için temel uygulamayı dağıtın.

1. Proje oluşturma

Modül 0 uygulamasını zaten dağıttıysanız aynı projeyi (ve kodu) yeniden kullanmanızı öneririz. Alternatif olarak, yepyeni bir proje oluşturabilir veya mevcut başka bir projeyi yeniden kullanabilirsiniz. Projenin etkin bir faturalandırma hesabı olduğundan ve App Engine'in etkinleştirildiğinden emin olun.

2. Temel örnek uygulamayı alma

Bu codelab'in ön koşullarından biri, çalışan bir Modül 0 örnek uygulamanızın olmasıdır. Uygulamanız yoksa Modül 0 "START" klasöründen (aşağıdaki bağlantı) indirebilirsiniz. Bu codelab'de her adım açıklanır ve Modül 15 "FINISH" klasöründeki koda benzer bir kodla tamamlanır.

Modül 0 BAŞLANGIÇ dosyalarının dizini şu şekilde görünmelidir:

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

3. Temel uygulamayı (yeniden) dağıtma

Şimdi uygulamanız gereken kalan ön çalışma adımları:

  1. gcloud komut satırı aracını tekrar inceleme
  2. Örnek uygulamayı gcloud app deploy ile yeniden dağıtma
  3. Uygulamanın App Engine'de sorunsuz çalıştığını doğrulama

Bu adımları başarıyla uyguladıktan ve web uygulamanızın çalıştığını gördükten sonra (aşağıdakine benzer bir çıkışla) uygulamanıza önbelleğe alma özelliğini eklemeye hazırsınız demektir.

a7a9d2b80d706a2b.png

4. Yapılandırma dosyalarını güncelleme

app.yaml

Uygulama yapılandırmasında önemli bir değişiklik yok. Ancak daha önce de belirtildiği gibi, Django şablonundan (varsayılan) Jinja2'ye geçiyoruz. Bu nedenle, geçiş yapmak için kullanıcıların App Engine sunucularında bulunan Jinja2'nin en yeni sürümünü belirtmesi gerekir. Bunu, app.yaml dosyasının yerleşik üçüncü taraf kitaplıkları bölümüne ekleyerek yapabilirsiniz.

ÖNCE:

runtime: python27
threadsafe: yes
api_version: 1

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

app.yaml dosyanızı, burada gördüğünüz gibi yeni bir libraries bölümü ekleyerek düzenleyin:

AFTER:

runtime: python27
threadsafe: yes
api_version: 1

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

libraries:
- name: jinja2
  version: latest

Başka bir yapılandırma dosyasının güncellenmesi gerekmediğinden uygulama dosyalarına geçelim.

5. Uygulama dosyalarını değiştirme

İçe aktarma ve Jinja2 desteği

main.py için ilk değişiklik grubu, Blobstore API'nin kullanımını eklemeyi ve Django şablon oluşturmayı Jinja2 ile değiştirmeyi içerir. Değişiklikler şu şekildedir:

  1. os modülünün amacı, bir Django şablonuna giden dosya yolu adı oluşturmaktır. Bu işlemin yapıldığı Jinja2'ye geçiş yaptığımız için os ve Django şablon oluşturucu google.appengine.ext.webapp.template artık gerekli değildir. Bu nedenle kaldırılmaktadır.
  2. Blobstore API'yi içe aktarın: google.appengine.ext.blobstore
  3. Orijinal webapp çerçevesinde bulunan Blobstore işleyicilerini içe aktarın. Bunlar webapp2 içinde kullanılamaz: google.appengine.ext.webapp.blobstore_handlers
  4. webapp2_extras paketinden Jinja2 desteğini içe aktarma

ÖNCE:

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

main.py dosyasındaki mevcut içe aktarma bölümünü aşağıdaki kod snippet'iyle değiştirerek yukarıdaki listede yer alan değişiklikleri uygulayın.

AFTER:

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

İçe aktarma işlemlerinden sonra, webapp2_extras belgelerinde tanımlandığı şekilde Jinja2 kullanımını desteklemek için ortak metin kodu ekleyin. Aşağıdaki kod snippet'i, standart webapp2 istek işleyici sınıfını Jinja2 işleviyle sarmalar. Bu nedenle, bu kod bloğunu içe aktarma işlemlerinden hemen sonra main.py dosyasına ekleyin:

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

Blobstore desteği ekleme

Bu serideki diğer taşıma işlemlerinde örnek uygulamanın işlevini veya çıkışını kullanıcı deneyiminde (fazla) değişiklik yapmadan aynı (veya neredeyse aynı) tutuyoruz. Bu örnekte ise normdan daha radikal bir şekilde ayrılıyoruz. Yeni bir ziyareti hemen kaydedip en son on ziyareti göstermek yerine, uygulamayı güncelleyerek kullanıcıdan ziyaretini kaydetmek için bir dosya yapısı isteyeceğiz. Son kullanıcılar daha sonra ilgili dosyayı yükleyebilir veya hiçbir şey yüklememek için "Atla"yı seçebilir. Bu adım tamamlandığında "en son ziyaretler" sayfası gösterilir.

Bu değişiklik, uygulamamızın Blobstore hizmetini kullanarak bu resmi veya diğer dosya türlerini en son ziyaretler sayfasında depolamasına (ve muhtemelen daha sonra oluşturmasına) olanak tanır.

Veri modelini güncelleme ve kullanımını uygulama

Daha fazla veri depoluyoruz. Özellikle veri modelini, Blobstore'a yüklenen dosyanın kimliğini ("BlobKey" olarak adlandırılır) depolayacak şekilde güncelliyor ve bunu store_visit() içine kaydedecek bir referans ekliyoruz. Bu ek veriler, sorgu üzerine diğer her şeyle birlikte döndürüldüğünden fetch_visits() aynı kalır.

ndb.BlobKeyProperty olan file_blob ile bu güncellemelerin öncesi ve sonrasını burada görebilirsiniz:

ÖNCE:

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)

Şimdiye kadar yapılan değişikliklerin görsel bir gösterimini aşağıda bulabilirsiniz:

2270783776759f7f.png

Dosya yüklemelerini destekleme

İşlevsellikteki en önemli değişiklik, dosya yükleme desteğidir. Bu destek, kullanıcıdan dosya isteme, "atla" özelliğini destekleme veya bir ziyarete karşılık gelen dosyayı oluşturma gibi işlemleri kapsar. Bunların hepsi resmin bir parçasıdır. Dosya yüklemelerini desteklemek için yapılması gereken değişiklikler şunlardır:

  1. Ana işleyici GET isteği artık gösterilecek en son ziyaretleri getirmiyor. Bunun yerine, kullanıcıdan yükleme yapmasını ister.
  2. Son kullanıcı, yüklenecek bir dosya gönderdiğinde veya bu işlemi atladığında formdaki bir POST, kontrolü google.appengine.ext.webapp.blobstore_handlers.BlobstoreUploadHandler öğesinden türetilen yeni UploadHandler öğesine geçirir.
  3. UploadHandler'nin POST yöntemi yükleme işlemini gerçekleştirir, ziyareti kaydetmek için store_visit() yöntemini çağırır ve kullanıcıyı "/" dizinine geri göndermek için bir HTTP 307 yönlendirmesi tetikler. Burada...
  4. Ana işleyicinin POST yöntemi, en son ziyaretleri (fetch_visits() aracılığıyla) sorgular ve görüntüler. Kullanıcı "atla"yı seçerse dosya yüklenmez ancak ziyaret yine de kaydedilir ve ardından aynı yönlendirme yapılır.
  5. En son ziyaretler ekranında, kullanıcıya gösterilen yeni bir alan bulunur. Bu alan, yükleme dosyası varsa köprü bağlantılı bir "görüntüle" düğmesi, yoksa "yok" ifadesidir. Bu değişiklikler, bir yükleme formunun eklenmesiyle birlikte HTML şablonunda uygulanır (bu konuda daha fazla bilgi yakında paylaşılacaktır).
  6. Son kullanıcı, yüklenen bir videonun bulunduğu ziyaret için "görüntüle" bağlantısını tıklarsa google.appengine.ext.webapp.blobstore_handlers.BlobstoreDownloadHandler adresinden türetilen yeni bir ViewBlobHandler adresine GET isteği gönderilir. Bu istek, dosya bir resimse dosyayı oluşturur (destekleniyorsa tarayıcıda), resim değilse indirme istemi gösterir veya bulunamazsa HTTP 404 hatası döndürür.
  7. Yeni işleyici sınıfları ve trafiği bunlara gönderecek yeni rotaların yanı sıra ana işleyicinin, yukarıda açıklanan 307 yönlendirmesini almak için yeni bir POST yöntemine ihtiyacı vardır.

Bu güncellemelerden önce, Modül 0 uygulamasında yalnızca GET yöntemi ve tek bir rotası olan bir ana işleyici vardı:

ÖNCE:

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)

Bu güncellemeler uygulandığında artık üç işleyici vardır: 1) POST yöntemine sahip yükleme işleyicisi, 2) GET yöntemine sahip "view blob" indirme işleyicisi ve 3) GET ve POST yöntemlerine sahip ana işleyici. Uygulamanızın geri kalanının aşağıdaki gibi görünmesi için bu değişiklikleri yapın.

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)

Yeni eklediğimiz bu kodda birkaç önemli çağrı var:

  • MainHandler.get sonra blobstore.create_upload_url için arama var. Bu çağrı, formun POST yaptığı URL'yi oluşturur ve dosyayı Blobstore'a göndermek için yükleme işleyicisini çağırır.
  • UploadHandler.post sonra blobstore_handlers.BlobstoreUploadHandler.get_uploads için arama var. Dosyayı Blobstore'a yerleştiren ve bu dosya için benzersiz ve kalıcı bir kimlik (BlobKey) döndüren asıl sihir budur.
  • ViewBlobHandler.get içinde, bir dosyanın BlobKey değeriyle blobstore_handlers.BlobstoreDownloadHandler.send çağrıldığında dosya getirilir ve son kullanıcının tarayıcısına yönlendirilir.

Bu çağrılar, uygulamaya eklenen özelliklere erişimin büyük bir kısmını oluşturur. main.py ile ilgili bu ikinci ve son değişiklik grubunun görsel bir temsili aşağıda verilmiştir:

da2960525ac1b90d.png

HTML şablonunu güncelleme

Ana uygulamada yapılan güncellemelerden bazıları uygulamanın kullanıcı arayüzünü (UI) etkiler. Bu nedenle, web şablonunda ilgili değişikliklerin yapılması gerekir. Aslında iki değişiklik yapılması gerekir:

  1. 3 giriş öğesi içeren bir dosya yükleme formu gereklidir: bir dosya ve sırasıyla dosya yükleme ve atlama için bir çift gönder düğmesi.
  2. İlgili dosya yüklemesi olan ziyaretler için "görüntüle" bağlantısı ekleyerek en son ziyaretler çıkışını güncelleyin. İlgili dosya yüklemesi yoksa "yok" yazın.

ÖNCE:

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

Güncellenen şablonu oluşturmak için yukarıdaki listede yer alan değişiklikleri uygulayın:

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>

Bu resimde index.html için gerekli güncellemeler gösterilmektedir:

8583e975f25aa9e7.png

Son bir değişiklik olarak Jinja2, şablonlarını bir templates klasöründe tercih eder. Bu nedenle, bu klasörü oluşturun ve index.html dosyasını bu klasöre taşıyın. Bu son adımla birlikte, Modül 0 örnek uygulamasına Blobstore kullanımını eklemek için gereken tüm değişiklikleri tamamlamış oldunuz.

(isteğe bağlı) Cloud Storage "iyileştirmesi"

Blobstore depolama alanı, zaman içinde Cloud Storage'a dönüştü. Bu, Blobstore yüklemelerinin Cloud Console'da, özellikle de Cloud Storage tarayıcısında görülebileceği anlamına gelir. Asıl soru, nerede olduğudur. Cevap, App Engine uygulamanızın varsayılan Cloud Storage paketidir. Adı, App Engine uygulamanızın tam alan adıdır: PROJECT_ID.appspot.com. Tüm proje kimlikleri benzersiz olduğu için bu çok kullanışlı bir yöntem, değil mi?

Örnek uygulamada yapılan güncellemeler, yüklenen dosyaları bu pakete bırakır ancak geliştiriciler daha spesifik bir konum seçebilir. Varsayılan pakete google.appengine.api.app_identity.get_default_gcs_bucket_name() üzerinden programatik olarak erişilebilir. Bu değere erişmek istiyorsanız (ör. yüklenen dosyaları düzenlemek için önek olarak kullanmak üzere) yeni bir içe aktarma işlemi yapmanız gerekir. Örneğin, dosya türüne göre sıralama:

f61f7a23a1518705.png

Örneğin, resimler için buna benzer bir şey uygulamak istiyorsanız aşağıdaki gibi bir kodun yanı sıra istenen paket adını seçmek için dosya türlerini kontrol eden bir kod kullanırsınız:

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

Ayrıca, resim türünü onaylamak için Python Standart Kitaplığı imghdr modülü gibi bir araç kullanarak yüklenen resimleri doğrulayacaksınız. Son olarak, kötü niyetli kişilere karşı yükleme boyutunu sınırlamak isteyebilirsiniz.

Tüm bunların yapıldığını varsayalım. Uygulamamızı, yüklenen dosyaların nerede depolanacağını belirtecek şekilde nasıl güncelleyebiliriz? Burada önemli olan, MainHandler.get içindeki blobstore.create_upload_url çağrısını düzenleyerek Cloud Storage'da yükleme için istenen konumu belirtmek üzere gs_bucket_name parametresini şu şekilde eklemektir:

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

Yüklemelerin nereye gideceğini belirtmek istiyorsanız bu isteğe bağlı bir güncelleme olduğundan depodaki main.py dosyasının bir parçası değildir. Bunun yerine, depoda incelemeniz için main-gcs.py adlı bir alternatif sunulmuştur. main-gcs.py içindeki kod, ayrı bir paket "klasörü" kullanmak yerine yüklemeleri tıpkı main.py gibi "kök" pakette (PROJECT_ID.appspot.com) depolar ancak bu bölümde belirtildiği gibi örneği daha fazla türetmeniz gerekirse ihtiyacınız olan iskeleyi sağlar. Aşağıda, main.py ile main-gcs.py arasındaki "farklar" gösterilmektedir.

256e1ea68241a501.png

6. Özet/Temizleme

Bu bölümde, uygulamayı dağıtarak, amaçlandığı gibi çalıştığını ve tüm yansıtılan çıkışlarda çalıştığını doğrulayarak bu codelab'i tamamlayacağız. Uygulama doğrulandıktan sonra temizleme adımlarını uygulayın ve sonraki adımları değerlendirin.

Uygulamayı dağıtma ve doğrulama

Uygulamanızı gcloud app deploy ile yeniden dağıtın ve uygulamanın reklamı yapıldığı gibi çalıştığını, kullanıcı deneyimi (UX) açısından Modül 0 uygulamasından farklı olduğunu doğrulayın. Uygulamanızda artık iki farklı ekran var. İlki, ziyaret dosyası yükleme formu istemidir:

f5b5f9f19d8ae978.pngSon kullanıcılar bu ekranda bir dosya yükleyip "Gönder"i veya hiçbir şey yüklememek için "Atla"yı tıklar. Her iki durumda da sonuç, en son ziyaret ekranıdır. Bu ekran artık ziyaret zaman damgaları ile ziyaretçi bilgileri arasında "görüntüle" bağlantıları veya "yok" ifadesiyle zenginleştirilmiştir:

f5ac6b98ee8a34cb.png

Modül 0 örnek uygulamasına App Engine Blobstore kullanımını ekleyen bu codelab'i tamamladığınız için tebrikler. Kodunuz artık FINISH (Modül 15) klasöründeki kodla eşleşmelidir. Alternatif main-gcs.py de bu klasörde bulunuyor.

Temizleme

Genel

Şimdilik işiniz bittiyse faturalandırılmamak için App Engine uygulamanızı devre dışı bırakmanızı öneririz. Ancak daha fazla test veya deneme yapmak isterseniz App Engine platformunun ücretsiz kotası vardır. Bu kullanım katmanını aşmadığınız sürece sizden ücret alınmaz. Bu, işlem için geçerlidir ancak ilgili App Engine hizmetleri için de ücret alınabilir. Bu nedenle, daha fazla bilgi için fiyatlandırma sayfasını inceleyin. Bu taşıma işlemi diğer Cloud hizmetlerini içeriyorsa bunlar ayrı olarak faturalandırılır. Her iki durumda da, geçerliyse aşağıdaki "Bu codelab'e özel" bölümüne bakın.

App Engine gibi bir Google Cloud sunucusuz bilgi işlem platformuna dağıtım yapmanın küçük derleme ve depolama maliyetleri olduğunu belirtmek isteriz. Cloud Build'un, Cloud Storage gibi kendi ücretsiz kotası vardır. Bu resmin depolanması, kotanın bir kısmını kullanır. Ancak, böyle bir ücretsiz katmanın bulunmadığı bir bölgede yaşıyor olabilirsiniz. Bu nedenle, olası maliyetleri en aza indirmek için depolama alanı kullanımınıza dikkat edin. İncelemeniz gereken belirli Cloud Storage "klasörleri" şunlardır:

  • 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
  • Yukarıdaki depolama alanı bağlantıları, PROJECT_ID ve *LOC*konumunuza bağlıdır. Örneğin, uygulamanız ABD'de barındırılıyorsa "us" olur.

Öte yandan, bu uygulamaya veya diğer ilgili taşıma codelab'lerine devam etmeyecekseniz ve her şeyi tamamen silmek istiyorsanız projenizi kapatın.

Bu codelab'e özel

Aşağıda listelenen hizmetler bu codelab'e özeldir. Daha fazla bilgi için her ürünün belgelerine bakın:

Sonraki adımlar

Dikkate alınması gereken bir sonraki mantıksal taşıma işlemi, geliştiricilere App Engine Blobstore hizmetinden Cloud Storage istemci kitaplığını kullanmaya nasıl geçiş yapacaklarını gösteren 16. modülde ele alınmaktadır. Yükseltme yapmanın avantajları arasında daha fazla Cloud Storage özelliğine erişebilmek ve Google Cloud'da, diğer bulutlarda, hatta şirket içinde App Engine dışındaki uygulamalarda çalışan bir istemci kitaplığına aşina olmak yer alır. Cloud Storage'ın sunduğu tüm özelliklere ihtiyacınız olmadığını düşünüyorsanız veya maliyet üzerindeki etkileri konusunda endişeleriniz varsa App Engine Blobstore'u kullanmaya devam edebilirsiniz.

16. modülden sonra Cloud NDB ve Cloud Datastore, Cloud Tasks veya Cloud Memorystore gibi diğer olası taşıma işlemleri yer alır. Cloud Run ve Cloud Functions'a ürünler arası geçişler de vardır. Taşıma deposu, tüm kod örneklerini içerir, sizi mevcut tüm codelab'lere ve videolara yönlendirir, ayrıca hangi taşıma işlemlerinin dikkate alınması gerektiği ve ilgili taşıma "sırası" hakkında rehberlik sağlar.

7. Ek kaynaklar

Codelab sorunları/geri bildirimleri

Bu codelab ile ilgili herhangi bir sorunla karşılaşırsanız lütfen bildirimde bulunmadan önce sorununuzu arayın. Yeni sorunları aramak ve oluşturmak için bağlantılar:

Veri taşımayla ilgili kaynaklar

Modül 0 (BAŞLANGIÇ) ve Modül 15 (BİTİŞ) için depo klasörlerinin bağlantılarını aşağıdaki tabloda bulabilirsiniz. Bu dosyalara, klonlayabileceğiniz veya ZIP dosyası olarak indirebileceğiniz tüm App Engine codelab taşıma işlemlerinin deposundan da erişebilirsiniz.

Codelab

Python 2

Python 3

Modül 0

code

Yok

15. modül (bu codelab)

code

Yok

Online kaynaklar

Aşağıda, bu eğitimle alakalı olabilecek online kaynaklar verilmiştir:

App Engine

Google Cloud

Python

Videolar

Lisans

Bu çalışma, Creative Commons Attribution 2.0 Genel Amaçlı Lisans ile lisans altına alınmıştır.