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

1. Genel Bakış

Serverless Migration Station serisi codelab'ler (kendi hızınızda ilerleyebileceğiniz, uygulamalı eğitimler) ve ilgili videolar, Google Cloud sunucusuz geliştiricilerin öncelikle eski hizmetlerden uzaklaşarak bir veya daha fazla taşıma işlemi yapmalarına rehberlik ederek uygulamalarını modernleştirmelerine yardımcı olmayı amaçlar. Bu sayede uygulamalarınız daha taşınabilir hale gelir, daha fazla seçenek ve esneklik elde edersiniz. Böylece daha geniş bir Cloud ürün yelpazesiyle entegrasyon yapabilir, bu ürünlere erişebilir ve yeni dil sürümlerine daha kolay yükseltebilirsiniz. Başlangıçta öncelikle App Engine (standart ortam) geliştiricileri olmak üzere en eski Cloud kullanıcılarına odaklanılsa da bu seri, Cloud Functions ve Cloud Run gibi diğer sunucusuz platformları veya uygun olduğu durumlarda başka platformları da kapsayacak kadar geniştir.

Bu 15. Modül codelab'inde, App Engine blobstore kullanımının 0. Modüldeki örnek uygulamaya 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.

Bu demoda aşağıdaki işlemleri yapmayı öğreneceksiniz:

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

İhtiyacınız olanlar

Anket

Bu eğitimi nasıl kullanacaksınız?

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

Python ile ilgili deneyiminizi nasıl değerlendirirsiniz?

Yeni başlayan Orta düzey Uzman

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

Başlangıç Orta İleri

2. Arka plan

App Engine Blobstore API'den geçiş yapmak için kullanımını 0. Modül'deki mevcut temel App Engine ndb uygulamasına ekleyin. Örnek uygulama, kullanıcının en son on ziyaretini gösterir. Uygulamayı, son kullanıcıdan "ziyaretiyle" ilgili bir yapıt (dosya) yüklemesini isteyecek şekilde değiştiriyoruz. Kullanıcı bunu yapmak istemiyorsa "atla" seçeneği sunulur. Kullanıcının kararı ne olursa olsun, sonraki sayfa Modül 0'daki uygulamanın (ve bu serideki diğer birçok modülün) çıktısıyla aynı sonucu oluşturur. Bu App Engine blobstore entegrasyonu uygulandıktan sonra, bir sonraki (16. modül) codelab'de 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) Modül 0'da Django'nun kullanılmasından Modül 15'te Jinja2'ye geçilmesidir. App Engine uygulamalarını modernleştirmenin önemli bir adımı, web çerçevelerini webapp2'dan Flask'e taşımaktır. İkincisi, varsayılan şablon sistemi olarak Jinja2'yi kullanır. Bu nedenle, Blobstore erişimi için webapp2'da kalırken Jinja2'yi uygulayarak bu yönde ilerlemeye başlıyoruz. Flask varsayılan olarak Jinja2'yi kullandığından, 16. modülde şablonda herhangi bir değişiklik yapılması gerekmeyecektir.

3. Kurulum/Ön Hazırlık

Eğitimin ana bölümüne geçmeden önce projenizi ayarlayın, kodu alın ve temel uygulamayı dağıtarak çalışan kodla başlayın.

1. Proje oluşturma

Module 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ına sahip olduğundan ve App Engine'in etkinleştirildiğinden emin olun.

2. Temel örnek uygulamayı edinme

Bu codelab'in ön koşullarından biri, çalışan bir 0. Modül örnek uygulamasına sahip olmaktır. Bu uygulamaya sahip değilseniz 0. Modül "BAŞLANGIÇ" klasöründen (aşağıdaki bağlantı) edinebilirsiniz. Bu codelab, sizi her adımda yönlendirir ve 15. modüldeki "FINISH" klasöründeki koda benzer bir kodla sonuçlanır.

Module 0 STARTing 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 yapmanız gereken kalan ön hazırlık adımları:

  1. gcloud komut satırı aracı hakkında bilgi edinin
  2. Örnek uygulamayı gcloud app deploy ile yeniden dağıtın.
  3. Uygulamanın App Engine'de sorunsuz çalıştığını onaylayın.

Bu adımları başarıyla uygulayıp web uygulamanızın çalıştığını (aşağıdakine benzer bir çıkışla) gördüğünüzde, 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 yapılmamıştır. Ancak daha önce belirtildiği gibi, Django şablonundan (varsayılan) Jinja2'ye geçiş yapıyoruz. Bu nedenle, geçiş yapmak için kullanıcıların App Engine sunucularında bulunan Jinja2'nin en son sürümünü belirtmesi gerekir. Bunu, app.yaml'nın yerleşik üçüncü taraf kitaplıkları bölümüne ekleyerek yapabilirsiniz.

