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 codelab'de, App Engine Blobstore'dan Cloud Storage'a nasıl geçiş yapacağınızı öğreneceksiniz. Aşağıdaki kaynaklardan dolaylı taşıma işlemleri de vardır:
webapp2web çerçevesinden Flask'e (1. modülde ele alınmıştır)- Datastore erişimi için App Engine NDB'den Cloud NDB'ye geçiş (2. modülde ele alınmıştır)
- Python 2'den 3'e (taşınan uygulama hem Python 2 hem de 3 ile uyumludur)
Adım adım daha fazla bilgi için ilgili taşıma modüllerine bakın.
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
Gerekenler
- Etkin bir GCP faturalandırma hesabına sahip bir Google Cloud Platform projesi
- Temel Python becerileri
- Sık kullanılan Linux komutları hakkında mesleki bilgi
- App Engine uygulamalarını geliştirme ve dağıtma hakkında temel düzeyde bilgi
- Çalışan bir 15. Modül App Engine uygulaması: 15. Modül codelab'ini tamamlayın (önerilir) veya depodan 15. Modül uygulamasını kopyalayın.
Anket
Bu eğitimden nasıl yararlanacaksınız?
Python deneyiminizi nasıl değerlendirirsiniz?
Google Cloud hizmetlerini kullanma deneyiminizi nasıl değerlendirirsiniz?
2. Arka plan
Bu codelab, 15. modüldeki örnek uygulamayla başlar ve Blobstore (ve NDB)'dan Cloud Storage (ve Cloud NDB)'a nasıl geçiş yapılacağını gösterir. Taşıma işlemi, App Engine'in eski paket hizmetlerine olan bağımlılıkların değiştirilmesini içerir. Bu sayede, uygulamalarınızı isterseniz başka bir Cloud sunucusuz platformuna veya başka bir barındırma platformuna taşıyabilirsiniz.
Bu taşıma işlemi, bu serideki diğer taşıma işlemlerine kıyasla biraz daha fazla çaba gerektirir. Blobstore, orijinal webapp çerçevesine bağımlıdır. Bu nedenle örnek uygulama, Flask yerine webapp2 çerçevesini kullanır. Bu eğitimde Cloud Storage, Cloud NDB, Flask ve Python 3'e geçiş işlemleri ele alınmaktadır.
Uygulama, son kullanıcı "ziyaretlerini" kaydetmeye ve en son on ziyareti göstermeye devam eder ancak önceki (Modül 15) codelab, Blobstore kullanımına uyum sağlamak için yeni işlevler ekledi: Uygulama, son kullanıcılardan "ziyaretlerine" karşılık gelen bir yapıyı (dosya) yüklemelerini ister. Kullanıcılar bu işlemi yapabilir veya kapsamı dışında kalmayı seçmek için "atla"yı seçebilir. Kullanıcının kararından bağımsız olarak, sonraki sayfa bu uygulamanın önceki sürümleriyle aynı çıkışı oluşturarak en son ziyaretleri gösterir. İlgili yapay öğeleri içeren ziyaretlerde, ziyaretin yapay öğesini görüntülemek için bir "görüntüle" bağlantısı bulunur. Bu codelab'de, açıklanan işlevler korunarak daha önce bahsedilen taşıma işlemleri uygulanır.
3. Kurulum/Ön çalışma
Eğitimin ana bölümüne geçmeden önce projemizi ayarlayalım, kodu alalım ve ardından temel uygulamayı dağıtalım. Böylece çalışan bir kodla başladığımızdan emin oluruz.
1. Proje oluşturma
15. modül 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 15 örnek uygulamanızın olmasıdır. Uygulamanız yoksa Modül 15 "START" klasöründen (aşağıdaki bağlantı) indirebilirsiniz. Bu codelab'de her adımda size yol gösterilir ve Modül 16 "FINISH" klasöründekine benzer bir kodla tamamlanır.
- BAŞLANGIÇ: Modül 15 klasörü (Python 2)
- BİTİŞ: Modül 16 klasörü (Python 2)
- Tüm depo (ZIP dosyasını kopyalamak veya indirmek için)
15. modülün BAŞLANGIÇ dosyalarının dizini şu şekilde görünmelidir:
$ ls README.md app.yaml main-gcs.py main.py templates
main-gcs.py dosyası, Modül 15'teki main.py dosyasının alternatif bir sürümüdür. Bu dosya, projenin kimliğine göre bir uygulamanın atanan URL'sinin varsayılanından farklı bir Cloud Storage paketi seçilmesine olanak tanır: PROJECT_ID.appspot.com. Bu dosyanın bu (Modül 16) codelab'de bir rolü yoktur. Ancak isterseniz benzer taşıma tekniklerini bu dosyaya da uygulayabilirsiniz.
3. Temel uygulamayı (yeniden) dağıtma
Şimdi uygulamanız gereken kalan ön çalışma adımları:
gcloudkomut satırı aracını tekrar inceleme- Örnek uygulamayı
gcloud app deployile yeniden dağıtma - Uygulamanın App Engine'de sorunsuz çalıştığını doğrulama
Bu adımları başarıyla uyguladıktan sonra Modül 15 uygulamanızın çalıştığını onaylayın. İlk sayfada, kullanıcılar bir formla karşılanır. Bu formda, ziyaret yapay nesnesi dosyasının yüklenmesi istenir ve "atla" düğmesiyle bu işlemi atlama seçeneği sunulur:

