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 codelab'de App Engine Blobstore'dan Cloud Storage'a nasıl geçeceğiniz açıklanmaktadır. Aşağıdaki kaynaklardan da örtülü taşıma işlemleri yapılabilir:
webapp2web framework to Flask (covered by Module 1)- Datastore erişimi için App Engine NDB'den Cloud NDB'ye geçiş (2. Modül'de ele alınmıştır)
- Python 2'den 3'e (taşınan uygulama hem Python 2 hem de 3 ile uyumludur)
Daha fazla adım adım bilgi için ilgili taşıma modüllerine bakın.
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
Gerekenler
- Etkin bir GCP faturalandırma hesabına sahip bir Google Cloud Platform projesi
- Temel Python becerileri
- Yaygın Linux komutları hakkında çalışma bilgisi
- App Engine uygulamalarını geliştirme ve dağıtma hakkında temel bilgiler
- Çalışan bir 15. Modül App Engine uygulaması: 15. Modül codelab'ini tamamlayın (önerilir) veya 15. Modül uygulamasını depodan kopyalayın.
Anket
Bu eğitimi nasıl kullanacaksınız?
Python ile ilgili 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'dan (ve NDB) Cloud Storage'a (ve Cloud NDB) nasıl geçileceğini gösterir. Taşıma işlemi, App Engine'in eski paketlenmiş hizmetlerine yönelik bağımlılıkların değiştirilmesini içerir. Bu sayede, isterseniz uygulamalarınızı başka bir Cloud sunucusuz platforma veya başka bir barındırma platformuna taşıyabilirsiniz.
Bu taşıma, bu serideki diğer taşımalara kıyasla biraz daha fazla çaba gerektirir. Blobstore, orijinal webapp çerçevesine bağlıdır. Bu nedenle örnek uygulamada Flask yerine webapp2 çerçevesi kullanılır. Bu eğitimde Cloud Storage, Cloud NDB, Flask ve Python 3'e geçişler ele alınmaktadır.
Uygulama, son kullanıcı "ziyaretlerini" kaydetmeye ve en son on tanesini göstermeye devam ediyor ancak önceki (15. Modül) codelab'de Blobstore kullanımına uygun yeni işlevler eklenmişti: Uygulama, son kullanıcılardan "ziyaretlerine" karşılık gelen bir yapıyı (dosya) yüklemelerini istiyor. Kullanıcılar bu işlemi yapabilir veya devre dışı bırakmak için "atla"yı seçebilir. Kullanıcının kararı ne olursa olsun, sonraki sayfada bu uygulamanın önceki sürümleriyle aynı çıktı oluşturulur ve en son ziyaretler gösterilir. Bir diğer nokta ise ilgili yapay nesneleri içeren ziyaretlerde, ziyaretin yapay nesnesini görüntülemek için "görüntüle" bağlantısının bulunmasıdır. Bu codelab, daha önce bahsedilen taşıma işlemlerini açıklanan işlevselliği koruyarak uygular.
3. Kurulum/Ön Hazırlık
Eğitimin ana bölümüne geçmeden önce projemizi oluşturalım, kodu alalım ve temel uygulamayı dağıtalım. Böylece, çalışır durumda olan bir kodla başladığımızı biliriz.
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ı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 15. Modül örnek uygulamasına sahip olmaktır. Bu uygulamaya sahip değilseniz 15. Modül "BAŞLANGIÇ" klasöründen (aşağıdaki bağlantı) edinebilirsiniz. Bu codelab, sizi her adımda yönlendirir ve 16. modüldeki "FINISH" klasöründekine benzer bir kodla sonuçlanır.
- BAŞLANGIÇ: Module 15 folder (Python 2)
- BİTİRME: 16. Modül klasörü (Python 2)
- Deponun tamamı (ZIP dosyasını klonlamak veya indirmek için)
15. Modül 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ı, 15. modüldeki main.py dosyasının alternatif bir sürümüdür. Bu sürüm, projenin kimliğine (PROJECT_ID.appspot.com) göre bir uygulamanın varsayılan olarak atanan URL'sinden farklı bir Cloud Storage paketi seçilmesine olanak tanır. Bu dosya, bu (16. Modül) codelab'de hiçbir rol oynamaz. Ancak istenirse benzer taşıma teknikleri bu dosyaya uygulanabilir.
3. Temel uygulamayı (yeniden) dağıtma
Şimdi yapmanız gereken kalan ön hazırlık adımları:
gcloudkomut satırı aracı hakkında bilgi edinin- Örnek uygulamayı
gcloud app deployile yeniden dağıtın. - Uygulamanın App Engine'de sorunsuz çalıştığını onaylayın.
Bu adımları başarıyla uygulayıp 15. Modül uygulamanızın çalıştığını onayladıktan sonra. İlk sayfada, kullanıcıları bir formla karşılıyoruz. Bu formda, yüklemek için bir ziyaret yapıtı dosyası isteniyor ve devre dışı bırakma seçeneği olarak "atla" düğmesi sunuluyor:

Kullanıcılar bir dosyayı yükledikten veya atladıktan sonra uygulama, "en son ziyaretler" sayfasını gösterir:

Bir yapıtın yer aldığı ziyaretlerde, yapıtı görüntülemek (veya indirmek) için ziyaretin zaman damgasının sağında "görüntüle" bağlantısı bulunur. Uygulamanın işlevselliğini onayladıktan sonra App Engine eski hizmetlerinden (webapp2, NDB, Blobstore) güncel 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ünde üç yapılandırma dosyası kullanılır. Yapılması gereken işlemler şunlardır:
app.yaml'daki gerekli yerleşik üçüncü taraf kitaplıklarını güncelleyin ve Python 3'e geçiş için kapıyı açık bırakı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
app.yaml dosyanızı, libraries bölümünü güncelleyerek düzenleyin. jinja2 öğesini kaldırıp grpcio, setuptools ve ssl öğelerini ekleyin. Üç kitaplığın tümü için mevcut olan en son sürümü seçin. Ayrıca, Python 3 runtime yönergesini de ekleyin ancak yorum satırı olarak. İşleminiz tamamlandığında aşağıdaki gibi görünmelidir (Python 3.9'u seçtiyseniz):
ÖNCESİ:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
SONRASI:
#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 öncelikle App Engine sunucularında kullanılabilen Python 2 yerleşik kitaplıklarıyla ilgilidir (bu nedenle bunları kendiniz paketlemeniz gerekmez). Jinja2'yi kaldırdık. Çünkü bu kitaplık, 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 için ssl kitaplığı gerekir. En üstteki yorum satırı haline getirilmiş çalışma zamanı yönergesi, bu uygulamayı Python 3'e taşımaya hazır olduğunuzda kullanılmak içindir. Bu konuyu eğitimin sonunda ele alacağız.
requirements.txt
Flask çerçevesi, Cloud NDB ve Cloud Storage istemci kitaplıklarını gerektiren bir requirements.txt dosyası ekleyin. Bu kitaplıkların hiçbiri yerleşik değildir. Aşağıdaki içeriğe sahip dosyayı oluşturun:
flask
google-cloud-ndb
google-cloud-storage
Python 2 App Engine çalışma zamanı, yerleşik olmayan üçüncü taraf kitaplıkların kendiliğinden 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 3 varsa bu kitaplıkların Python 2 sürümlerini aldığınızdan emin olmak için pip2 komutunu kullanmanız gerekebilir. Python 3'e yükselttikten sonra artık kendiniz paket 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. Aşağıdaki içeriğe sahip dosyayı 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 dokümanlarının Python 2 uygulamaları için kitaplık yükleme bölümünde listelenen adımlara benzer veya aynı olmalıdır. Daha spesifik olarak, appengine_config.py içeriği, oradaki 5. adımda yer alan içerikle eşleşmelidir.
Yapılandırma dosyalarıyla ilgili çalışmalar tamamlandı. Şimdi uygulamaya geçelim.
5. Uygulama dosyalarını değiştirme
İçe aktarılanlar
main.py ile ilgili ilk değişiklik grubunda, değiştirilen tüm öğeler çıkarılır. Değişiklikler şu şekildedir:
webapp2yerine Flask kullanılıyorwebapp2_extraskonumundaki Jinja2'yi kullanmak yerine Flask ile birlikte gelen Jinja2'yi kullanın.- App Engine Blobstore ve NDB, Cloud NDB ve Cloud Storage ile değiştirildi
webappiçindeki Blobstore işleyicilerinin yeriniiostandart kitaplık modülü, Flask vewerkzeugyardımcı programlarının birleşimi almıştır.- Blobstore, varsayılan olarak uygulamanızın URL'siyle (
PROJECT_ID.appspot.com) aynı adı taşıyan bir Cloud Storage paketine yazar. Cloud Storage istemci kitaplığına taşıdığımız içingoogle.auth, tam olarak aynı paket adını belirtmek üzere proje kimliğini almak için kullanılır. (Paket adı artık sabit kodlanmadığı için değiştirilebilir.)
ÖNCESİ:
import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers
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 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, BaseHandler ile webapp2_extras arasındaki Jinja2 kullanımını belirten koddur. Jinja2, Flask ile birlikte geldiği ve varsayılan şablon oluşturma motoru olduğu için bu gereksizdir. Bu nedenle kaldırın.
16. modül tarafında, eski uygulamada bulunmayan nesneleri örneklendirin. Bu işlem, Flask uygulamasını ilk kullanıma hazırlamayı ve Cloud NDB ile Cloud Storage için API istemcileri oluşturmayı içerir. Son olarak, yukarıda içe aktarma bölümünde açıklandığı gibi Cloud Storage paketi adını bir araya getiririz. Bu güncellemeler uygulanmadan önce ve uygulandıktan sonraki görünüm:
ÖNCESİ:
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))
SONRASI:
app = Flask(__name__)
ds_client = ndb.Client()
gcs_client = storage.Client()
_, PROJECT_ID = google.auth.default()
BUCKET = '%s.appspot.com' % PROJECT_ID
Veri deposu erişimini güncelleme
Cloud NDB, App Engine NDB ile büyük ölçüde uyumludur. Daha önce ele alınan bir fark, API istemcisi gerekliliğidir. Diğer bir fark ise ikincisinin, Datastore erişiminin API istemcisinin Python bağlam yöneticisi tarafından kontrol edilmesini gerektirmesidir. Bu, Cloud NDB istemci kitaplığı kullanılarak yapılan 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 biri; diğeri ise Blobstore ve nesnelerinin (ör.BlobKey) Cloud Storage tarafından desteklenmemesidir. Bu nedenle, file_blob öğesini ndb.StringProperty olarak değiştirin. Aşağıda, bu değişiklikleri yansıtan veri modeli sınıfı ve güncellenmiş store_visit() ve fetch_visits() işlevleri verilmiştir:
ÖNCESİ:
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)
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.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)
Şu ana kadar yapılan değişikliklerin görsel gösterimi aşağıda verilmiştir:

İşleyicileri güncelleme
Yükleme işleyicisi
webapp2'daki işleyiciler sınıflardır. Flask'te ise 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:
ÖNCESİ:
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)
SONRASI:
@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 yapıtları artık
blob_idyerine, varsa dosya adıyla (fname), yoksaNoneile (kullanıcı dosya yüklemeyi devre dışı bıraktı) tanımlanır. - Blobstore işleyicileri, yükleme sürecini kullanıcılarından soyutlaştırıyordu ancak Cloud Storage'da bu durum geçerli değildir. 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 süslenmiş işleyicide bulunur.- Her iki işleyici de
POSTisteğini HTTP 307 dönüş koduyla koruyarak ana sayfaya (/) yönlendirme yaparak işlevlerini tamamlar.
İndirme işleyicisi
İndirme işleyicisini güncelleme, yükleme işleyicisine benzer bir kalıba sahiptir ancak incelenecek çok daha az kod vardır. Blobstore ve webapp işlevini Cloud Storage ve Flask eşdeğerleriyle değiştirin:
ÖNCESİ:
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)
SONRASI:
@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üncelleme ile ilgili notlar:
- Flask, işleyici işlevlerini rotalarıyla süslerken
webappbunu alttaki bir yönlendirme tablosunda yapar. Bu nedenle, Flask'ın ('/view/<path:fname>') aksinewebapp'nın kalıp eşleştirme söz dizimini (('/view/([^/]+)?') tanıyın. - Yükleme işleyicisinde olduğu gibi, Blobstore işleyicileri tarafından soyutlanan işlevsellik için Cloud Storage tarafında biraz daha fazla çalışma yapılması gerekir. Bu işlevsellik, söz konusu dosyanın (büyük ikili nesne) tanımlanması ve Blobstore işleyicisinin tek
send_blob()yöntem çağrısı yerine ikili programın açıkça indirilmesidir. - Her iki durumda da bir yapıt bulunamazsa kullanıcıya HTTP 404 hatası döndürülür.
Ana işleyici
Ana uygulamadaki son değişiklikler ana işleyicide gerçekleşir. webapp2 HTTP fiil yöntemlerinin yerini, işlevlerini birleştiren tek bir işlev alıyor. MainHandler sınıfını root() işleviyle değiştirin ve webapp2 yönlendirme tablosunu aşağıdaki gibi kaldırın:
ÖNCESİ:
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)
SONRASI:
@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, root() içinde if-else ifadesi kullanılır. Ayrıca, root() tek bir işlev olduğundan GET ve POST için şablonu oluşturmak üzere yalnızca bir çağrı yapılır. Bu, webapp2'de mümkün değildir.
main.py'da yapılan bu ikinci ve son değişiklik grubunun görsel temsilini aşağıda bulabilirsiniz:

(isteğe bağlı) Geriye dönük uyumluluk "geliştirme"
Bu nedenle, 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 tamamlanmış 16. Modül uygulaması, Blobstore dosyalarını olduğu gibi görüntüleyemez. Başka bir deyişle, bu taşıma işlemini gerçekleştirerek eski sürümlerle uyumsuz bir değişiklik yaptık. Şimdi bu açığı kapatmaya çalışan main.py adlı bir alternatif sürüm sunuyoruz (depoda bulunur).main-migrate.py
Blobstore'da oluşturulan dosyaları destekleyen ilk "uzantı", BlobKeyProperty (Cloud Storage'da oluşturulan dosyalar için StringProperty'ye ek olarak) içeren bir veri modelidir:
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. Artık yeni ziyaretler oluştururken file_blob yerine file_gcs içinde açıkça bir değer depoladığınız için store_visit biraz farklı görünüyor:
ÖNCESİ:
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()
SONRASI:
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 ziyaretler getirilirken veriler şablona gönderilmeden önce "normalleştirilir":
ÖNCESİ:
@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)
SONRASI:
@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'nin (ya da ikisinin de) varlığını onaylayın. Kullanılabilir bir dosya varsa mevcut olanı seçin ve bu tanımlayıcıyı kullanın (Blobstore'da oluşturulan dosyalar için BlobKey veya Cloud Storage'da oluşturulan dosyalar için dosya adı). "Cloud Storage'da oluşturulan dosyalar" ifadesiyle, Cloud Storage istemci kitaplığı kullanılarak oluşturulan dosyaları kastediyoruz. Blobstore da Cloud Storage'a yazar ancak bu durumda Blobstore tarafından oluşturulan dosyalar söz konusudur.
Daha da önemlisi, son kullanıcı için verileri normalleştirmek veya ETL (ayıklama, dönüştürme ve yükleme) yapmak için 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'nin mevcut olup olmadığını kontrol eder ve varsa bunlardan birini (veya ikisi de yoksa None) seçer.
main.py ile 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 destekleyici dosyaları istiyorsanız kendi uygulamalarınız için geçişleri planlamanıza yardımcı olmak üzere bu tür senaryolarla nasıl başa çıkılacağına dair bir örnek olarak main-migrate.py'a göz atın. Karmaşık geçişler yapılırken özel durumların ortaya çıkması muhtemeldir. Bu nedenle, bu örnek gerçek verilerle gerçek uygulamaları modernleştirme konusunda daha fazla bilgi vermeyi amaçlamaktadır.
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ı yeniden dağıtmadan önce, bu kendi kendine paketlenmiş üçü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 dosyasını main.py olarak yeniden adlandırın. Şimdi gcloud app deploy uygulamasını çalıştırın ve uygulamanın 15. Modül uygulamasının aynısı olduğunu doğrulayı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, App Engine NDB'yi Cloud NDB ve webapp2'ı Flask ile değiştirme codelab'ini tamamladığınız için tebrik ederiz. Kodunuz artık FINISH (Module 16) klasöründeki kodla eşleşmelidir. Alternatif main-migrate.py de bu klasörde bulunuyor.
Python 3'e "geçiş"
Bu uygulamayı Python 3'e taşımak için app.yaml dosyasının en üstündeki yorum satırı haline getirilmiş Python 3 runtime yönergesi yeterlidir. Kaynak kodun kendisi zaten Python 3 ile uyumlu olduğundan 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 yorum işaretini kaldırın.app.yamliçindeki 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 gereksizdir)
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/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- Yukarıdaki depolama bağlantıları,
PROJECT_IDve *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:
- App Engine Blobstore hizmeti, depolanan veri kotaları ve sınırları kapsamındadır. Bu nedenle, eski paketlenmiş hizmetlerin fiyatlandırma sayfasını da inceleyin.
- Cloud Storage, belirli bölgeler için ücretsiz katman sunar. Daha fazla bilgi için genel fiyatlandırma sayfasına da göz atın.
- 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ına bakın."
15. modülden 16. modüle geçtiyseniz Blobstore'da verileriniz olmaya devam eder. Bu nedenle, fiyatlandırma bilgilerini yukarıda paylaştık.
Sonraki adımlar
Bu eğitimin yanı sıra eski paketlenmiş hizmetlerden geçişe odaklanan diğer taşıma modüllerini de inceleyebilirsiniz:
- 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-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ğil. Küçük bir App Engine uygulamanız veya sınırlı işlevselliğe sahip bir uygulamanız varsa ve bunu bağımsız bir mikro hizmete dönüştürmek istiyorsanız ya da tek bir uygulamayı birden fazla yeniden kullanılabilir bileşene ayırmak istiyorsanız Cloud Functions'a geçmeyi düşünebilirsiniz. Container mimarisine alma, özellikle CI/CD (sürekli entegrasyon/sürekli teslim veya dağıtım) ardışık düzeninden oluşuyorsa uygulama geliştirme iş akışınızın bir parçası haline geldiyse Cloud Run'a geçmeyi düşünebilirsiniz. Bu senaryolar aşağıdaki modüllerde ele alınır:
- App Engine'den Cloud Functions'a geçiş: 11. Modül'e bakın.
- App Engine'den Cloud Run'a taşıma: Uygulamanızı Docker ile container mimarisine almak için 4. Modül'e, container'lar, Docker bilgisi veya
Dockerfileolmadan yapmak için 5. Modül'e bakın.
Başka bir sunucusuz platforma geçmek 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 göz önünde bulundurmanızı öneririz.
Bir sonraki geçiş modülünüz hangisi olursa olsun, tüm Serverless Migration Station içeriklerine (codelab'ler, videolar, kaynak kodu [varsa]) açık kaynaklı depodan erişebilirsiniz. Depodaki README, hangi taşımaların dikkate alınması gerektiği ve ilgili "sıra" hakkında da rehberlik sağlar.
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ı
15. Modül (BAŞLANGIÇ) ve 16. Modül (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 15 | Yok | |
Modül 16 (bu codelab) | (Python 2 ile aynı) |
Online kaynaklar
Bu eğitimle ilgili olabilecek online kaynakları aşağıda bulabilirsiniz:
App Engine Blobstore ve Cloud Storage
- App Engine Blobstore hizmeti
- Cloud Storage istemci kitaplığına geçiş
- 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'in 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 3'e App Engine (standart ortam) taşıma kılavuzu
- App Engine fiyatlandırma ve kota bilgileri
- İkinci nesil App Engine platformunun kullanıma sunulması (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 gönderilen taşıma örnekleri deposu
Diğer Cloud 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 frameworkwebapp2belgelerwebapp2_extrasbağlantılarıwebapp2_extrasJinja2 belgeleri- Flask web çerçevesi
Videolar
- Sunucusuz Taşıma İstasyonu
- Sunucusuz Expeditions
- Google Cloud Tech kanalına 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.