ÖNCESİ:

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:

SONRASI:

runtime: python27
threadsafe: yes
api_version: 1

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

libraries:
- name: jinja2
  version: latest

Başka yapılandırma dosyalarının güncellenmesi gerekmez. Bu nedenle, uygulama dosyalarına geçebiliriz.

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

İçe aktarmalar ve Jinja2 desteği

main.py ile ilgili ilk değişiklikler arasında Blobstore API'nin kullanılması ve Django şablonlarının Jinja2 ile değiştirilmesi yer alıyor. Değişiklikler şu şekildedir:

  1. os modülünün amacı, bir Django şablonuna yönelik dosya yolu adı oluşturmaktır. Bu durumun ele alındığı Jinja2'ye geçiş yaptığımız için os ve Django şablon oluşturucusu google.appengine.ext.webapp.template artık gerekli değil. Bu nedenle, kaldırılıyorlar.
  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. Bu işleyiciler webapp2 içinde kullanılamaz: google.appengine.ext.webapp.blobstore_handlers
  4. webapp2_extras paketinden Jinja2 desteğini içe aktarma

ÖNCESİ:

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

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

SONRASI:

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 dokümanlarında tanımlandığı şekilde Jinja2 kullanımını desteklemek için bazı ortak metin kodları 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 main.py içe aktarma işlemlerinden hemen sonra 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şlevselliğini veya çıkışını kullanıcı deneyiminde (çok fazla) değişiklik yapmadan aynı (veya neredeyse aynı) tutarken bu örnek, normdan daha radikal bir şekilde ayrılıyor. Yeni bir ziyareti hemen kaydetmek ve ardından 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 söz konusu 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ıma alma

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

file_blob adlı ndb.BlobKeyProperty ile bu güncellemelerden önceki ve sonraki görünümü aşağıda bulabilirsiniz:

ÖNCESİ:

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)

SONRASI:

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)

Şu ana kadar yapılan değişikliklerin görsel gösterimi aşağıda verilmiştir:

2270783776759f7f.png

Dosya yüklemelerini destekleme

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

  1. Ana işleyici GET isteği artık görüntüleme için en son ziyaretleri getirmiyor. Bunun yerine, kullanıcıdan yükleme yapmasını ister.
  2. Bir son kullanıcı yüklemek üzere dosya gönderdiğinde veya bu işlemi atladığında, formdaki POST, google.appengine.ext.webapp.blobstore_handlers.BlobstoreUploadHandler öğesinden türetilen yeni UploadHandler öğesine kontrolü geçirir.
  3. UploadHandler'nın POST yöntemi yüklemeyi gerçekleştirir, ziyareti kaydetmek için store_visit()'ı çağırır ve kullanıcıyı "/" adresine geri göndermek için bir HTTP 307 yönlendirmesini tetikler. Burada...
  4. Ana işleyicinin POST yöntemi, en son ziyaretleri sorgular (fetch_visits() aracılığıyla) ve görüntüler. Kullanıcı "atla"yı seçerse dosya yüklenmez ancak ziyaret kaydedilir ve aynı yönlendirme işlemi uygulanı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üleme", aksi takdirde "yok" olarak gösterilir. Bu değişiklikler, yükleme formu eklenerek HTML şablonunda gerçekleştirilir (bu konuyla ilgili daha fazla bilgi yakında paylaşılacaktır).
  6. Bir son kullanıcı, yüklenmiş bir videonun bulunduğu herhangi bir ziyaret için "görüntüle" bağlantısını tıkladığında GET isteği gönderilir. Bu istek, google.appengine.ext.webapp.blobstore_handlers.BlobstoreDownloadHandler öğesinden türetilen yeni bir ViewBlobHandler öğesine gönderilir. Bu öğe, resim olması durumunda dosyayı oluşturur (destekleniyorsa tarayıcıda), resim olmaması durumunda indirme isteminde bulunur veya bulunmaması durumunda HTTP 404 hatası döndürür.
  7. Yeni işleyici sınıflarının yanı sıra trafiği bunlara göndermek için yeni bir rota çiftine ek olarak, ana işleyicinin yukarıda açıklanan 307 yönlendirmesini almak için yeni bir POST yöntemi gerekir.