Kullanıcılar bir dosya yükledikten veya bu adımı atladıktan sonra uygulama, tanıdık "en son ziyaretler" sayfasını oluşturur:

Yapı içeren ziyaretlerde, yapıyı görüntülemek (veya indirmek) için ziyaret zaman damgasının sağında bir "görüntüle" bağlantısı bulunur. Uygulamanın işlevselliğini onayladıktan sonra App Engine'in eski hizmetlerinden (webapp2, NDB, Blobstore) modern alternatiflere (Flask, Cloud NDB, Cloud Storage) geçiş yapmaya hazırsınız demektir.
4. Yapılandırma dosyalarını güncelleme
Uygulamamızın güncellenmiş sürümü için üç yapılandırma dosyası kullanılır. Gerekli görevler şunlardır:
app.yamluygulamasında gerekli yerleşik üçüncü taraf kitaplıklarını güncelleyin ve Python 3'e geçişe olanak tanıyın.- Yerleşik olmayan tüm gerekli kitaplıkları belirten bir
requirements.txtekleyin. - Uygulamanın hem yerleşik hem de yerleşik olmayan üçüncü taraf kitaplıklarını desteklemesi için
appengine_config.pyekleyin.
app.yaml
libraries bölümünü güncelleyerek app.yaml dosyanızı düzenleyin. jinja2 öğesini kaldırıp grpcio, setuptools ve ssl öğelerini ekleyin. Üç kitaplık için de mevcut olan en yeni sürümü seçin. Ayrıca Python 3 runtime yönergesini de ekleyin ancak açıklama satırı yapın. İşlemi tamamladığınızda, ekranınız aşağıdaki gibi görünmelidir (Python 3.9'u seçtiyseniz):
ÖNCE:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
AFTER:
#runtime: python39
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: latest
- name: setuptools
version: latest
- name: ssl
version: latest
Değişiklikler, temel olarak App Engine sunucularında bulunan Python 2 yerleşik kitaplıkları ile ilgilidir (böylece bunları kendiniz paketlemek zorunda kalmazsınız). Jinja2'yi kaldırdık çünkü reqs.txt dosyasına ekleyeceğimiz Flask ile birlikte geliyor. Cloud NDB ve Cloud Storage gibi Google Cloud istemci kitaplıkları kullanıldığında grpcio ve setuptools gerekir. Son olarak, Cloud Storage'ın kendisi ssl kitaplığını gerektirir. Üst kısımdaki açıklama satırı yapılmış çalışma zamanı yönergesi, bu uygulamayı Python 3'e taşımaya hazır olduğunuzda kullanılır. Bu konuyu bu eğitimin sonunda ele alacağız.
requirements.txt
Flask çerçevesi ile Cloud NDB ve Cloud Storage istemci kitaplıklarını gerektiren bir requirements.txt dosyası ekleyin. Bu bileşenlerin hiçbiri yerleşik değildir. Dosyayı şu içerikle oluşturun:
flask
google-cloud-ndb
google-cloud-storage
Python 2 App Engine çalışma zamanı, yerleşik olmayan üçüncü taraf kitaplıklarının kendi kendine paketlenmesini gerektirir. Bu nedenle, bu kitaplıkları lib klasörüne yüklemek için aşağıdaki komutu yürütün:
pip install -t lib -r requirements.txt
Geliştirme makinenizde hem Python 2 hem de Python 3 varsa bu kitaplıkların Python 2 sürümlerini almak için pip2 komutunu kullanmanız gerekebilir. Python 3'e geçtikten sonra artık kendi paketlerinizi oluşturmanız gerekmez.
appengine_config.py
Yerleşik ve yerleşik olmayan üçüncü taraf kitaplıklarını destekleyen bir appengine_config.py dosyası ekleyin. Dosyayı şu içerikle oluşturun:
import pkg_resources
from google.appengine.ext import vendor
# Set PATH to your libraries folder.
PATH = 'lib'
# Add libraries installed in the PATH folder.
vendor.add(PATH)
# Add libraries to pkg_resources working set to find the distribution.
pkg_resources.working_set.add_entry(PATH)
Az önce tamamlanan adımlar, App Engine belgelerinin Python 2 uygulamaları için kitaplık yükleme bölümünde listelenen adımlara benzer veya aynı olmalıdır. Daha açık belirtmek gerekirse appengine_config.py içeriği, buradaki 5. adımda yer alan içerikle eşleşmelidir.
Yapılandırma dosyalarıyla ilgili çalışma tamamlandığına göre uygulamaya geçelim.
5. Uygulama dosyalarını değiştirme
İçe aktarılanlar
main.py için yapılan ilk değişiklikler, değiştirilen tüm öğelerin kaldırılmasını içerir. Değişiklikler şu şekildedir:
webapp2, Flask ile değiştirildiwebapp2_extrasüzerinden Jinja2 kullanmak yerine Flask ile birlikte gelen Jinja2'yi kullanın.- App Engine Blobstore ve NDB'nin yerini Cloud NDB ve Cloud Storage aldı.
webappuygulamasındaki Blobstore işleyicileri,iostandart kitaplık modülü, Flask vewerkzeugyardımcı programlarının bir kombinasyonuyla değiştirilir.- Blobstore, varsayılan olarak uygulamanızın URL'sinin (
PROJECT_ID.appspot.com) adını taşıyan bir Cloud Storage paketine yazar. Cloud Storage istemci kitaplığına taşıma yaptığımız için tam olarak aynı paket adını belirtmek üzere proje kimliğini almak içingoogle.authkullanılır. (Paket adı artık sabit kodlu olmadığından adı değiştirebilirsiniz.)
ÖNCE:
import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers
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 io
from flask import (Flask, abort, redirect, render_template,
request, send_file, url_for)
from werkzeug.utils import secure_filename
import google.auth
from google.cloud import exceptions, ndb, storage
Başlatma ve gereksiz Jinja2 desteği
Değiştirilecek bir sonraki kod bloğu, webapp2_extras'dan Jinja2 kullanımını belirten BaseHandler bloğudur. Jinja2, Flask ile birlikte gelir ve varsayılan şablon motorudur. Bu nedenle, Jinja2'yi kaldırmanız gerekir.
16. modül tarafında, eski uygulamada bulunmayan nesneleri örneklendirin. Buna Flask uygulamasını başlatma ve Cloud NDB ile Cloud Storage için API istemcileri oluşturma dahildir. Son olarak, Cloud Storage paketi adını yukarıda içe aktarma bölümünde açıklandığı şekilde oluştururuz. Bu güncellemeler uygulanmadan önce ve uygulandıktan sonraki durum şu şekildedir:
ÖNCE:
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))
AFTER:
app = Flask(__name__)
ds_client = ndb.Client()
gcs_client = storage.Client()
_, PROJECT_ID = google.auth.default()
BUCKET = '%s.appspot.com' % PROJECT_ID
Datastore erişimini güncelleme
Cloud NDB, App Engine NDB ile büyük ölçüde uyumludur. Daha önce bahsedilen bir fark, API istemcisine duyulan ihtiyaçtır. Diğer bir fark ise Datastore erişiminin API istemcisinin Python bağlam yöneticisi tarafından kontrol edilmesini gerektirmesidir. Bu, Cloud NDB istemci kitaplığını kullanan tüm Datastore erişim çağrılarının yalnızca Python with bloklarında gerçekleşebileceği anlamına gelir.
Bu, değişikliklerden biridir. Diğer değişiklik ise Blobstore ve nesnelerinin (ör. BlobKey) Cloud Storage tarafından desteklenmemesidir. Bu nedenle, file_blob yerine ndb.StringProperty kullanın. Aşağıda, veri modeli sınıfı ve bu değişiklikleri yansıtan güncellenmiş store_visit() ve fetch_visits() işlevleri verilmiştir:
ÖNCE:
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)
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.StringProperty()
def store_visit(remote_addr, user_agent, upload_key):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent),
file_blob=upload_key).put()
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return Visit.query().order(-Visit.timestamp).fetch(limit)
Şimdiye kadar yapılan değişikliklerin görsel bir gösterimini aşağıda bulabilirsiniz:

