1. بررسی اجمالی
مجموعه کدهای ایستگاه انتقال بدون سرور (آموزشهای عملی) و ویدیوهای مرتبط با هدف کمک به توسعهدهندگان بدون سرور Google Cloud برای مدرن کردن برنامههای خود با هدایت آنها از طریق یک یا چند انتقال، عمدتاً از سرویسهای قدیمی دور میشوند. انجام این کار برنامه های شما را قابل حمل تر می کند و گزینه ها و انعطاف پذیری بیشتری در اختیار شما قرار می دهد و به شما امکان می دهد با طیف وسیع تری از محصولات Cloud ادغام شده و به آنها دسترسی داشته باشید و راحت تر به نسخه های زبان جدیدتر ارتقا دهید. در حالی که در ابتدا بر روی اولین کاربران Cloud، عمدتاً توسعه دهندگان App Engine (محیط استاندارد) تمرکز می شود، این مجموعه به اندازه کافی گسترده است که شامل سایر پلتفرم های بدون سرور مانند Cloud Functions و Cloud Run یا در صورت وجود جاهای دیگر است.
این کد لبه به شما می آموزد که چگونه از App Engine Blobstore به فضای ذخیره سازی ابری مهاجرت کنید. همچنین مهاجرت های ضمنی از:
-
webapp2
web frame to Flask (پوشش داده شده توسط ماژول 1 ) - App Engine NDB به Cloud NDB برای دسترسی به Datastore (پوشش داده شده توسط ماژول 2 )
- پایتون 2 به 3 (برنامه انتقال داده شده با پایتون 2 و 3 سازگار است)
برای اطلاعات گام به گام بیشتر به هر ماژول مهاجرت مرتبط مراجعه کنید.
شما یاد خواهید گرفت که چگونه
- استفاده از App Engine Blobstore API/کتابخانه را اضافه کنید
- آپلودهای کاربران را در سرویس Blobstore ذخیره کنید
- برای مرحله بعدی مهاجرت به فضای ذخیره سازی ابری آماده شوید
آنچه شما نیاز دارید
- یک پروژه Google Cloud Platform با یک حساب صورتحساب GCP فعال
- مهارت های پایه پایتون
- دانش کاری دستورات رایج لینوکس
- دانش اولیه توسعه و استقرار برنامه های App Engine
- یک برنامه کاربردی Module 15 App Engine: نسخه کد ماژول 15 را تکمیل کنید (توصیه می شود) یا برنامه ماژول 15 را از مخزن کپی کنید
نظرسنجی
چگونه از این آموزش استفاده خواهید کرد؟
تجربه خود را با پایتون چگونه ارزیابی می کنید؟
تجربه خود را در استفاده از خدمات Google Cloud چگونه ارزیابی می کنید؟
2. پس زمینه
این نرم افزار کد با نمونه برنامه ماژول 15 شروع می شود و نحوه مهاجرت از Blobstore (و NDB) به Cloud Storage (و Cloud NDB) را نشان می دهد. فرآیند مهاجرت شامل جایگزینی وابستگیها به سرویسهای همراه قدیمی App Engine است که به شما امکان میدهد در صورت تمایل، برنامههای خود را به پلتفرم دیگر بدون سرور Cloud یا پلتفرم میزبانی دیگر منتقل کنید.
این مهاجرت در مقایسه با سایر مهاجرت های این مجموعه کمی تلاش بیشتری می طلبد. Blobstore به چارچوب اصلی برنامه وب وابستگی دارد و به همین دلیل است که برنامه نمونه از چارچوب webapp2 به جای Flask استفاده می کند. این آموزش شامل مهاجرت به Cloud Storage، Cloud NDB، Flask و Python 3 است.
این برنامه همچنان «بازدید» کاربر نهایی را ثبت میکند و ده مورد اخیر را نمایش میدهد، اما نسخه قبلی (ماژول 15) قابلیت جدیدی را برای استفاده از Blobstore اضافه کرده است: برنامه از کاربران نهایی میخواهد که مصنوع (فایلی) را آپلود کنند. "بازدید" آنها کاربران می توانند این کار را انجام دهند یا "پرش" را برای انصراف انتخاب کنند. صرف نظر از تصمیم کاربر، صفحه بعدی همان خروجی نسخه های قبلی این برنامه را ارائه می دهد و آخرین بازدیدها را نمایش می دهد. یک پیچ اضافی این است که بازدیدهایی با مصنوعات مربوطه دارای یک پیوند "نما" برای نمایش مصنوع یک بازدید هستند. این Codelab با حفظ عملکرد توصیف شده، مهاجرت هایی را که قبلا ذکر شد پیاده سازی می کند.
3. راه اندازی/پیش کار
قبل از اینکه به بخش اصلی آموزش برسیم، بیایید پروژه خود را راهاندازی کنیم، کد را دریافت کنیم، سپس برنامه پایه را اجرا کنیم تا بدانیم با کد کار شروع کردهایم.
1. پروژه راه اندازی
اگر قبلاً برنامه ماژول 15 را مستقر کرده اید، توصیه می کنیم از همان پروژه (و کد) دوباره استفاده کنید. از طرف دیگر، می توانید یک پروژه کاملاً جدید ایجاد کنید یا از پروژه موجود دیگری استفاده مجدد کنید. مطمئن شوید که پروژه دارای حساب صورتحساب فعال است و App Engine فعال است.
2. برنامه نمونه پایه را دریافت کنید
یکی از پیش نیازهای این نرم افزار کد، داشتن یک برنامه نمونه کار با ماژول 15 است. اگر آن را ندارید، می توانید آن را از پوشه "START" ماژول 15 (لینک زیر) دریافت کنید. این لبه کد شما را در هر مرحله راهنمایی می کند و با کدی که شبیه آنچه در پوشه "FINISH" ماژول 16 است به پایان می رسد.
- START: پوشه ماژول 15 (Python 2)
- FINISH: پوشه ماژول 16 (Python 2)
- مخزن کامل (برای شبیه سازی یا دانلود فایل ZIP )
دایرکتوری فایل های شروع ماژول 15 باید به شکل زیر باشد:
$ ls README.md app.yaml main-gcs.py main.py templates
فایل main-gcs.py
نسخه جایگزین main.py
از ماژول 15 است که امکان انتخاب یک سطل فضای ذخیرهسازی ابری متفاوت با پیشفرض URL اختصاصیافته برنامه بر اساس شناسه پروژه را فراهم میکند: PROJECT_ID
.appspot.com
. این فایل هیچ نقشی در این (ماژول 16) نرم افزار کد ندارد مگر اینکه در صورت تمایل می توان تکنیک های مشابهی را برای انتقال به آن فایل اعمال کرد.
3. (دوباره) استقرار برنامه پایه
مراحل پیشکار باقیمانده برای اجرا اکنون:
- دوباره با ابزار خط فرمان
gcloud
آشنا شوید - برنامه نمونه را با
gcloud app deploy
مجدداً مستقر کنید - تأیید کنید که برنامه بدون مشکل در App Engine اجرا می شود
هنگامی که آن مراحل را با موفقیت انجام دادید و تأیید کردید که برنامه ماژول 15 کار می کند. صفحه اولیه با فرمی به کاربران خوشامد میگوید که از یک فایل مصنوع بازدید برای آپلود همراه با یک گزینه، دکمه «پرش» برای انصراف درخواست میکند:
هنگامی که کاربران یک فایل را آپلود می کنند یا از آن پرش می کنند، برنامه صفحه آشنا "آخرین بازدیدها" را نمایش می دهد:
بازدیدهایی که دارای یک مصنوع هستند یک پیوند "مشاهده" در سمت راست مهر زمان بازدید برای نمایش (یا دانلود) مصنوع خواهند داشت. هنگامی که عملکرد برنامه را تأیید کردید، آماده هستید که از سرویس های قدیمی App Engine (webapp2، NDB، Blobstore) به گزینه های جایگزین امروزی (Flask، Cloud NDB، Cloud Storage) مهاجرت کنید.
4. فایل های پیکربندی را به روز کنید
سه فایل پیکربندی برای نسخه به روز شده برنامه ما وارد عمل می شوند. وظایف مورد نیاز عبارتند از:
- کتابخانههای شخص ثالث داخلی مورد نیاز را در
app.yaml
بهروزرسانی کنید و همچنین درب را برای مهاجرت Python 3 باز بگذارید. - یک
requirements.txt
اضافه کنید، که تمام کتابخانههای مورد نیاز را که داخلی نیستند، مشخص میکند -
appengine_config.py
را اضافه کنید تا برنامه از کتابخانه های شخص ثالث داخلی و غیر داخلی پشتیبانی کند
app.yaml
فایل app.yaml
خود را با به روز رسانی بخش libraries
ویرایش کنید. jinja2
بردارید و grpcio
، setuptools
و ssl
را اضافه کنید. آخرین نسخه موجود برای هر سه کتابخانه را انتخاب کنید. دستور runtime
پایتون 3 را نیز اضافه کنید، اما نظر داده شده است. وقتی کارتان تمام شد، باید به این شکل باشد (اگر پایتون 3.9 را انتخاب کرده باشید):
قبل از:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
بعد از:
#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
تغییرات در درجه اول مربوط به کتابخانه های داخلی پایتون 2 است که در سرورهای App Engine موجود است (بنابراین شما مجبور نیستید آنها را خود بسته بندی کنید). ما Jinja2 را حذف کردیم زیرا با Flask همراه است که می خواهیم آن را به reqs.txt اضافه کنیم. هر زمان که از کتابخانه های سرویس گیرنده Google Cloud، مانند کتابخانه های Cloud NDB و Cloud Storage استفاده می شود، به grpcio و setuptools نیاز است. در نهایت، Cloud Storage خود به کتابخانه ssl نیاز دارد. دستورالعمل زمان اجرا در بالا برای زمانی است که شما آماده پورت کردن این برنامه به پایتون 3 هستید. ما این موضوع را در پایان این آموزش پوشش خواهیم داد.
الزامات. txt
یک فایل requirements.txt
اضافه کنید که به چارچوب Flask نیاز دارد و کتابخانه های سرویس گیرنده Cloud NDB و Cloud Storage که هیچ کدام داخلی نیستند. فایل را با این محتوا ایجاد کنید:
flask
google-cloud-ndb
google-cloud-storage
زمان اجرا Python 2 App Engine نیاز به بستهبندی کتابخانههای شخص ثالث غیر داخلی دارد، بنابراین دستور زیر را برای نصب این کتابخانهها در پوشه lib اجرا کنید:
pip install -t lib -r requirements.txt
اگر هم پایتون 2 و هم 3 را روی دستگاه توسعه خود دارید، ممکن است مجبور شوید از دستور pip2 برای اطمینان از دریافت نسخه های Python 2 این کتابخانه ها استفاده کنید. پس از ارتقاء به پایتون 3، دیگر نیازی به بستهبندی خودکار ندارید.
appengine_config.py
یک فایل appengine_config.py
اضافه کنید که از کتابخانه های شخص ثالث داخلی و غیر داخلی پشتیبانی می کند. فایل را با این محتوا ایجاد کنید:
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)
مراحلی که به تازگی تکمیل شده اند باید مشابه یا مشابه مراحل فهرست شده در بخش نصب کتابخانه ها برای برنامه های پایتون 2 در اسناد App Engine باشند، و به طور خاص، محتویات appengine_config.py
باید با آنچه در مرحله 5 وجود دارد مطابقت داشته باشد.
کار روی فایلهای پیکربندی کامل شده است، بنابراین بیایید به سمت برنامه حرکت کنیم.
5. فایل های برنامه را تغییر دهید
واردات
اولین مجموعه تغییرات برای main.py
شامل تعویض همه چیزهایی است که جایگزین می شوند. این چیزی است که در حال تغییر است:
-
webapp2
با Flask جایگزین شده است - به جای استفاده از Jinja2 از
webapp2_extras
، از Jinja2 همراه با Flask استفاده کنید - App Engine Blobstore و NDB با Cloud NDB و Cloud Storage جایگزین شدند
- کنترل کننده های Blobstore در
webapp
با ترکیبی از ماژول کتابخانه استانداردio
، Flask و ابزارهایwerkzeug
جایگزین شده اند. - بهطور پیشفرض، Blobstore در یک سطل فضای ذخیرهسازی ابری با نام URL برنامه شما (
PROJECT_ID.appspot.com
) مینویسد. از آنجایی که ما در حال انتقال به کتابخانه سرویس گیرنده Cloud Storage هستیم،google.auth
برای دریافت شناسه پروژه برای تعیین نام دقیق سطل استفاده می شود. (می توانید نام سطل را تغییر دهید زیرا دیگر کدگذاری نشده است.)
قبل از:
import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers
با جایگزین کردن بخش واردات فعلی در main.py
با قطعه کد زیر، تغییرات را در لیست بالا اعمال کنید.
بعد از:
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
مقداردهی اولیه و پشتیبانی غیر ضروری Jinja2
بلوک بعدی کدی که باید جایگزین شود BaseHandler
است که استفاده از Jinja2 را از webapp2_extras
مشخص می کند. این غیرضروری است زیرا Jinja2 با Flask همراه است و موتور قالب پیش فرض آن است، بنابراین آن را حذف کنید.
در سمت ماژول 16، اشیایی را که در برنامه قدیمیتر نداشتیم، نمونه برداری کنید. این شامل مقداردهی اولیه برنامه Flask و ایجاد کلاینت های API برای Cloud NDB و Cloud Storage است. در نهایت، نام سطل Cloud Storage را همانطور که در بالا در بخش واردات توضیح داده شد، قرار دادیم. در اینجا قبل و بعد از اجرای این به روز رسانی ها آمده است:
قبل از:
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))
بعد از:
app = Flask(__name__)
ds_client = ndb.Client()
gcs_client = storage.Client()
_, PROJECT_ID = google.auth.default()
BUCKET = '%s.appspot.com' % PROJECT_ID
دسترسی به Datastore را به روز کنید
Cloud NDB بیشتر با App Engine NDB سازگار است. یکی از تفاوت هایی که قبلاً پوشش داده شده است، نیاز به مشتری API است. مورد دوم این است که دسترسی به Datastore توسط مدیر زمینه Python کلاینت API کنترل شود. اساساً، این بدان معناست که همه تماسهای دسترسی به Datastore با استفاده از کتابخانه سرویس گیرنده Cloud NDB فقط میتوانند در پایتون with
بلوکها انجام شوند.
این یک تغییر است. مورد دیگر این است که Blobstore و اشیاء آن، به عنوان مثال، BlobKey
s، توسط Cloud Storage پشتیبانی نمی شوند، بنابراین file_blob
به یک ndb.StringProperty
تغییر دهید. در زیر کلاس مدل داده و توابع به روز شده store_visit()
و fetch_visits()
که این تغییرات را منعکس می کنند، آمده است:
قبل از:
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)
بعد از:
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)
در اینجا یک نمایش تصویری از تغییراتی است که تاکنون ایجاد شده است:
به روز رسانی کنترل کننده ها
کنترل کننده آپلود
هندلرها در webapp2
کلاس هستند در حالی که توابع در Flask هستند. به جای روش فعل HTTP، Flask از فعل برای تزئین تابع استفاده می کند. Blobstore و کنترلکنندههای webapp
آن با قابلیتهای Cloud Storage و همچنین Flask و ابزارهای آن جایگزین شدهاند:
قبل از:
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)
بعد از:
@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)
چند نکته در رابطه با این به روز رسانی:
- به جای
blob_id
، مصنوعات فایل اکنون با نام فایل (fname
) در صورت وجود شناسایی می شوند و در غیر این صورتNone
(کاربر از آپلود فایل منصرف شد). - کنترلکنندههای Blobstore فرآیند آپلود را از کاربران خود انتزاع میکنند، اما Cloud Storage این کار را نمیکند، بنابراین میتوانید کد جدید اضافهشده را ببینید که شی blob و مکان فایل (سطل) و همچنین تماسی را که آپلود واقعی را انجام میدهد را تنظیم میکند. (
upload_from_file()
). -
webapp2
از یک جدول مسیریابی در پایین فایل برنامه استفاده می کند در حالی که مسیرهای Flask در هر کنترل کننده تزئین شده یافت می شود. - هر دو کنترل کننده عملکرد خود را با هدایت به خانه (
/
) جمع بندی می کنند و در عین حال درخواستPOST
را با یک کد بازگشتی HTTP 307 حفظ می کنند.
کنترل کننده دانلود
به روز رسانی کنترل کننده دانلود از یک الگوی مشابه با کنترل کننده آپلود پیروی می کند، فقط کد بسیار کمتری برای مشاهده وجود دارد. عملکرد Blobstore و webapp
را با Cloud Storage و Flask جایگزین کنید:
قبل از:
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)
بعد از:
@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)
نکات مربوط به این به روز رسانی:
- مجدداً، Flask توابع کنترلر را با مسیر خود تزئین می کند در حالی که
webapp
این کار را در جدول مسیریابی در پایین انجام می دهد، بنابراین الگوی دستوری مطابق الگوی('/view/([^/]+)?'
) در مقابل Flask's ('/view/<path:fname>'
) را بشناسید.'/view/<path:fname>'
). - مانند کنترل کننده آپلود، برای عملکردی که توسط کنترل کننده های Blobstore انتزاع شده است، کمی کار بیشتری در سمت ذخیره سازی ابری لازم است، یعنی شناسایی فایل (blob) مورد نظر و دانلود صریح متد
send_blob()
باینری در مقابل کنترل کننده Blobstore. تماس بگیرید. - در هر دو مورد، اگر مصنوع پیدا نشد، یک خطای HTTP 404 به کاربر برگردانده میشود.
کنترل کننده اصلی
تغییرات نهایی در برنامه اصلی در کنترل کننده اصلی انجام می شود. متدهای فعل webapp2
HTTP با یک تابع واحد که عملکرد آنها را ترکیب می کند جایگزین می شود. کلاس MainHandler
را با تابع root()
جایگزین کنید و جدول مسیریابی webapp2
را مطابق شکل زیر حذف کنید:
قبل از:
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)
بعد از:
@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()
و post()
، آنها اساساً یک عبارت if-else
در root()
هستند. همچنین، از آنجایی که root()
یک تابع واحد است، تنها یک فراخوانی برای ارائه الگو برای GET
و POST
وجود دارد، در حالی که واقعاً در webapp2
این امکان وجود ندارد.
در اینجا یک نمایش تصویری از دومین و آخرین مجموعه تغییرات به main.py
است:
(اختیاری) "افزایش" سازگاری با عقب
بنابراین راه حل ایجاد شده در بالا کاملاً کار می کند ... اما فقط در صورتی که از ابتدا شروع کنید و فایل های ایجاد شده توسط Blobstore را ندارید. از آنجایی که ما برنامه را بهروزرسانی کردیم تا فایلها را بهجای BlobKey
با نام فایل شناسایی کنیم، برنامه تکمیلشده ماژول 16 آنطور که هست نمیتواند فایلهای Blobstore را مشاهده کند. به عبارت دیگر، ما با انجام این مهاجرت یک تغییر ناسازگار با عقب را ایجاد کردیم. ما اکنون یک نسخه جایگزین از main.py
به نام main-migrate.py
(موجود در مخزن) ارائه می کنیم که تلاش می کند این شکاف را پر کند.
اولین "افزونه" برای پشتیبانی از فایلهای ایجاد شده توسط Blobstore، یک مدل داده است که دارای یک BlobKeyProperty
(علاوه بر StringProperty
برای فایلهای ایجاد شده در فضای ابری) است:
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
برای شناسایی فایلهای ایجاد شده توسط Blobstore استفاده میشود در حالی که file_gcs
برای فایلهای Cloud Storage است. اکنون هنگام ایجاد بازدیدهای جدید، بهصراحت یک مقدار را به جای file_gcs
file_blob
کنید، بنابراین store_visit کمی متفاوت به نظر میرسد:
قبل از:
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 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()
هنگام واکشی آخرین بازدیدها، داده ها را قبل از ارسال به الگو "عادی" کنید:
قبل از:
@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)
بعد از:
@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)
سپس وجود file_blob
یا file_gcs
(یا هیچکدام) را تایید کنید. اگر فایلی در دسترس است، فایل موجود را انتخاب کنید و از آن شناسه استفاده کنید ( BlobKey
برای فایلهای ایجاد شده توسط Blobstore یا نام فایل برای فایلهای ایجاد شده توسط Cloud Storage). وقتی میگوییم «فایلهای ایجاد شده در فضای ذخیرهسازی ابری»، منظور فایلهایی است که با استفاده از کتابخانه سرویس گیرنده فضای ذخیرهسازی ابری ایجاد شدهاند. Blobstore همچنین به Cloud Storage نیز می نویسد، اما در این مورد، آن ها فایل های ایجاد شده توسط Blobstore هستند.
اکنون مهمتر از آن، این تابع etl_visits()
چیست که برای عادی سازی یا ETL (استخراج، تبدیل و بارگذاری) داده ها برای کاربر نهایی استفاده می شود؟ به نظر می رسد این است:
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]
احتمالاً شبیه چیزی است که انتظار داشتید: کد در تمام بازدیدها حلقه می زند، و برای هر بازدید، داده های بازدیدکننده و مهر زمانی را به کلمه کلمه می گیرد، سپس بررسی می کند که آیا file_gcs
یا file_blob
وجود دارد یا خیر، و اگر چنین است، یکی از آنها را انتخاب می کند (یا اگر None
) وجود ندارد).
در اینجا تصویری از تفاوت های main.py
و main-migrate.py
آمده است:
اگر بدون فایلهای ایجاد شده توسط Blobstore از ابتدا شروع میکنید، از main.py
استفاده کنید، اما اگر میخواهید فایلهای پشتیبانی ایجاد شده توسط Blobstore و Cloud Storage را تغییر دهید، main-migrate.py
را بهعنوان نمونهای از نحوه برخورد بررسی کنید. با سناریویی مانند کمک به برنامه ریزی مهاجرت برای برنامه های خود. هنگام انجام مهاجرتهای پیچیده، موارد خاصی احتمالاً به وجود میآیند، بنابراین این مثال برای نشان دادن تمایل بیشتری به مدرنسازی اپلیکیشنهای واقعی با دادههای واقعی است.
6. خلاصه/پاکسازی
این بخش با استقرار برنامه، این کد را جمعبندی میکند و تأیید میکند که آنطور که در نظر گرفته شده و در هر خروجی منعکسشده کار میکند. پس از تأیید اعتبار برنامه، مراحل پاکسازی را انجام دهید و مراحل بعدی را در نظر بگیرید.
استقرار و تأیید برنامه
قبل از استقرار مجدد برنامه خود، مطمئن شوید که pip install -t lib -r requirements.txt
اجرا کنید تا کتابخانه های شخص ثالث خود همراه را در پوشه lib دریافت کنید. اگر می خواهید راه حل سازگار با عقب را اجرا کنید، ابتدا نام main-migrate.py
را به main.py
تغییر دهید. اکنون gcloud app deploy
اجرا کنید و تأیید کنید که برنامه همانند برنامه Module 15 کار می کند. صفحه فرم به شکل زیر است:
آخرین صفحه بازدیدها به این صورت است:
بابت تکمیل این کد لبه جایگزین App Engine Blobstore با Cloud Storage، App Engine NDB با Cloud NDB، و webapp2
با Flask را به شما تبریک میگوییم. اکنون کد شما باید با آنچه در پوشه FINISH (ماژول 16) است مطابقت داشته باشد. جایگزین main-migrate.py
نیز در آن پوشه وجود دارد.
"مهاجرت" پایتون 3
دستورالعمل runtime
پایتون 3 در بالای app.yaml
تمام چیزی است که برای پورت کردن این برنامه به پایتون 3 لازم است. کد منبع خود از قبل با پایتون 3 سازگار است، بنابراین هیچ تغییری در آنجا لازم نیست. برای استقرار این برنامه به عنوان یک برنامه پایتون 3، مراحل زیر را اجرا کنید:
- دستور
runtime
پایتون 3 را در بالایapp.yaml
لغو نظر کنید. - تمام خطوط دیگر را در
app.yaml
حذف کنید. - فایل
appengine_config.py
حذف کنید. (استفاده نشده در زمان اجرا پایتون 3) - در صورت وجود پوشه
lib
حذف کنید. (غیر ضروری در زمان اجرای پایتون 3)
پاک کن
ژنرال
اگر فعلاً کارتان تمام شده است، توصیه میکنیم برنامه App Engine خود را غیرفعال کنید تا از پرداخت صورتحساب جلوگیری کنید. با این حال، اگر میخواهید بیشتر آزمایش یا آزمایش کنید، پلتفرم App Engine یک سهمیه رایگان دارد، و تا زمانی که از آن سطح استفاده تجاوز نکنید، هزینهای از شما دریافت نمیشود. این برای محاسبه است، اما ممکن است هزینههایی برای خدمات App Engine مربوطه نیز وجود داشته باشد، بنابراین صفحه قیمت آن را برای اطلاعات بیشتر بررسی کنید. اگر این انتقال شامل سایر سرویسهای Cloud باشد، آنها جداگانه صورتحساب میشوند. در هر صورت، در صورت وجود، بخش «ویژه این کد آزمایشگاه» را در زیر ببینید.
برای افشای کامل، استقرار در یک پلت فرم محاسباتی بدون سرور Google Cloud مانند App Engine هزینههای ساخت و ذخیرهسازی جزئی را متحمل میشود. Cloud Build سهمیه رایگان خودش را دارد و Cloud Storage هم دارد. ذخیره سازی آن تصویر مقداری از آن سهمیه را مصرف می کند. با این حال، ممکن است در منطقهای زندگی کنید که چنین سطح رایگانی ندارد، بنابراین برای به حداقل رساندن هزینههای احتمالی از میزان استفاده از فضای ذخیرهسازی خود آگاه باشید. پوشههای خاص Cloud Storage که باید بررسی کنید عبارتند از:
-
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
- پیوندهای ذخیره سازی بالا به
PROJECT_ID
و *LOC
* شما بستگی دارد، به عنوان مثال، اگر برنامه شما در ایالات متحده میزبانی می شود، "us
".
از سوی دیگر، اگر نمیخواهید با این برنامه یا دیگر کدهای مهاجرت مرتبط ادامه دهید و میخواهید همه چیز را به طور کامل حذف کنید، پروژه خود را خاموش کنید .
مخصوص این کد لبه
خدمات لیست شده در زیر منحصر به این کدلب است. برای اطلاعات بیشتر به مستندات هر محصول مراجعه کنید:
- سرویس App Engine Blobstore تحت سهمیهها و محدودیتهای ذخیرهشده داده قرار میگیرد، بنابراین آن را و همچنین صفحه قیمتگذاری سرویسهای همراه قدیمی را بررسی کنید.
- Cloud Storage یک لایه رایگان برای مناطق خاص دارد. همچنین برای اطلاعات بیشتر به صفحه قیمت کلی آن مراجعه کنید.
- سرویس App Engine Datastore توسط Cloud Datastore (Cloud Firestore در حالت Datastore) ارائه می شود که دارای یک ردیف رایگان نیز می باشد. برای اطلاعات بیشتر به صفحه قیمت آن مراجعه کنید."
توجه داشته باشید که اگر از ماژول 15 به ماژول 16 مهاجرت کرده اید، همچنان در Blobstore داده خواهید داشت، بنابراین ما اطلاعات قیمت گذاری آن را در بالا اضافه می کنیم.
مراحل بعدی
فراتر از این آموزش، ماژولهای مهاجرت دیگری که بر دور شدن از سرویسهای همراه قدیمی تمرکز دارند عبارتند از:
- ماژول 2 : از App Engine
ndb
به Cloud NDB مهاجرت کنید - ماژولهای 7-9 : انتقال از وظایف فشاری App Engine Task Queue به Cloud Tasks
- ماژولهای 12-13 : انتقال از App Engine Memcache به Cloud Memorystore
- ماژولهای 18-19 : انتقال از App Engine Task Queue (کشش وظایف) به Cloud Pub/Sub
App Engine دیگر تنها پلتفرم بدون سرور در Google Cloud نیست. اگر یک برنامه App Engine کوچک یا برنامهای دارید که عملکرد محدودی دارد و میخواهید آن را به یک میکروسرویس مستقل تبدیل کنید، یا میخواهید یک برنامه یکپارچه را به چندین مؤلفه قابل استفاده مجدد تقسیم کنید، اینها دلایل خوبی برای فکر رفتن به Cloud Functions هستند. اگر کانتینریسازی بخشی از گردش کار توسعه برنامه شما شده است، بهویژه اگر شامل یک خط لوله CI/CD (ادغام پیوسته/تحویل مداوم یا استقرار) باشد، مهاجرت به Cloud Run را در نظر بگیرید. این سناریوها توسط ماژول های زیر پوشش داده می شوند:
- مهاجرت از App Engine به Cloud Functions: به ماژول 11 مراجعه کنید
- مهاجرت از App Engine به Cloud Run: به ماژول 4 مراجعه کنید تا برنامه خود را با Docker محفظه کنید، یا ماژول 5 را بدون کانتینر، دانش Docker یا
Dockerfile
s انجام دهید.
جابجایی به یک پلتفرم بدون سرور دیگر اختیاری است، و توصیه میکنیم قبل از هر گونه تغییر، بهترین گزینهها را برای برنامهها و موارد استفاده خود در نظر بگیرید.
صرف نظر از اینکه کدام ماژول مهاجرت را بعدی در نظر می گیرید، تمام محتوای ایستگاه مهاجرت بدون سرور (مجموعه کدها، ویدیوها، کد منبع [در صورت وجود]) را می توان در مخزن منبع باز آن دسترسی داشت. README
مخزن همچنین راهنمایی هایی را ارائه می دهد که کدام مهاجرت ها باید در نظر گرفته شود و هر "ترتیب" مربوط به ماژول های مهاجرت.
7. منابع اضافی
مسائل/بازخوردهای Codelab
اگر مشکلی در این کد لبه پیدا کردید، لطفاً قبل از تشکیل پرونده ابتدا مشکل خود را جستجو کنید. پیوندهایی برای جستجو و ایجاد مسائل جدید:
منابع مهاجرت
پیوندهای پوشههای مخزن برای ماژول 15 (START) و ماژول 16 (FINISH) را میتوانید در جدول زیر بیابید. همچنین میتوانید از مخزن برای همه انتقالهای نرمافزار App Engine که میتوانید یک فایل ZIP را شبیهسازی یا دانلود کنید، دسترسی پیدا کنید.
Codelab | پایتون 2 | پایتون 3 |
ماژول 15 | N/A | |
ماژول 16 (این آزمایشگاه کد) | (همان پایتون 2) |
منابع آنلاین
در زیر منابع آنلاینی وجود دارد که ممکن است برای این آموزش مرتبط باشد:
موتور برنامه Blobstore و Cloud Storage
- سرویس App Engine Blobstore
- انتقال به کتابخانه سرویس گیرنده Cloud Storage
- صفحه اصلی Cloud Storage
- اسناد ذخیره سازی ابری
پلت فرم App Engine
- مستندات App Engine
- زمان اجرا Python 2 App Engine (محیط استاندارد).
- استفاده از کتابخانه های داخلی App Engine در Python 2 App Engine
- زمان اجرا Python 3 App Engine (محیط استاندارد).
- تفاوت بین زمان اجرا Python 2 و 3 App Engine (محیط استاندارد).
- راهنمای مهاجرت Python 2 به 3 App Engine (محیط استاندارد).
- اطلاعات قیمت و سهمیه موتور App
- راه اندازی پلتفرم App Engine نسل دوم (2018)
- مقایسه پلت فرم های نسل اول و دوم
- پشتیبانی طولانی مدت از زمان اجراهای قدیمی
- مخزن نمونه مهاجرت اسناد
- مخزن نمونه مهاجرت با مشارکت جامعه
سایر اطلاعات Cloud
- پایتون در پلتفرم ابری گوگل
- کتابخانه های سرویس گیرنده Google Cloud Python
- لایه Google Cloud "همیشه رایگان".
- Google Cloud SDK (ابزار خط فرمان
gcloud
) - تمام اسناد Google Cloud
پایتون
- سیستم های قالب بندی جنگو و جینجا2
- چارچوب وب
webapp2
- مستندات
webapp2
- پیوندهای
webapp2_extras
-
webapp2_extras
اسناد Jinja2 - چارچوب وب فلاسک
ویدئوها
- ایستگاه مهاجرت بدون سرور
- اکسپدیشن های بدون سرور
- در Google Cloud Tech مشترک شوید
- در Google Developers مشترک شوید
مجوز
این اثر تحت مجوز Creative Commons Attribution 2.0 Generic مجوز دارد.