Bu güncellemelerden önce Module 0 uygulamasında yalnızca GET yöntemi ve tek bir rota içeren bir ana işleyici bulunuyordu:

ÖNCESİ:

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ıktan sonra artık üç işleyici vardır: 1) POST yöntemiyle yükleme işleyicisi, 2) GET yöntemiyle "blob görüntüleme" indirme işleyicisi ve 3) GET ve POST yöntemleriyle 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.

SONRASI:

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 içinde blobstore.create_upload_url numarasına yapılan bir arama var. Bu çağrı, formun POST URL'sini oluşturur ve dosyayı Blobstore'a göndermek için yükleme işleyicisini çağırır.
  • UploadHandler.post içinde blobstore_handlers.BlobstoreUploadHandler.get_uploads numarasına yapılan bir arama var. Bu, dosyayı Blobstore'a yerleştiren ve bu dosya için benzersiz ve kalıcı bir kimlik döndüren gerçek sihirli işlemdir. Bu kimlik, dosyanın BlobKey değeridir.
  • ViewBlobHandler.get içinde, bir dosyanın BlobKey ile blobstore_handlers.BlobstoreDownloadHandler.send çağrıldığında dosya getirilip son kullanıcının tarayıcısına yönlendirilir.

Bu çağrılar, uygulamaya eklenen özelliklere erişimin büyük bir bölümünü temsil eder. main.py'da yapılan bu ikinci ve son değişiklik grubunun görsel bir temsilini aşağıda bulabilirsiniz:

da2960525ac1b90d.png

HTML şablonunu güncelleme

Ana uygulamadaki bazı güncellemeler, uygulamanın kullanıcı arayüzünü (UI) etkiler. Bu nedenle, web şablonunda iki değişiklik yapılması gerekir:

  1. 3 giriş öğesi içeren bir dosya yükleme formu gerekir: dosya ve sırasıyla dosya yükleme ve atlama için bir çift gönderme düğmesi.
  2. En son ziyaretler çıktısını, ilgili dosya yükleme işlemi olan ziyaretler için "görüntüleme" bağlantısı ekleyerek, aksi takdirde "yok" ekleyerek güncelleyin.

ÖNCESİ:

<!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üncellenmiş şablonu oluşturmak için yukarıdaki listede yer alan değişiklikleri uygulayın:

SONRASI:

<!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ı templates klasöründe tutmayı 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, Blobstore kullanımını 0. Modül örnek uygulamasına eklemek için gerekli tüm değişiklikleri tamamlamış olursunuz.

(isteğe bağlı) Cloud Storage "geliştirme"

Blobstore depolama alanı zamanla Cloud Storage'a dönüştü. Bu, Blobstore yüklemelerinin Cloud Console'da (özellikle Cloud Storage Tarayıcısı) görülebileceği anlamına gelir. Soru, nerede olduğudur. Yanıt, 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ğundan bu yöntem çok kullanışlıdır.

Ö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 isterseniz (ör. yüklenen dosyaları düzenlemek için önek olarak kullanmak) 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 dosya türlerini kontrol ederek istenen paket adını seçen bir kodun yanı sıra aşağıdaki gibi bir kodunuz olur:

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 Standard Library imghdr modülü gibi bir araç kullanarak yüklenen resimleri doğrulayacaksınız. Son olarak, kötü niyetli kişilere karşı yüklemelerin boyutunu sınırlamak isteyebilirsiniz.

Tüm bunların yapıldığını varsayalım. Yüklenen dosyaların nereye kaydedileceğini belirtmeyi desteklemek için uygulamamızı nasıl güncelleyebiliriz? Önemli olan, blobstore.create_upload_url işlevini MainHandler.get içinde değiştirerek gs_bucket_name parametresini aşağıdaki gibi ekleyerek yükleme için Cloud Storage'da istenen konumu belirtmektir:

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

Bu güncelleme isteğe bağlı olduğundan, yüklemelerin nereye gideceğini belirtmek isterseniz bu güncelleme, depodaki main.py dosyasının bir parçası değildir. Bunun yerine, depodaki incelemeniz için main-gcs.py adlı bir alternatif kullanılabilir. main-gcs.py içindeki kod, ayrı bir paket "klasörü" kullanmak yerine yüklemeleri main.py gibi "kök" paketinde (PROJECT_ID.appspot.com) depolar ancak bu bölümde belirtildiği gibi örneği daha fazla şeyden türetmeniz durumunda ihtiyacınız olan iskeleti sağlar. Aşağıda, main.py ile main-gcs.py arasındaki "farkların" bir resmi verilmiştir.