İşleyicileri güncelleme
Yükleme işleyici
webapp2'da işleyiciler sınıflarken Flask'ta işlevlerdir. Flask, HTTP fiil yöntemi yerine işlevi süslemek için fiili kullanır. Blobstore ve webapp işleyicilerinin yerini Cloud Storage'ın yanı sıra Flask ve yardımcı programlarının işlevleri alır:
ÖNCE:
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)
AFTER:
@app.route('/upload', methods=['POST'])
def upload():
'Upload blob (POST) handler'
fname = None
upload = request.files.get('file', None)
if upload:
fname = secure_filename(upload.filename)
blob = gcs_client.bucket(BUCKET).blob(fname)
blob.upload_from_file(upload, content_type=upload.content_type)
store_visit(request.remote_addr, request.user_agent, fname)
return redirect(url_for('root'), code=307)
Bu güncellemeyle ilgili bazı notlar:
- Dosya çıktıları artık
blob_idyerine varsa dosya adıyla (fname), yoksaNoneile tanımlanır (kullanıcı dosya yüklemeyi devre dışı bıraktı). - Blobstore işleyicileri, yükleme işlemini kullanıcılarından soyutlar ancak Cloud Storage bunu yapmaz. Bu nedenle, dosyanın blob nesnesini ve konumunu (paket) ayarlayan yeni eklenen kodu ve gerçek yüklemeyi gerçekleştiren çağrıyı görebilirsiniz. (
upload_from_file()). webapp2, uygulama dosyasının alt kısmında bir yönlendirme tablosu kullanırken Flask rotaları her bir dekore edilmiş işleyicide bulunur.- Her iki işleyici de HTTP 307 dönüş koduyla
POSTisteğini korurken ana sayfaya (/) yönlendirerek işlevlerini tamamlar.
İndirme işleyici
İndirme işleyicisini güncelleme işlemi, yükleme işleyicisine benzer bir kalıp izler ancak incelenecek çok daha az kod vardır. Blobstore ve webapp işlevlerini Cloud Storage ve Flask eşdeğerleriyle değiştirin:
ÖNCE:
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)
AFTER:
@app.route('/view/<path:fname>')
def view(fname):
'view uploaded blob (GET) handler'
blob = gcs_client.bucket(BUCKET).blob(fname)
try:
media = blob.download_as_bytes()
except exceptions.NotFound:
abort(404)
return send_file(io.BytesIO(media), mimetype=blob.content_type)
Bu güncellemeyle ilgili notlar:
- Flask, işleyici işlevlerini rotalarıyla süslerken
webappbunu en alttaki yönlendirme tablosunda yapar. Bu nedenle, Flask'ın () kalıp eşleştirme söz dizimi (('/view/([^/]+)?') ile Flask'ın ('/view/<path:fname>') kalıp eşleştirme söz dizimini tanıyın. - Yükleme işleyicisinde olduğu gibi, Blobstore işleyicileri tarafından soyutlanan işlevler için Cloud Storage tarafında biraz daha fazla çalışma yapılması gerekir. Bu çalışmalar, söz konusu dosyanın (blob) tanımlanması ve ikili programın açıkça indirilmesi ile Blobstore işleyicisinin tek
send_blob()yöntem çağrısıdır. - Her iki durumda da, bir yapı bulunamazsa kullanıcıya HTTP 404 hatası döndürülür.
Ana işleyici
Ana uygulamada yapılan son değişiklikler ana işleyicide gerçekleşir. webapp2 HTTP fiil yöntemleri, işlevlerini birleştiren tek bir işlevle değiştirilir. MainHandler sınıfını root() işleviyle değiştirin ve webapp2 yönlendirme tablosunu aşağıda gösterildiği gibi kaldırın:
ÖNCE:
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)
AFTER:
@app.route('/', methods=['GET', 'POST'])
def root():
'main application (GET/POST) handler'
context = {}
if request.method == 'GET':
context['upload_url'] = url_for('upload')
else:
context['visits'] = fetch_visits(10)
return render_template('index.html', **context)
Ayrı get() ve post() yöntemleri yerine, aslında root() içinde bir if-else ifadesidir. Ayrıca root() tek bir işlev olduğundan hem GET hem de POST için şablonu oluşturmak üzere yalnızca bir çağrı yapılır. Bu, webapp2'te mümkün değildir.
main.py için yapılan bu ikinci ve son değişiklik grubunun görsel bir temsilini aşağıda bulabilirsiniz:

(isteğe bağlı) Geriye dönük uyumluluk "iyileştirmesi"
Yukarıda oluşturulan çözüm mükemmel bir şekilde çalışır ancak yalnızca sıfırdan başlıyorsanız ve Blobstore tarafından oluşturulan dosyalarınız yoksa. Uygulamayı, dosyaları BlobKey yerine dosya adına göre tanımlayacak şekilde güncellediğimiz için tamamlanan Modül 16 uygulaması, Blobstore dosyalarını olduğu gibi görüntüleyemez. Başka bir deyişle, bu taşıma işlemini gerçekleştirirken geriye dönük uyumsuz bir değişiklik yaptık. Şimdi, bu boşluğu doldurmaya çalışan main.py adlı aracın main-migrate.py adlı alternatif bir sürümünü (depoda bulunur) sunuyoruz.
Blobstore tarafından oluşturulan dosyaları destekleyen ilk "uzantı", BlobKeyProperty içeren bir veri modelidir (Cloud Storage tarafından oluşturulan dosyalar için StringProperty'e ek olarak):
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() # backwards-compatibility
file_gcs = ndb.StringProperty()
file_blob özelliği, Blobstore tarafından oluşturulan dosyaları tanımlamak için kullanılırken file_gcs, Cloud Storage dosyaları için kullanılır. Yeni ziyaretler oluştururken file_blob yerine file_gcs parametresinde açıkça bir değer depolayın. Böylece store_visit biraz farklı görünür:
ÖNCE:
def store_visit(remote_addr, user_agent, upload_key):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent),
file_blob=upload_key).put()
AFTER:
def store_visit(remote_addr, user_agent, upload_key):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent),
file_gcs=upload_key).put()
En son ziyaretleri getirirken verileri şablona göndermeden önce "normalleştirin":
ÖNCE:
@app.route('/', methods=['GET', 'POST'])
def root():
'main application (GET/POST) handler'
context = {}
if request.method == 'GET':
context['upload_url'] = url_for('upload')
else:
context['visits'] = fetch_visits(10)
return render_template('index.html', **context)
AFTER:
@app.route('/', methods=['GET', 'POST'])
def root():
'main application (GET/POST) handler'
context = {}
if request.method == 'GET':
context['upload_url'] = url_for('upload')
else:
context['visits'] = etl_visits(fetch_visits(10))
return render_template('index.html', **context)
Ardından, file_blob veya file_gcs (ya da her ikisinin de) mevcut olup olmadığını onaylayın. Kullanılabilir bir dosya varsa mevcut olanı seçin ve bu tanımlayıcıyı kullanın (Blobstore tarafından oluşturulan dosyalar için BlobKey veya Cloud Storage tarafından oluşturulan dosyalar için dosya adı). "Cloud Storage tarafından oluşturulan dosyalar" ifadesi, Cloud Storage istemci kitaplığı kullanılarak oluşturulan dosyaları ifade eder. Blobstore da Cloud Storage'a yazar ancak bu durumda bunlar Blobstore tarafından oluşturulan dosyalar olur.
Şimdi daha önemli bir soruya geçelim: Son kullanıcı için verileri normalleştirmek veya ETL (ayıklama, dönüştürme ve yükleme) amacıyla kullanılan bu etl_visits() işlevi nedir? Şöyle görünür:
def etl_visits(visits):
return [{
'visitor': v.visitor,
'timestamp': v.timestamp,
'file_blob': v.file_gcs if hasattr(v, 'file_gcs') \
and v.file_gcs else v.file_blob
} for v in visits]
Muhtemelen beklediğiniz gibi görünüyordur: Kod, tüm ziyaretler arasında döngü oluşturur ve her ziyaret için ziyaretçi ve zaman damgası verilerini olduğu gibi alır, ardından file_gcs veya file_blob olup olmadığını kontrol eder ve varsa bunlardan birini (veya ikisi de yoksa None) seçer.
main.py ve main-migrate.py arasındaki farkları gösteren bir görseli aşağıda bulabilirsiniz:

Blobstore tarafından oluşturulan dosyalar olmadan sıfırdan başlıyorsanız main.py kullanın. Ancak geçiş yapıyorsanız ve hem Blobstore hem de Cloud Storage tarafından oluşturulan dosyaları desteklemek istiyorsanız kendi uygulamalarınız için geçiş planlamanıza yardımcı olacak senaryoları nasıl ele alacağınızı gösteren bir örnek için main-migrate.py adresine göz atın. Karmaşık taşıma işlemleri yaparken özel durumlar ortaya çıkabilir. Bu nedenle, bu örnekte gerçek verilerle gerçek uygulamaları modernize etmeye daha fazla önem verilmiştir.
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ğrulamasından sonra temizleme adımlarını uygulayın ve sonraki adımları değerlendirin.
Uygulamayı dağıtma ve doğrulama
Uygulamanızı yeniden dağıtmadan önce, kendi paketlediğiniz üçüncü taraf kitaplıklarını lib klasörüne almak için pip install -t lib -r requirements.txt komutunu çalıştırdığınızdan emin olun. Geriye dönük uyumlu çözümü çalıştırmak istiyorsanız önce main-migrate.py adlı dosyayı main.py olarak yeniden adlandırın. Şimdi gcloud app deploy uygulamasını çalıştırın ve uygulamanın Modül 15 uygulamasıyla aynı şekilde çalıştığını onaylayın. Form ekranı şu şekilde görünür:

