1. Genel Bakış
Sunucusuz Taşıma İstasyonu codelab'leri serisi (kendi kendine ilerleyen, uygulamalı eğiticiler) ve ilgili videolar, Google Cloud sunucusuz geliştiricilerinin uygulamalarını bir veya daha fazla taşıma işleminde yönlendirerek uygulamalarını modernleştirmelerine yardımcı olmayı amaçlar. Bu videolar genellikle eski hizmetlerden uzaklaştırılır. Bu sayede uygulamalarınızı daha taşınabilir hale getirir, daha fazla seçenek ve esneklik elde edebilir, daha geniş bir Cloud ürünü yelpazesiyle entegrasyon ve erişim elde edebilir, ayrıca yeni dil sürümlerine kolayca geçiş yapabilirsiniz. Başlangıçta özellikle App Engine (standart ortam) geliştiricileri olmak üzere ilk Cloud kullanıcılarına odaklanan bu seri, Cloud Functions ve Cloud Run gibi diğer sunucusuz platformları veya uygun olduğu durumlarda diğer sunucusuz platformları ya da diğer platformları kapsayacak kadar geniş kapsamlıdır.
Bu codelab'de App Engine Blobstore'dan Cloud Storage'a nasıl geçiş yapacağınızı öğrenebilirsiniz. Ayrıca, aşağıdakilerden örtülü taşıma işlemleri de yapılır:
webapp2
web çerçevesi'nden Flask'a (Modül 1 kapsamındadır)- Datastore erişimi için App Engine NDB'den Cloud NDB'ye (2. Modül kapsamındadır)
- Python 2'den 3'e (taşınan uygulama hem Python 2 hem 3 ile uyumludur)
Adım adım açıklamalı daha fazla bilgi için ilgili taşıma modüllerine bakın.
Demoda aşağıdaki işlemleri yapmayı öğreneceksiniz:
- App Engine Blobstore API/kitaplığının kullanımını ekleyin
- Kullanıcının yüklemelerini Blobstore hizmetine depolama
- Cloud Storage'a geçiş işleminin bir sonraki adımına hazırlanın
Gerekenler
- Etkin bir GCP faturalandırma hesabına sahip bir Google Cloud Platform projesi
- Temel Python becerileri
- Yaygın Linux komutlarıyla ilgili bilgi
- App Engine uygulamalarını geliştirme ve dağıtma ile ilgili temel bilgiler
- Çalışan bir Modül 15 App Engine uygulaması: Modül 15 codelab'ini tamamlayın (önerilen) veya depodan Modül 15 uygulamasını kopyalayın
Anket
Bu eğiticiden 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, Modül 15'teki örnek uygulamayla başlar ve Blobstore'dan (ve NDB) Cloud Storage'a (ve Cloud NDB'ye) geçişin nasıl yapılacağını gösterir. Taşıma sürecinde, App Engine'in eski paketlenmiş hizmetlerindeki bağımlılıklar değiştirilir. Bu sayede, isterseniz uygulamalarınızı 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'un orijinal web uygulaması çerçevesine bağımlıları olduğundan örnek uygulama, Flask yerine webapp2 çerçevesini kullanmaktadır. Bu eğiticide Cloud Storage, Cloud NDB, Flask ve Python 3'e taşıma işlemleri açıklanmaktadır.
Uygulama hâlâ son kullanıcı "ziyaretlerini" kaydetmeye devam ediyor ve en son on öğeyi görüntüler ancak önceki (Modül 15) codelab'i Blobstore kullanımına uygun yeni bir işlev eklemiştir: Uygulama, son kullanıcılardan "ziyaretlerine" karşılık gelen bir yapı (dosya) yüklemelerini ister. Kullanıcılar bunu yapabilir veya "atla"yı seçebilir. tıklayın. Kullanıcının kararından bağımsız olarak sonraki sayfa, bu uygulamanın önceki enkarnasyonlarıyla aynı çıktıyı verir ve en son ziyaretleri görüntüler. Bir ekstra farkla, ilgili yapılar içeren ziyaretlerde "görünüm" bir ziyaretin yapısını görüntüleme bağlantısı. Bu codelab'de daha önce bahsedilen taşıma işlemleri uygulanırken açıklanan işlevler korunur.
3. Kurulum/Ön Çalışma
Eğiticinin ana bölümüne geçmeden önce projemizi oluşturalım, kodu alın ve çalışan bir kodla başladığımızı öğrenmemiz için temel uygulamayı dağıtın.
1. Proje oluşturun
Daha önce Modül 15 uygulamasını dağıttıysanız aynı projeyi (ve kodu) yeniden kullanmanızı öneririz. Alternatif olarak, yeni bir proje oluşturabilir veya mevcut başka bir projeyi yeniden kullanabilirsiniz. Projenin etkin bir faturalandırma hesabı olduğundan ve App Engine'in etkin olduğundan emin olun.
2. Temel örnek uygulamayı al
Bu codelab'in ön koşullarından biri, çalışan bir Modül 15 örnek uygulamasına sahip olmaktır. Bu SDK'ya sahip değilseniz Modül 15'ten "START" alabilirsiniz. (bağlantıyı aşağıdaki bağlantı) tıklayın. Bu codelab'de, Modül 16'daki "FINISH"tekine benzeyen bir kod bulunmaktadır. Son adım ise her adımda yol gösterir. tıklayın.
- BAŞLAT: Modül 15 klasörü (Python 2)
- SON: Modül 16 klasörü (Python 2)
- Deponun tamamı (ZIP dosyasını klonlamak veya indirmek için)
Modül 15 STARTing 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
ürününün alternatif bir sürümüdür. Bir Cloud Storage paketinin, proje kimliğine (PROJECT_ID
.appspot.com
) göre uygulamaya atanan URL'nin varsayılanından farklı bir şekilde seçilmesine olanak tanır. Bu dosya, bu (Modül 16) codelab'inde yer almamaktadır. Yalnızca istenirse ilgili dosyaya benzer taşıma teknikleri uygulanabilir.
3. Temel uygulamayı (yeniden) dağıtma
Hemen yürütmek için kalan ön çalışma adımlarınız:
gcloud
komut satırı aracını yeniden tanıma- Örnek uygulamayı
gcloud app deploy
ile yeniden dağıtın - Uygulamanın App Engine'de sorunsuz çalıştığını onaylayın
Bu adımları başarıyla tamamladıktan sonra Modül 15 uygulamanızın çalıştığını onaylayın. İlk sayfada, kullanıcılara "atla" seçeneğiyle birlikte yüklemek üzere bir ziyaret yapı dosyası isteyen bir form gösteriliyor. düğmesini, devre dışı bırakmak için:
Kullanıcılar bir dosya yükledikten veya atladıktan sonra, uygulama, aşina oldukları "en son ziyaretleri" oluşturur sayfa:
Bir yapı içeren ziyaretler "görüntüleme"ye sahip olur bağlantıyı, yapıyı görüntülemek (veya indirmek) için ziyaret zaman damgasının sağında bulunur. Uygulamanın işlevselliğini onayladıktan sonra eski App Engine hizmetlerinden (webapp2, NDB, Blobstore) çıkıp modern alternatiflere (Flask, Cloud NDB, Cloud Storage) geçmeye 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ı işler. Gerekli görevler şunlardır:
app.yaml
uygulamasında gerekli yerleşik 3. taraf kitaplıklarını güncelleyin ve Python 3 taşıma işlemine açık bırakın- Yerleşik olmayan tüm gerekli kitaplıkları belirten
requirements.txt
ekleyin - Uygulamanın hem yerleşik hem de yerleşik olmayan üçüncü taraf kitaplıkları desteklemesi için
appengine_config.py
paketini ekleyin
app.yaml
libraries
bölümünü güncelleyerek app.yaml
dosyanızı düzenleyin. jinja2
adlı kullanıcıyı kaldırıp grpcio
, setuptools
ve ssl
adlı kullanıcıları ekleyin. Üç kitaplık için de kullanılabilir en son sürümü seçin. Python 3 runtime
yönergesini de ekleyin, ancak yorum yapmadınız. İşiniz bittiğinde (Python 3.9'u seçtiyseniz) kod aşağıdaki gibi görünmelidir:
ÖNCE:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
SONRA:
#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 ağırlıklı olarak App Engine sunucularında bulunan Python 2 yerleşik kitaplıkları ile ilgilidir (böylece bunları kendi başınıza gruplandırmanız gerekmez). Jinja2'yi, reqs.txt dosyasına ekleyeceğimiz Flask ile birlikte geldiği için kaldırdık. Cloud NDB ve Cloud Storage gibi Google Cloud istemci kitaplıkları her kullanıldığında grpcio ve setuptools gerekir. Son olarak, Cloud Storage'ın kendisi için SSL kitaplığı gerekir. Üstteki yorumlu çalışma zamanı yönergesi, bu uygulamayı Python 3'e taşımaya hazır olduğunuzda içindir. Bu konuyu bu eğiticinin sonunda ele alacağız.
requirements.txt
Flask çerçevesi ile hiçbiri yerleşik olmayan Cloud NDB ve Cloud Storage istemci kitaplıkları gerektiren bir requirements.txt
dosyası ekleyin. 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 kendi kendine paketlenmesini gerektirir. Bu nedenle, aşağıdaki komutu yürüterek bu kitaplıkları lib klasörüne yükleyin:
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 geçiş yaptıktan sonra artık paketinizi oluşturmanız gerekmez.
appengine_config.py
Yerleşik ve yerleşik olmayan üçüncü taraf kitaplıkları 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 olmak gerekirse appengine_config.py
içeriğinin içeriği buradaki 5. adımda belirtilenlerle eşleşmelidir.
Yapılandırma dosyalarıyla ilgili çalışmalar tamamlandığından, uygulamaya geçelim.
5. Uygulama dosyalarını değiştirme
İçe aktarılanlar
main.py
ile ilgili ilk değişiklik grubu, değiştirilen tüm öğelerin değiştirilmesini içeriyor. Değişiklikler aşağıda belirtilmiştir:
webapp2
, Flask ile değiştirildiwebapp2_extras
Jinja2'yi kullanmak yerine Flask ile birlikte gelen Jinja2'yi kullanın- App Engine Blobstore ve NDB, yerini Cloud NDB ve Cloud Storage'a bırakıyor
webapp
içindeki Blobstore işleyicilerin yeriniio
standart kitaplık modülü, Flask vewerkzeug
yardımcı programlarının bir kombinasyonu aldı- Varsayılan olarak Blobstore, adını uygulamanızın URL'sinden (
PROJECT_ID.appspot.com
) alan bir Cloud Storage paketine yazar. Cloud Storage istemci kitaplığına taşıma yaptığımız içingoogle.auth
, aynı paket adını belirtmek amacıyla proje kimliğini almak için kullanılır. (Artık koda gömülü olmadığı için paket adını 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
alan adı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.
SONRA:
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 sonraki kod bloğu, webapp2_extras
kaynağından Jinja2 kullanımını belirten BaseHandler
kodudur. Jinja2'nin Flask ile birlikte gelmesi ve varsayılan şablon oluşturma motoru olması nedeniyle bu gerekli değildir, bu nedenle kaldırın.
Modül 16 tarafında, eski uygulamada bulunmayan nesneleri örneklendirebilirsiniz. Buna Flask uygulamasının başlatılması ve Cloud NDB ve Cloud Storage için API istemcileri oluşturulması dahildir. Son olarak, Cloud Storage paketi adını yukarıdaki içe aktarmalar bölümünde açıklandığı gibi derledik. Bu güncellemelerin uygulanmadan önceki ve sonraki adımları aşağıda verilmiştir:
Ö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))
SONRA:
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 ele aldığımız farklardan biri, API istemcisi ihtiyacıdır. Bir diğer olasılık ise Datastore erişiminin API istemcisinin Python bağlam yöneticisi tarafından kontrol edilmesini gerektirir. Esasen bu, Cloud NDB istemci kitaplığını kullanan tüm Datastore erişim çağrılarının yalnızca Python with
blokları içinde gerçekleşebileceği anlamına gelir.
Yani bir değişiklik söz konusudur. diğeri ise Blobstore ve nesneleri (ör. BlobKey
, Cloud Storage tarafından desteklenmediğinden file_blob
değerini ndb.StringProperty
olacak şekilde değiştirin. 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)
SONRA:
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 resimli temsili:
İşleyicileri güncelleme
Yükleme işleyici
webapp2
bölgesindeki işleyiciler, Flask'ta işlev görürken sınıflardır. Flask, işlevi dekore etmek için HTTP fiil yöntemi yerine fiili kullanıyor. Blobstore ve webapp
işleyicilerinin yerini, Cloud Storage'ın yanı sıra Flask ve yardımcı programındaki işlevler alıyor:
Ö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)
SONRA:
@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ıları artık
blob_id
yerine dosya adıyla (fname
), varsaNone
ile tanımlanıyor (kullanıcı dosya yüklemeyi devre dışı bıraktı). - Blobstore işleyicileri, yükleme işlemini kullanıcılarından soyutlasa da Cloud Storage bunu yapmaz. Bu nedenle, dosyanın blob nesnesini ve konumunu (paket) ayarlayan yeni eklenen kodun yanı sıra gerçek yüklemeyi gerçekleştiren çağrıyı da 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 ana sayfaya (
/
) yönlendirerek işlevlerini tamamlarkenPOST
isteğini HTTP 307 dönüş koduyla korur.
İşleyiciyi indir
İndirme işleyicinin güncellenmesi, yükleme işleyiciye benzer bir kalıp izler ve yalnızca çok daha az koda bakmanız gerekir. Blobstore ve webapp
işlevini, 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)
SONRA:
@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:
- Yine Flask, işleyici işlevlerini kendi rotalarıyla süslerken
webapp
, bunu alttaki bir yönlendirme tablosunda yapar. Bu nedenle, Flask'ın ('/view/<path:fname>'
) ve('/view/([^/]+)?'
kalıp eşleştirme söz dizimini tanıyın. - Yükleme işleyicide olduğu gibi, Blobstore işleyicileri tarafından soyutlanan işlevler, yani söz konusu dosyanın (blob) tanımlanması ve ikili programın açık bir şekilde indirilmesi ve Blobstore işleyicinin tek
send_blob()
yöntem çağrısının karşılaştırılması için Cloud Storage tarafında da biraz daha fazla çalışma yapılması gerekir. - Her iki durumda da, yapı bulunmazsa 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)
SONRA:
@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)
get()
ve post()
yöntemleri arasındaki ayrımlar, root()
dilindeki bir if-else
ifadesidir. Ayrıca, root()
tek bir işlev olduğundan hem GET
hem de POST
için şablon oluşturmak üzere yalnızca bir çağrı gerçekleştirilir, ancak webapp2
içinde bu mümkün değildir.
main.py
ile ilgili bu ikinci ve son değişiklik grubunun resimli temsili şu şekildedir:
(isteğe bağlı) Geriye dönük uyumluluk "geliştirme"
Dolayısıyla yukarıda oluşturulan çözüm mükemmel bir şekilde çalışır. Ancak bu durum, yalnızca sıfırdan başlıyorsanız ve Blobstore tarafından oluşturulmuş dosyalarınız yoksa işe yarar. Uygulamayı, dosyaları BlobKey
yerine dosya adına göre tanımlayacak şekilde güncellediğimiz için tamamlanan Modül 16 uygulaması, artık Blobstore dosyalarını görüntüleyemeyecek. Başka bir deyişle, bu taşıma işlemini gerçekleştirirken geriye dönük olarak uyumsuz bir değişiklik yaptık. Şimdi de main.py
uygulamasının bu boşluğu doldurmaya çalışan main-migrate.py
adlı (depoda bulunan) alternatif bir sürümünü sunuyoruz.
İlk "uzantı" bir BlobKeyProperty
(Cloud Storage'da oluşturulan dosyalar için StringProperty
öğesine 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ır. file_gcs
ise Cloud Storage dosyaları için kullanılır. Artık yeni ziyaret oluştururken file_blob
yerine file_gcs
içine bir değer açıkça girildiğinden 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()
SONRA:
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 "normalize et"i seç verileri şablona göndermeden önce eklemeniz gerekir:
Ö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)
SONRA:
@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
varlığının (ya da hiçbirinin) varlığını onaylayın. Kullanılabilir bir dosya varsa mevcut olanı seçin ve bu tanımlayıcıyı (Blobstore tarafından oluşturulan dosyalar için BlobKey
, Cloud Storage tarafından oluşturulan dosyalar için dosya adı) kullanın. "Cloud Storage tarafından oluşturulan dosyalar" dediğimizde, Cloud Storage istemci kitaplığı kullanılarak oluşturulan dosyaları kastediyoruz. Blobstore, aynı zamanda Cloud Storage'a da yazar ancak bu durumda Blobstore tarafından oluşturulan dosyalar olur.
Daha da önemlisi, son kullanıcı için verileri normalleştirmek veya ETL (çıkarmak, dönüştürmek ve yüklemek) üzere kullanılan 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üyor: Kod, tüm ziyaretleri döngüye alır ve her ziyaret için ziyaretçi ve zaman damgası verilerini tam olarak alır, ardından file_gcs
veya file_blob
olup olmadığını kontrol eder. Varsa bunlardan birini seçer (veya ikisi de yoksa None
).
main.py
ile main-migrate.py
arasındaki farkların bir örneği aşağıda verilmiştir:
Blobstore tarafından oluşturulan dosyalar olmadan sıfırdan başlıyorsanız main.py
kullanın. Ancak hem Blobstore ve Cloud Storage tarafından oluşturulan dosyalara geçiş yapıyor ve bunları desteklemek istiyorsanız kendi uygulamalarınız için taşımaları planlamanıza yardımcı olmak gibi senaryoların nasıl ele alınacağına ilişkin bir örnek olarak main-migrate.py
sayfasına göz atın. Karmaşık taşıma işlemleri yapılırken özel durumların ortaya çıkması olasılığı yüksektir. Dolayısıyla, bu örneğin, gerçek uygulamaları gerçek verilerle modernleştirmeye daha uygun olduğunu göstermek amaçlanmıştır.
6. Özet/Temizlik
Bu bölümde, uygulamayı dağıtıp amaçlandığı şekilde ve yansıtılan herhangi bir çıkışta çalıştığını doğrulayarak bu codelab'i özetledik. Uygulama doğrulamasından sonra temizlik adımlarını uygulayın ve sonraki adımları değerlendirin.
Uygulamayı dağıtma ve doğrulama
Uygulamanızı yeniden dağıtmadan önce, bu bağımsız üçüncü taraf kitaplıklarını lib klasöründe almak için pip install -t lib -r requirements.txt
öğesini çalıştırdığınızdan emin olun. Geriye dönük uyumlu çözümü çalıştırmak istiyorsanız önce main-migrate.py
öğesini main.py
olarak yeniden adlandırın. Şimdi gcloud app deploy
komutunu ç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 ziyaret edilen sayfa şuna benzer:
App Engine Blobstore'u Cloud Storage, App Engine NDB'yi Cloud NDB ile ve webapp2
kodunu Flask ile değiştirerek bu codelab'i tamamladığınız için tebrik ederiz. Kodunuz artık FINISH (Modül 16) klasöründeki kodla eşleşmelidir. Bu klasörde alternatif main-migrate.py
de mevcuttur.
Python 3 "taşıma"
Bu uygulamayı Python 3'e taşımak için gereken tek şey, app.yaml
üst kısmındaki yorum eklenmiş Python 3 runtime
yönergesidir. Kaynak kodun kendisi Python 3 ile uyumludur, dolayısıyla herhangi bir değişiklik gerekmez. Bunu bir Python 3 uygulaması olarak dağıtmak için aşağıdaki adımları yürütün:
app.yaml
üst kısmındaki Python 3runtime
yönergesinin açıklamasını kaldırın.app.yaml
içindeki diğer tüm satırları silin.appengine_config.py
dosyasını silin. (Python 3 çalışma zamanında kullanılmaz)- Varsa
lib
klasörünü silin. (Python 3 çalışma zamanı ile gerekli değildir)
Temizleme
Genel
Şimdilik işiniz bittiyse faturalandırılma olmaması için App Engine uygulamanızı devre dışı bırakmanızı öneririz. Bununla birlikte, daha fazla test veya deneme yapmak isterseniz App Engine platformunun ücretsiz bir kotası vardır ve bu kullanım katmanını aşmadığınız sürece sizden ücret alınmaz. Burası işlem içindir, ancak ilgili App Engine hizmetleri için de ücret alınabilir. Daha fazla bilgi için fiyatlandırma sayfasına göz atın. Bu taşıma işlemi başka Cloud hizmetlerini içeriyorsa bunlar ayrı olarak faturalandırılır. Her iki durumda da (geçerliyse) "Bu codelab'e özel" bölümünü inceleyin bölümüne bakın.
Ayrıntılı açıklama için, App Engine gibi Google Cloud sunucusuz bilgi işlem platformuna dağıtım yapmak küçük derleme ve depolama maliyetleri gerektirir. Cloud Build'in ve Cloud Storage'ın kendi ücretsiz kotası vardır. Söz konusu resmin depolanması bu kotanın bir kısmını kullanır. Ancak, bu kadar ücretsiz katmanın olmadığı bir bölgede yaşıyor olabilirsiniz. Bu nedenle, olası maliyetleri en aza indirmek için depolama alanı kullanımınız konusunda dikkatli olun. Belirli Cloud Storage "klasörleri" şunları incelemeniz gerekir:
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
*ifadenize bağlıdır (örneğin, "us
") Uygulamanız ABD'de barındırılıyorsa.
Öte yandan, bu uygulamayı veya diğer ilgili taşıma codelab'lerini kullanmayacak 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 hizmeti ve eski paketlenmiş 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 inceleyin.
- App Engine Datastore hizmeti, aynı zamanda ücretsiz bir katmana sahip olan Cloud Datastore (Data Store modunda Cloud Firestore) tarafından sağlanır; daha fazla bilgi için fiyatlandırma sayfasını inceleyin."
Modül 15'ten 16'ya geçiş yaptıysanız Blobstore'da verileriniz olmaya devam edeceğini unutmayın. Bu nedenle, fiyatlandırma bilgilerini yukarıda bulabilirsiniz.
Sonraki adımlar
Bu eğiticinin yanı sıra, eski paket servislerin kullanımdan kaldırılmasına odaklanan diğer taşıma modüllerini de göz önünde bulundurun:
- Modül 2: App Engine
ndb
'den Cloud NDB'ye geçiş - Modüller 7-9: App Engine Görev Sırası push görevlerini Cloud Tasks'a taşıma
- Modüller 12-13: App Engine Memcache'den Cloud Memorystore'a taşıma
- Modül 18-19: App Engine Görev Sırası'ndan (görev alma) 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 varsa veya sınırlı işlevselliğe sahip bir uygulamanız varsa ve bunu bağımsız bir mikro hizmete dönüştürmek ya da monolitik bir uygulamayı yeniden kullanılabilir birden fazla bileşene ayırmak istiyorsanız Cloud Functions'a geçmek için iyi nedenler olabilir. Container mimarisine alma işlemi, 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ş yapmayı düşünün. Bu senaryolar aşağıdaki modüllerde ele alınmıştır:
- App Engine'den Cloud Functions'a geçiş: Modül 11'e bakın
- App Engine'den Cloud Run'a taşıma: Uygulamanızı Docker ile container mimarisine almak için Modül 4'e, bu işlemi container'lar, Docker bilgileri ya da
Dockerfile
olmadan yapmak için Modül 5'e bakın.
Başka bir sunucusuz platforma geçmek isteğe bağlıdır. Bu nedenle, 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 taşıma modülünden bağımsız olarak tüm Sunucusuz Taşıma İstasyonu içeriklerine (codelab'ler, videolar, kaynak kodu [kullanılabilir olduğunda]) açık kaynak deposundan erişebilirsiniz. Deponun README
özelliği, hangi taşıma işlemlerinin göz önünde bulundurulacağı ve ilgili "siparişler" hakkında da bilgi sağlar. göz atmanızı öneririm.
7. Ek kaynaklar
Codelab sorunları/geri bildirimi
Bu codelab'de herhangi bir sorun bulursanız lütfen göndermeden önce sorununuzu arayın. Arama ve yeni sayı oluşturma bağlantıları:
Taşıma kaynakları
Modül 15 (START) ve Modül 16 (FINISH) için depo klasörlerinin bağlantılarını aşağıdaki tabloda bulabilirsiniz. Bunlara tüm App Engine codelab taşıma işlemleri için depodan da erişilebilir. Bu depoyu klonlayabilir veya ZIP dosyası indirebilirsiniz.
Codelab | Python 2 | Python 3 |
Modül 15 | Yok | |
Modül 16 (bu codelab) | (Python 2 ile aynı) |
Çevrimiçi kaynaklar
Aşağıda, bu eğitim için alakalı olabilecek çevrimiçi 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 ile Python 2 arasındaki farklar 3 App Engine (standart ortam) çalışma zamanı
- Python 2'den 3'e App Engine (standart ortam) taşıma kılavuzu
- App Engine fiyatlandırması ve kota bilgileri
- İkinci nesil App Engine platformunun kullanıma sunulması (2018)
- Birinci ve ikinci nesil platformlar
- Eski çalışma zamanları için uzun süreli destek
- Belge taşıma örnekleri deposu
- Topluluğun katkıda bulunduğu taşıma örnekleri deposu
Diğer Cloud bilgileri
- Google Cloud Platform'da Python
- Google Cloud Python istemci kitaplıkları
- Google Cloud "Daima Ücretsiz" katman
- Google Cloud SDK'sı (
gcloud
komut satırı aracı) - Tüm Google Cloud belgeleri
Python
- Django ve Jinja2 şablon oluşturma sistemleri
webapp2
web çerçevesiwebapp2
belgeleriwebapp2_extras
bağlantıwebapp2_extras
Jinja2 dokümanları- Flask web çerçevesi
Videolar
- Sunucusuz Taşıma İstasyonu
- Sunucusuz Keşif Seferleri
- Google Cloud Teknolojisi'ne 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.