256e1ea68241a501.png

6. Özet/Temizleme

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

Uygulamayı dağıtma ve doğrulama

Uygulamanızı gcloud app deploy ile yeniden dağıtın ve uygulamanın, kullanıcı deneyimi (UX) açısından Modül 0 uygulamasından farklı olarak reklamda belirtildiği gibi çalıştığını doğrulayın. Uygulamanızda artık iki farklı ekran var. Bunlardan ilki, ziyaret dosyası yükleme formu istemi:

f5b5f9f19d8ae978.pngBuradan sonra son kullanıcılar bir dosya yükleyip "Gönder"i tıklayabilir veya herhangi bir şey yüklememek için "Atla"yı tıklayabilir. Her iki durumda da sonuç, ziyaret zaman damgaları ile ziyaretçi bilgileri arasında "görüntüleme" bağlantıları veya "yok" ile zenginleştirilmiş en son ziyaret ekranıdır:

f5ac6b98ee8a34cb.png

Bu codelab'i tamamlayarak Module 0 örnek uygulamasına App Engine Blobstore kullanımını eklediğiniz için tebrik ederiz. Kodunuz artık FINISH (Module 15) klasöründeki kodla eşleşmelidir. Alternatif main-gcs.py de bu klasörde bulunuyor.

Temizleme

Genel

Şimdilik işiniz bittiyse faturalandırmayı önlemek için App Engine uygulamanızı devre dışı bırakmanızı öneririz. Ancak biraz daha test veya deneme yapmak isterseniz App Engine platformunda ücretsiz kota bulunur. Bu nedenle, 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. Daha fazla bilgi için fiyatlandırma sayfasını inceleyin. Bu taşıma işlemine başka Cloud hizmetleri de dahilse bunlar ayrı olarak faturalandırılır. Her iki durumda da varsa aşağıdaki "Bu codelab'e özel" bölümüne bakın.

Tam açıklama yapmak gerekirse App Engine gibi bir Google Cloud sunucusuz bilgi işlem platformuna dağıtım yapıldığında küçük derleme ve depolama maliyetleri oluşur. Cloud Build ve Cloud Storage'ın kendi ücretsiz kotaları vardır. Bu görüntünün depolanması, kotanın bir kısmını kullanır. Ancak, böyle bir ücretsiz katmanın olmadığı 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 bağlantıları, PROJECT_ID ve *LOC*ınıza bağlıdır. Örneğin, uygulamanız ABD'de barındırılıyorsa "us" olur.

Öte yandan, bu uygulamaya veya ilgili diğer 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

Bir sonraki mantıksal taşıma işlemi 16. modülde ele alınmakta ve geliştiricilere App Engine Blobstore hizmetinden Cloud Storage istemci kitaplığını kullanmaya nasıl geçecekleri gösterilmektedir. Yükseltmenin avantajları arasında daha fazla Cloud Storage özelliğine erişebilme ve Google Cloud, diğer bulutlar veya şirket içi uygulamalar için çalışan bir istemci kitaplığına alışma yer alır. Cloud Storage'da sunulan 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ülün ötesinde Cloud NDB ve Cloud Datastore, Cloud Tasks veya Cloud Memorystore gibi bir dizi başka olası taşıma işlemi vardır. Cloud Run ve Cloud Functions'a ürünler arası geçişler de vardır. Taşıma deposunda tüm kod örnekleri yer alır, mevcut tüm codelab'lere ve videolara bağlantılar verilir. Ayrıca, hangi taşımaların dikkate alınması gerektiği ve ilgili taşıma "sırası" hakkında rehberlik sağlanır.

7. Ek kaynaklar

Codelab ile ilgili sorunlar/geri bildirimler

Bu codelab ile ilgili sorun bulursanız lütfen göndermeden önce sorununuzu arayın. Arama yapma ve yeni sorunlar oluşturma bağlantıları:

Taşıma kaynakları

Modül 0 (BAŞLANGIÇ) ve Modül 15 (BİTİŞ) ile ilgili depo klasörlerinin bağlantılarını aşağıdaki tabloda bulabilirsiniz. Bu dokümanlara, tüm App Engine codelab'lerinin taşındığı depodan da erişebilirsiniz. Bu depoyu klonlayabilir veya ZIP dosyası olarak indirebilirsiniz.

Codelab

Python 2

Python 3

Modül 0

code

Yok

15. Modül (bu codelab)

code

Yok

Online kaynaklar

Bu eğitimle ilgili olabilecek online kaynakları aşağıda bulabilirsiniz:

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.