En son ziyaretler sayfası şu şekilde görünür:

App Engine Blobstore'u Cloud Storage ile, App Engine NDB'yi Cloud NDB ile ve webapp2'yi Flask ile değiştirdiğiniz bu codelab'i tamamladığınız için tebrikler. Kodunuz artık FINISH (Modül 16) klasöründeki kodla eşleşmelidir. Alternatif main-migrate.py de bu klasörde yer alır.
Python 3 "migration"
Bu uygulamayı Python 3'e taşımak için app.yaml dosyasının üst kısmındaki açıklama satırı yapılmış Python 3 runtime yönergesi yeterlidir. Kaynak kodun kendisi zaten Python 3 ile uyumlu olduğundan bu konuda herhangi bir değişiklik yapılması gerekmez. Bunu Python 3 uygulaması olarak dağıtmak için aşağıdaki adımları uygulayın:
app.yamldosyasının üst kısmındaki Python 3runtimeyönergesinin açıklama işaretini kaldırın.app.yamldosyasındaki diğer tüm satırları silin.appengine_config.pydosyasını silin. (Python 3 çalışma zamanında kullanılmaz)- Varsa
libklasörünü silin. (Python 3 çalışma zamanında gerekli değildir)
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, ücretsiz katmanın sunulmadığı 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/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- Yukarıdaki depolama alanı bağlantıları,
PROJECT_IDve *LOC*asyonunuza 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:
- App Engine Blobstore hizmeti, Depolanan Veri kotaları ve sınırları kapsamındadır. Bu nedenle, bu kotaları ve sınırları, ayrıca eski paket hizmetlerin fiyatlandırma sayfasını inceleyin.
- Cloud Storage'ın belirli bölgeler için ücretsiz katmanı vardır. Daha fazla bilgi için genel fiyatlandırma sayfasını da inceleyebilirsiniz.
- App Engine Datastore hizmeti, ücretsiz katmanı da olan Cloud Datastore (Datastore modunda Cloud Firestore) tarafından sağlanır. Daha fazla bilgi için fiyatlandırma sayfasını inceleyin."
15. modülden 16. modüle geçiş yaptıysanız Blobstore'da verileriniz olmaya devam eder. Bu nedenle, yukarıda Blobstore'un fiyatlandırma bilgilerine yer verilmiştir.
Sonraki adımlar
Bu eğitimde ele alınanların yanı sıra, eski paket hizmetlerden geçiş yapmaya odaklanan diğer taşıma modülleri şunlardır:
- 2. modül: App Engine
ndb'den Cloud NDB'ye taşıma - 7-9. modüller: App Engine görev sırası push görevlerinden Cloud Tasks'e geçiş
- 12-13. modüller: App Engine Memcache'ten Cloud Memorystore'a geçiş
- 18 ve 19. modüller: App Engine görev sırasından (çekme görevleri) Cloud Pub/Sub'a geçiş
App Engine artık Google Cloud'daki tek sunucusuz platform değildir. Küçük veya sınırlı işlevselliğe sahip bir App Engine uygulamanız varsa ve bunu bağımsız bir mikro hizmete dönüştürmek istiyorsanız ya da monolitik bir uygulamayı birden çok yeniden kullanılabilir bileşene bölmek istiyorsanız Cloud Functions'a geçmeyi düşünebilirsiniz. Kapsayıcılaştırma, uygulama geliştirme iş akışınızın bir parçası haline geldiyse (özellikle de bir CI/CD [sürekli entegrasyon/sürekli teslim veya dağıtım] ardışık düzeninden oluşuyorsa) Cloud Run'a geçiş yapabilirsiniz. Bu senaryolar aşağıdaki modüllerde ele alınmaktadır:
- App Engine'den Cloud Functions'a geçiş: 11. Modül'e bakın.
- App Engine'den Cloud Run'a geçiş: Uygulamanızı Docker ile container mimarisine almak için 4. modüle, container'lar, Docker bilgisi veya
Dockerfileolmadan yapmak için 5. modüle bakın.
Başka bir sunucusuz platforma geçiş yapmak isteğe bağlıdır. Herhangi bir değişiklik yapmadan önce uygulamalarınız ve kullanım alanlarınız için en iyi seçenekleri değerlendirmenizi öneririz.
Bir sonraki adımda hangi taşıma modülünü kullanmayı düşünürseniz düşünün, tüm Serverless Migration Station içeriklerine (codelab'ler, videolar, kaynak kodu [varsa]) açık kaynak deposundan erişebilirsiniz. Deponun README sayfasında, hangi taşıma işlemlerinin dikkate alınması gerektiği ve taşıma modüllerinin ilgili "sırası" hakkında da bilgi verilmektedir.
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 15 (BAŞLANGIÇ) ve Modül 16 (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 |
15. Modül | Yok | |
Modül 16 (bu codelab) | (Python 2 ile aynı) |
Online kaynaklar
Aşağıda, bu eğitimle alakalı olabilecek online kaynaklar verilmiştir:
App Engine Blobstore ve Cloud Storage
- App Engine Blobstore hizmeti
- Cloud Storage istemci kitaplığına taşıma
- Cloud Storage ana sayfası
- Cloud Storage belgeleri
App Engine platformu
- App Engine belgeleri
- Python 2 App Engine (standart ortam) çalışma zamanı
- Python 2 App Engine'de App Engine yerleşik kitaplıklarını kullanma
- Python 3 App Engine (standart ortam) çalışma zamanı
- Python 2 ve 3 App Engine (standart ortam) çalışma zamanları arasındaki farklar
- Python 2'den Python 3 App Engine'e (standart ortam) geçiş rehberi
- App Engine fiyatlandırması ve kotaları hakkında bilgi
- İkinci nesil App Engine platformunun lansmanı (2018)
- Birinci ve ikinci nesil platformları karşılaştırma
- Eski çalışma zamanları için uzun süreli destek
- Belge taşıma örnekleri deposu
- Topluluk tarafından katkıda bulunulan taşıma örnekleri deposu
Diğer bulut bilgileri
- Google Cloud Platform'da Python
- Google Cloud Python istemci kitaplıkları
- Google Cloud "Her Zaman Ücretsiz" katmanı
- Google Cloud SDK (
gcloudkomut satırı aracı) - Tüm Google Cloud belgeleri
Python
- Django ve Jinja2 şablon sistemleri
webapp2web çerçevesiwebapp2belgeleriwebapp2_extrasbağlantıwebapp2_extrasJinja2 belgeleri- Flask web çerçevesi
Videolar
- Serverless Migration Station
- Serverless Expeditions
- Google Cloud Tech'e abone olun.
- Google Developers'a abone olun
Lisans
Bu çalışma, Creative Commons Attribution 2.0 Genel Amaçlı Lisans ile lisans altına alınmıştır.