1. بررسی اجمالی
مجموعه کدهای ایستگاه انتقال بدون سرور (آموزشهای عملی) و ویدیوهای مرتبط با هدف کمک به توسعهدهندگان بدون سرور Google Cloud برای مدرن کردن برنامههای خود با هدایت آنها از طریق یک یا چند انتقال، عمدتاً از سرویسهای قدیمی دور میشوند. انجام این کار برنامه های شما را قابل حمل تر می کند و گزینه ها و انعطاف پذیری بیشتری در اختیار شما قرار می دهد و به شما امکان می دهد با طیف وسیع تری از محصولات Cloud ادغام شده و به آنها دسترسی داشته باشید و راحت تر به نسخه های زبان جدیدتر ارتقا دهید. در حالی که در ابتدا بر روی اولین کاربران Cloud، عمدتاً توسعه دهندگان App Engine (محیط استاندارد) تمرکز می شود، این مجموعه به اندازه کافی گسترده است که شامل سایر پلتفرم های بدون سرور مانند Cloud Functions و Cloud Run یا در صورت وجود جاهای دیگر است.
این کد ماژول 15 نحوه افزودن استفاده از App Engine blobstore
را به برنامه نمونه از ماژول 0 توضیح میدهد. سپس در ماژول 16 آماده انتقال این استفاده به Cloud Storage خواهید بود.
شما یاد خواهید گرفت که چگونه
- استفاده از App Engine Blobstore API/کتابخانه را اضافه کنید
- آپلودهای کاربران را در سرویس
blobstore
ذخیره کنید - برای مرحله بعدی مهاجرت به فضای ذخیره سازی ابری آماده شوید
آنچه شما نیاز دارید
- یک پروژه Google Cloud Platform با یک حساب صورتحساب GCP فعال
- مهارت های پایه پایتون
- دانش کاری دستورات رایج لینوکس
- دانش اولیه توسعه و استقرار برنامه های App Engine
- یک برنامه کاربردی Module 0 App Engine (دریافت از مخزن)
نظرسنجی
چگونه از این آموزش استفاده خواهید کرد؟
تجربه خود را با پایتون چگونه ارزیابی می کنید؟
تجربه خود را در استفاده از خدمات Google Cloud چگونه ارزیابی می کنید؟
2. پس زمینه
به منظور مهاجرت از App Engine Blobstore API، استفاده از آن را از ماژول 0 به برنامه اصلی App Engine ndb
موجود اضافه کنید. برنامه نمونه ده بازدید اخیر کاربر را نشان می دهد. ما در حال تغییر برنامه هستیم تا از کاربر نهایی بخواهد مصنوع (فایلی) را که با "بازدید" آنها مطابقت دارد، آپلود کند. اگر کاربر مایل به انجام این کار نیست، گزینه "پرش" وجود دارد. صرف نظر از تصمیم کاربر، صفحه بعدی همان خروجی برنامه را از ماژول 0 (و بسیاری از ماژول های دیگر در این سری) ارائه می دهد. با اجرای این ادغام blobstore
App Engine، میتوانیم آن را به Cloud Storage در آزمایشگاه کد بعدی (ماژول 16) منتقل کنیم.
App Engine دسترسی به سیستمهای قالببندی جنگو و Jinja2 را فراهم میکند، و چیزی که این مثال را متفاوت میکند (علاوه بر اضافه کردن دسترسی Blobstore) این است که از استفاده از جنگو در ماژول 0 به Jinja2 در اینجا در ماژول 15 تغییر میکند. یک گام کلیدی در مدرن کردن App Engine برنامه ها برای انتقال چارچوب های وب از webapp2
به Flask است. دومی از Jinja2 به عنوان سیستم قالب پیشفرض خود استفاده میکند، بنابراین با پیادهسازی Jinja2 در حالی که در webapp2
برای دسترسی Blobstore میمانیم، حرکت در آن جهت را آغاز میکنیم. از آنجایی که Flask به طور پیشفرض از Jinja2 استفاده میکند، این بدان معناست که هیچ تغییری در قالب در ماژول 16 مورد نیاز نخواهد بود.
3. راه اندازی/پیش کار
قبل از اینکه به بخش اصلی آموزش برسیم، پروژه خود را راه اندازی کنید، کد را دریافت کنید و برنامه پایه را برای شروع با کد کار اجرا کنید.
1. پروژه راه اندازی
اگر قبلاً برنامه Module 0 را مستقر کرده اید، توصیه می کنیم از همان پروژه (و کد) دوباره استفاده کنید. از طرف دیگر، می توانید یک پروژه کاملاً جدید ایجاد کنید یا از پروژه موجود دیگری استفاده مجدد کنید. مطمئن شوید که پروژه دارای حساب صورتحساب فعال است و App Engine فعال است.
2. برنامه نمونه پایه را دریافت کنید
یکی از پیش نیازهای این نرم افزار کد، داشتن یک برنامه نمونه کار با ماژول 0 است. اگر آن را ندارید، می توانید آن را از پوشه "START" ماژول 0 (لینک زیر) دریافت کنید. این لبه کد شما را در هر مرحله راهنمایی می کند و با کدی که شبیه آنچه در پوشه "FINISH" ماژول 15 است به پایان می رسد.
- START: پوشه ماژول 0 (Python 2)
- FINISH: پوشه ماژول 15 (Python 2)
- مخزن کامل (برای شبیه سازی یا دانلود فایل ZIP )
دایرکتوری فایل های شروع ماژول 0 باید به شکل زیر باشد:
$ ls README.md index.html app.yaml main.py
3. (دوباره) استقرار برنامه پایه
مراحل پیشکار باقیمانده برای اجرا اکنون:
- دوباره با ابزار خط فرمان
gcloud
آشنا شوید - برنامه نمونه را با
gcloud app deploy
مجدداً مستقر کنید - تأیید کنید که برنامه بدون مشکل در App Engine اجرا می شود
هنگامی که آن مراحل را با موفقیت انجام دادید و مشاهده کردید که برنامه وب شما کار می کند (با خروجی مشابه زیر)، آماده هستید تا استفاده از کش را به برنامه خود اضافه کنید.
4. فایل های پیکربندی را به روز کنید
app.yaml
هیچ تغییر اساسی در پیکربندی برنامه وجود ندارد، با این حال همانطور که قبلا ذکر شد، ما از قالب جنگو (پیشفرض) به Jinja2 حرکت میکنیم، بنابراین برای تغییر، کاربران باید آخرین نسخه Jinja2 موجود در سرورهای App Engine را مشخص کنند، و شما این کار را انجام میدهید. با افزودن آن به بخش داخلی کتابخانه های شخص ثالث app.yaml
.
قبل از:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
فایل app.yaml
خود را با افزودن یک بخش libraries
جدید مانند آنچه در اینجا می بینید ویرایش کنید:
بعد از:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
هیچ فایل پیکربندی دیگری نیاز به به روز رسانی ندارد، بنابراین بیایید به سراغ فایل های برنامه برویم.
5. فایل های برنامه را تغییر دهید
واردات و پشتیبانی Jinja2
اولین مجموعه تغییرات برای main.py
شامل اضافه کردن استفاده از Blobstore API و جایگزینی قالب جنگو با Jinja2 است. این چیزی است که در حال تغییر است:
- هدف ماژول
os
ایجاد یک نام مسیر فایل برای قالب جنگو است. از آنجایی که در آنجا به Jinja2 تغییر میدهیم، استفاده ازos
و همچنین ارائهدهنده الگوی جنگو،google.appengine.ext.webapp.template
، دیگر مورد نیاز نیست، بنابراین حذف میشوند. - API Blobstore را وارد کنید:
google.appengine.ext.blobstore
- کنترلکنندههای Blobstore موجود در چارچوب اصلی
webapp
را وارد کنید—آنها درwebapp2
در دسترس نیستند:google.appengine.ext.webapp.blobstore_handlers
- پشتیبانی Jinja2 را از بسته
webapp2_extras
وارد کنید
قبل از:
import os
import webapp2
from google.appengine.ext import ndb
from google.appengine.ext.webapp import template
با جایگزین کردن بخش واردات فعلی در main.py
با قطعه کد زیر، تغییرات را در لیست بالا اعمال کنید.
بعد از:
import webapp2
from webapp2_extras import jinja2
from google.appengine.ext import blobstore, ndb
from google.appengine.ext.webapp import blobstore_handlers
پس از وارد کردن، مقداری کد دیگ بخار برای پشتیبانی از استفاده از Jinja2 همانطور که در webapp2_extras
docs تعریف شده است، اضافه کنید. قطعه کد زیر کلاس کنترل کننده درخواست استاندارد webapp2 را با عملکرد Jinja2 میپوشاند، بنابراین این بلوک کد را درست بعد از وارد کردن به main.py
اضافه کنید:
class BaseHandler(webapp2.RequestHandler):
'Derived request handler mixing-in Jinja2 support'
@webapp2.cached_property
def jinja2(self):
return jinja2.get_jinja2(app=self.app)
def render_response(self, _template, **context):
self.response.write(self.jinja2.render_template(_template, **context))
پشتیبانی Blobstore را اضافه کنید
برخلاف سایر انتقالها در این سری که عملکرد یا خروجی برنامه نمونه را بدون تغییر (بسیار) در UX یکسان (یا تقریباً یکسان) نگه میداریم، این مثال یک انحراف اساسیتر از هنجار دارد. به جای ثبت فوری یک بازدید جدید و سپس نمایش ده مورد اخیر، ما در حال به روز رسانی برنامه هستیم تا از کاربر یک مصنوع فایل بخواهیم تا بازدید خود را با آن ثبت کند. سپس کاربران نهایی می توانند فایل مربوطه را آپلود کنند یا "Skip" را انتخاب کنند تا اصلاً چیزی آپلود نشود. پس از اتمام این مرحله، صفحه "آخرین بازدیدها" نمایش داده می شود.
این تغییر به برنامه ما اجازه می دهد تا از سرویس Blobstore برای ذخیره (و احتمالاً بعداً رندر) آن تصویر یا نوع فایل دیگر در آخرین صفحه بازدید استفاده کند.
به روز رسانی مدل داده و پیاده سازی استفاده از آن
ما دادههای بیشتری را ذخیره میکنیم، بهویژه مدل دادهها را برای ذخیره شناسه (به نام " BlobKey
") فایل آپلود شده در Blobstore بهروزرسانی میکنیم و یک مرجع برای ذخیره آن در store_visit()
اضافه میکنیم. از آنجایی که این داده های اضافی همراه با هر چیز دیگری پس از پرس و جو برگردانده می شود، fetch_visits()
یکسان می ماند.
در اینجا قبل و بعد از این به روز رسانی ها با file_blob
، یک ndb.BlobKeyProperty
آمده است:
قبل از:
class Visit(ndb.Model):
'Visit entity registers visitor IP address & timestamp'
visitor = ndb.StringProperty()
timestamp = ndb.DateTimeProperty(auto_now_add=True)
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
return Visit.query().order(-Visit.timestamp).fetch(limit)
بعد از:
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)
در اینجا یک نمایش تصویری از تغییراتی است که تاکنون ایجاد شده است:
پشتیبانی از آپلود فایل
مهمترین تغییر در عملکرد، پشتیبانی از آپلود فایلها است، چه درخواست از کاربر برای یک فایل، پشتیبانی از ویژگی «پرش» یا ارائه یک فایل مربوط به یک بازدید. همه اینها بخشی از تصویر است. اینها تغییرات مورد نیاز برای پشتیبانی از آپلود فایل هستند:
- درخواست
GET
کنترل کننده اصلی دیگر آخرین بازدیدها را برای نمایش واکشی نمی کند. در عوض، کاربر را برای آپلود درخواست می کند. - هنگامی که کاربر نهایی فایلی را برای آپلود ارسال میکند یا از آن فرآیند رد میشود، یک
POST
از فرم، کنترل را بهUploadHandler
جدید که ازgoogle.appengine.ext.webapp.blobstore_handlers.BlobstoreUploadHandler
مشتق شده است، منتقل میکند. - روش
POST
UploadHandler
آپلود را انجام می دهد، برای ثبت بازدیدstore_visit()
را فراخوانی می کند و یک تغییر مسیر HTTP 307 را برای ارسال کاربر به "/"، که در آن... - متد
POST
کنترل کننده اصلی برای (از طریقfetch_visits()
) پرس و جو می کند و آخرین بازدیدها را نمایش می دهد. اگر کاربر «پرش» را انتخاب کند، هیچ فایلی آپلود نمیشود، اما بازدید همچنان ثبت میشود و به دنبال آن همان تغییر مسیر انجام میشود. - نمایش آخرین بازدیدها شامل یک فیلد جدید است که به کاربر نمایش داده میشود، یا در صورت وجود فایل آپلود، "نمایش" پیوند داده شده یا "هیچ" در غیر این صورت. این تغییرات در قالب HTML همراه با افزودن یک فرم آپلود (اطلاعات بیشتر در مورد این به زودی) تحقق می یابد.
- اگر کاربر نهایی برای هر بازدیدی با یک ویدیوی آپلود شده، روی پیوند "مشاهده" کلیک کند، یک درخواست
GET
بهViewBlobHandler
جدید، برگرفته ازgoogle.appengine.ext.webapp.blobstore_handlers.BlobstoreDownloadHandler
، درخواست می کند، یا اگر یک تصویر باشد، فایل را رندر می کند. (در مرورگر در صورت پشتیبانی)، درخواست دانلود در غیر این صورت، یا بازگشت خطای HTTP 404 اگر یافت نشد. - علاوه بر جفت کلاس های کنترل کننده جدید و همچنین یک جفت مسیر جدید برای ارسال ترافیک به آنها، کنترل کننده اصلی به یک روش
POST
جدید برای دریافت تغییر مسیر 307 که در بالا توضیح داده شد نیاز دارد.
قبل از این بهروزرسانیها، برنامه Module 0 فقط دارای یک کنترلر اصلی با روش GET
و یک مسیر واحد بود:
قبل از:
class MainHandler(webapp2.RequestHandler):
'main application (GET) handler'
def get(self):
store_visit(self.request.remote_addr, self.request.user_agent)
visits = fetch_visits(10)
tmpl = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(tmpl, {'visits': visits}))
app = webapp2.WSGIApplication([
('/', MainHandler),
], debug=True)
با اجرای آن بهروزرسانیها، اکنون سه کنترلکننده وجود دارد: 1) کنترل کننده آپلود با روش POST
، 2) کنترل کننده دانلود "view blob" با روش GET
، و 3) کنترل کننده اصلی با روشهای GET
و POST
. این تغییرات را به گونهای انجام دهید که بقیه برنامه شما اکنون مانند شکل زیر باشد.
بعد از:
class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
'Upload blob (POST) handler'
def post(self):
uploads = self.get_uploads()
blob_id = uploads[0].key() if uploads else None
store_visit(self.request.remote_addr, self.request.user_agent, blob_id)
self.redirect('/', code=307)
class ViewBlobHandler(blobstore_handlers.BlobstoreDownloadHandler):
'view uploaded blob (GET) handler'
def get(self, blob_key):
self.send_blob(blob_key) if blobstore.get(blob_key) else self.error(404)
class MainHandler(BaseHandler):
'main application (GET/POST) handler'
def get(self):
self.render_response('index.html',
upload_url=blobstore.create_upload_url('/upload'))
def post(self):
visits = fetch_visits(10)
self.render_response('index.html', visits=visits)
app = webapp2.WSGIApplication([
('/', MainHandler),
('/upload', UploadHandler),
('/view/([^/]+)?', ViewBlobHandler),
], debug=True)
چندین تماس کلیدی در این کد وجود دارد که ما به تازگی اضافه کردیم:
- در
MainHandler.get
، یک تماس باblobstore.create_upload_url
وجود دارد. این فراخوانی URL فرمPOST
را ایجاد میکند و با کنترل کننده آپلود برای ارسال فایل به Blobstore تماس میگیرد. - در
UploadHandler.post
، یک تماس باblobstore_handlers.BlobstoreUploadHandler.get_uploads
وجود دارد. این جادوی واقعی است که فایل را در Blobstore قرار می دهد و یک شناسه منحصر به فرد و ثابت برای آن فایل،BlobKey
آن را برمی گرداند. - در
ViewBlobHandler.get
، فراخوانیblobstore_handlers.BlobstoreDownloadHandler.send
باBlobKey
یک فایل منجر به واکشی فایل و ارسال آن به مرورگر کاربر نهایی می شود.
این تماس ها بخش عمده ای از دسترسی به ویژگی های اضافه شده به برنامه را نشان می دهد. در اینجا یک نمایش تصویری از دومین و آخرین مجموعه تغییرات به main.py
است:
قالب HTML را به روز کنید
برخی از بهروزرسانیهای برنامه اصلی بر رابط کاربری (UI) برنامه تأثیر میگذارند، بنابراین تغییرات مربوطه در قالب وب مورد نیاز است، در واقع دو مورد:
- یک فرم آپلود فایل با 3 عنصر ورودی لازم است: یک فایل و یک جفت دکمه ارسال برای آپلود فایل و پرش.
- آخرین خروجی بازدیدها را با افزودن یک پیوند "نما" برای بازدیدهایی با آپلود فایل مربوطه یا "هیچ" بهروزرسانی کنید.
قبل از:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>
<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>
</body>
</html>
تغییرات را در لیست بالا برای تشکیل الگوی به روز شده اعمال کنید:
بعد از:
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>
<h1>VisitMe example</h1>
{% if upload_url %}
<h3>Welcome... upload a file? (optional)</h3>
<form action="{{ upload_url }}" method="POST" enctype="multipart/form-data">
<input type="file" name="file"><p></p>
<input type="submit"> <input type="submit" value="Skip">
</form>
{% else %}
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }}
<i><code>
{% if visit.file_blob %}
(<a href="/view/{{ visit.file_blob }}" target="_blank">view</a>)
{% else %}
(none)
{% endif %}
</code></i>
from {{ visit.visitor }}
</li>
{% endfor %}
</ul>
{% endif %}
</body>
</html>
این تصویر به روز رسانی های مورد نیاز برای index.html
را نشان می دهد:
یکی از آخرین تغییرات این است که Jinja2 الگوهای خود را در یک پوشه templates
ترجیح می دهد، بنابراین آن پوشه را ایجاد کنید و index.html
را داخل آن منتقل کنید. با این حرکت نهایی، اکنون تمام تغییرات لازم برای افزودن استفاده از Blobstore به برنامه نمونه ماژول 0 را انجام داده اید.
(اختیاری) "بهبود" فضای ذخیره سازی ابری
ذخیره سازی Blobstore در نهایت به خود Cloud Storage تبدیل شد. این بدان معنی است که آپلودهای Blobstore در کنسول Cloud، به ویژه مرورگر Cloud Storage قابل مشاهده هستند. سوال اینجاست که کجاست. پاسخ، سطل پیشفرض Cloud Storage برنامه App Engine شما است. نام آن نام دامنه کامل برنامه App Engine شما، PROJECT_ID
.appspot.com
است. این بسیار راحت است زیرا همه شناسه های پروژه منحصر به فرد هستند، درست است؟
به روز رسانی های انجام شده در برنامه نمونه، فایل های آپلود شده را در آن سطل رها می کند، اما توسعه دهندگان این گزینه را دارند که مکان خاصی را انتخاب کنند. سطل پیشفرض از طریق برنامهنویسی از طریق google.appengine.api.app_identity.get_default_gcs_bucket_name()
قابل دسترسی است، اگر میخواهید به این مقدار دسترسی داشته باشید، نیاز به وارد کردن جدید دارد، مثلاً به عنوان پیشوندی برای سازماندهی فایلهای آپلود شده استفاده کنید. به عنوان مثال، مرتب سازی بر اساس نوع فایل:
به عنوان مثال، برای پیاده سازی چیزی شبیه به آن برای تصاویر، کدی مانند این به همراه کدهایی خواهید داشت که انواع فایل را برای انتخاب نام سطل مورد نظر بررسی می کند:
ROOT_BUCKET = app_identity.get_default_gcs_bucket_name()
IMAGE_BUCKET = '%s/%s' % (ROOT_BUCKET, 'images')
همچنین تصاویر آپلود شده را با استفاده از ابزاری مانند ماژول کتابخانه استاندارد پایتون imghdr
برای تأیید نوع تصویر تأیید میکنید. در نهایت، احتمالاً می خواهید در صورت وجود بازیگران بد ، حجم آپلودها را محدود کنید .
بیایید بگوییم تمام کارهایی که انجام شده است. چگونه می توانیم برنامه خود را به روز کنیم تا از تعیین محل ذخیره فایل های آپلود شده پشتیبانی کند؟ نکته کلیدی این است که تماس را با blobstore.create_upload_url
در MainHandler.get
تغییر دهید تا با افزودن پارامتر gs_bucket_name
به این صورت، مکان مورد نظر را در Cloud Storage برای آپلود مشخص کنید:
blobstore.create_upload_url('/upload', gs_bucket_name=IMAGE_BUCKET))
از آنجایی که اگر میخواهید مشخص کنید بارگذاریها کجا باید بروند، این یک بهروزرسانی اختیاری است، بخشی از فایل main.py
در مخزن نیست. در عوض، یک جایگزین به نام main-gcs.py
برای بررسی شما در مخزن موجود است. به جای استفاده از یک سطل جداگانه "پوشه"، کد موجود در main-gcs.py
آپلودها را در سطل "root" ( PROJECT_ID
.appspot.com
) ذخیره می کند، درست مانند main.py
، اما داربست مورد نیاز شما را در صورت استخراج فراهم می کند. نمونه را به چیزی بیشتر که در این بخش اشاره شده است. در زیر تصویری از "تفاوت" بین main.py
و main-gcs.py
آمده است.
6. خلاصه/پاکسازی
این بخش با استقرار برنامه، این کد را جمعبندی میکند و تأیید میکند که آنطور که در نظر گرفته شده و در هر خروجی منعکسشده کار میکند. پس از تأیید اعتبار برنامه، مراحل پاکسازی را انجام دهید و مراحل بعدی را در نظر بگیرید.
استقرار و تأیید برنامه
برنامه خود را با gcloud app deploy
مجدداً استقرار دهید و تأیید کنید که برنامه طبق آگهی کار می کند و در تجربه کاربری (UX) با برنامه Module 0 متفاوت است. در حال حاضر دو صفحه مختلف در برنامه شما وجود دارد، اولین مورد درخواست فرم آپلود فایل بازدید است:
از آنجا، کاربران نهایی یا یک فایل را آپلود می کنند و روی "ارسال" کلیک می کنند یا روی "پرش" کلیک می کنند تا چیزی آپلود نشود. در هر صورت، نتیجه آخرین صفحه بازدید است که اکنون با پیوندهای "مشاهده" یا "هیچ" بین مهرهای زمانی بازدید و اطلاعات بازدیدکننده افزوده شده است:
برای تکمیل این کد لبه با افزودن استفاده از App Engine Blobstore به برنامه نمونه ماژول 0 تبریک میگوییم. اکنون کد شما باید با آنچه در پوشه FINISH (ماژول 15) است مطابقت داشته باشد. جایگزین main-gcs.py
نیز در آن پوشه وجود دارد.
پاک کن
ژنرال
اگر فعلاً کارتان تمام شده است، توصیه میکنیم برنامه 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 تحت سهمیهها و محدودیتهای ذخیرهشده داده قرار میگیرد، بنابراین آن را و همچنین صفحه قیمتگذاری سرویسهای همراه قدیمی را بررسی کنید.
- سرویس App Engine Datastore توسط Cloud Datastore (Cloud Firestore در حالت Datastore) ارائه می شود که دارای یک ردیف رایگان نیز می باشد. برای اطلاعات بیشتر به صفحه قیمت آن مراجعه کنید.
مراحل بعدی
انتقال منطقی بعدی که باید در نظر بگیرید در ماژول 16 پوشش داده شده است و به توسعه دهندگان نشان می دهد که چگونه از سرویس App Engine Blobstore به استفاده از کتابخانه سرویس گیرنده Cloud Storage مهاجرت کنند. از مزایای ارتقا می توان به دسترسی به ویژگی های بیشتر Cloud Storage، آشنایی با کتابخانه سرویس گیرنده ای که برای برنامه های خارج از App Engine کار می کند، چه در Google Cloud، دیگر ابرها، و یا حتی در محل، اشاره کرد. اگر احساس نمیکنید به همه ویژگیهای موجود در Cloud Storage نیاز دارید یا نگران تأثیر آن بر هزینه هستید، میتوانید در App Engine Blobstore بمانید.
فراتر از ماژول 16 تعداد زیادی انتقال احتمالی دیگر مانند Cloud NDB و Cloud Datastore، Cloud Tasks یا Cloud Memorystore وجود دارد. همچنین انتقال محصول متقابل به Cloud Run و Cloud Function وجود دارد. مخزن مهاجرت همه نمونههای کد را نشان میدهد، شما را به همه کدها و ویدیوهای موجود پیوند میدهد، و همچنین راهنماییهایی را در مورد مهاجرتها و هر «ترتیب» مربوط به مهاجرت ارائه میدهد.
7. منابع اضافی
مسائل/بازخوردهای Codelab
اگر مشکلی در این کد لبه پیدا کردید، لطفاً قبل از تشکیل پرونده ابتدا مشکل خود را جستجو کنید. پیوندهایی برای جستجو و ایجاد مسائل جدید:
منابع مهاجرت
پیوندهای پوشههای مخزن برای ماژول 0 (START) و ماژول 15 (FINISH) را میتوانید در جدول زیر پیدا کنید. همچنین میتوانید از مخزن برای همه انتقالهای نرمافزار App Engine که میتوانید یک فایل ZIP را شبیهسازی یا دانلود کنید، دسترسی پیدا کنید.
Codelab | پایتون 2 | پایتون 3 |
ماژول 0 | N/A | |
ماژول 15 (این آزمایشگاه کد) | N/A |
منابع آنلاین
در زیر منابع آنلاینی وجود دارد که ممکن است برای این آموزش مرتبط باشد:
موتور برنامه
- سرویس App Engine Blobstore
- سهمیه ها و محدودیت های داده های ذخیره شده در موتور برنامه
- مستندات App Engine
- زمان اجرا Python 2 App Engine (محیط استاندارد).
- استفاده از کتابخانه های داخلی App Engine در Python 2 App Engine
- اطلاعات قیمت و سهمیه موتور App
- راه اندازی پلتفرم App Engine نسل دوم (2018)
- مقایسه پلت فرم های نسل اول و دوم
- پشتیبانی طولانی مدت از زمان های اجرا قدیمی
- مخزن نمونه مهاجرت اسناد
- مخزن نمونه مهاجرت با مشارکت جامعه
Google 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 مجوز دارد.