1. खास जानकारी
Serverless Migration Station series of codelabs (अपनी रफ़्तार से सीखने वाले, व्यावहारिक ट्यूटोरियल) और मिलते-जुलते वीडियो का मकसद, Google Cloud serverless डेवलपर को उनके ऐप्लिकेशन को आधुनिक बनाने में मदद करना है. इसके लिए, उन्हें एक या उससे ज़्यादा माइग्रेशन के बारे में बताया जाता है. इसमें मुख्य रूप से, लेगसी सेवाओं से दूर जाने के बारे में बताया जाता है. ऐसा करने से, आपके ऐप्लिकेशन ज़्यादा पोर्टेबल हो जाते हैं. साथ ही, आपको ज़्यादा विकल्प और सुविधाएं मिलती हैं. इससे आपको Cloud के ज़्यादा प्रॉडक्ट के साथ इंटिग्रेट करने और उन्हें ऐक्सेस करने में मदद मिलती है. साथ ही, नई भाषा के रिलीज़ पर आसानी से अपग्रेड किया जा सकता है. इस सीरीज़ में, Cloud के शुरुआती उपयोगकर्ताओं पर फ़ोकस किया गया है. इनमें मुख्य रूप से, App Engine (स्टैंडर्ड एनवायरमेंट) के डेवलपर शामिल हैं. हालांकि, इस सीरीज़ में अन्य सर्वरलेस प्लैटफ़ॉर्म भी शामिल हैं. जैसे, Cloud Functions और Cloud Run. इसके अलावा, इसमें अन्य प्लैटफ़ॉर्म भी शामिल किए जा सकते हैं.
इस कोडलैब में, App Engine Blobstore से Cloud Storage पर माइग्रेट करने का तरीका बताया गया है. इनसे भी इंप्लिसिट माइग्रेशन होते हैं:
webapp2वेब फ़्रेमवर्क से Flask पर माइग्रेट करना (इसके बारे में मॉड्यूल 1 में बताया गया है)- Datastore को ऐक्सेस करने के लिए, App Engine NDB से Cloud NDB पर माइग्रेट करना (इसके बारे में मॉड्यूल 2 में बताया गया है)
- Python 2 से 3 (माइग्रेट किया गया ऐप्लिकेशन, Python 2 और 3, दोनों के साथ काम करता है)
सिलसिलेवार तरीके से ज़्यादा जानकारी पाने के लिए, माइग्रेशन से जुड़े किसी भी मॉड्यूल को देखें.
आपको इनके बारे में जानकारी मिलेगी
- App Engine Blobstore API/लाइब्रेरी का इस्तेमाल करना
- Blobstore सेवा में उपयोगकर्ता के अपलोड किए गए डेटा को सेव करना
- Cloud Storage पर माइग्रेट करने के लिए, अगले चरण की तैयारी करना
आपको इन चीज़ों की ज़रूरत होगी
- चालू GCP बिलिंग खाते वाला Google Cloud Platform प्रोजेक्ट
- Python की बुनियादी स्किल
- Linux के सामान्य कमांड की जानकारी
- App Engine ऐप्लिकेशन को डेवलप और डिप्लॉय करने की बुनियादी जानकारी
- मॉड्यूल 15 का App Engine ऐप्लिकेशन: मॉड्यूल 15 का कोडलैब पूरा करें (इसका सुझाव दिया जाता है) या रिपॉज़िटरी से मॉड्यूल 15 का ऐप्लिकेशन कॉपी करें
सर्वे
इस ट्यूटोरियल का इस्तेमाल कैसे किया जाएगा?
Python इस्तेमाल करने का आपका अनुभव कैसा रहा?
Google Cloud की सेवाओं को इस्तेमाल करने के अपने अनुभव को आप क्या रेटिंग देंगे/देंगी?
2. बैकग्राउंड
इस कोडलैब की शुरुआत, मॉड्यूल 15 के सैंपल के तौर पर मिले ऐप्लिकेशन से होती है. इसमें Blobstore (और NDB) से Cloud Storage (और Cloud NDB) पर डेटा दूसरी जगह भेजने का तरीका बताया गया है. माइग्रेशन की प्रोसेस में, App Engine की लेगसी बंडल की गई सेवाओं पर निर्भरता को बदलना शामिल है. इससे आपको अपने ऐप्लिकेशन को किसी दूसरे Cloud सर्वरलेस प्लैटफ़ॉर्म या अन्य होस्टिंग प्लैटफ़ॉर्म पर माइग्रेट करने की सुविधा मिलती है.
इस सीरीज़ में मौजूद अन्य माइग्रेशन की तुलना में, इस माइग्रेशन के लिए आपको ज़्यादा मेहनत करनी होगी. Blobstore, ओरिजनल वेबऐप्लिकेशन फ़्रेमवर्क पर निर्भर करता है. इसलिए, सैंपल के तौर पर मिला ऐप्लिकेशन, Flask के बजाय webapp2 फ़्रेमवर्क का इस्तेमाल करता है. इस ट्यूटोरियल में, Cloud Storage, Cloud NDB, Flask, और Python 3 पर माइग्रेट करने के बारे में बताया गया है.
ऐप्लिकेशन अब भी असली उपयोगकर्ता की "विज़िट" को रजिस्टर करता है और हाल ही की दस विज़िट दिखाता है. हालांकि, पिछले (मॉड्यूल 15) कोडलैब में, Blobstore के इस्तेमाल के लिए नई सुविधा जोड़ी गई है: ऐप्लिकेशन, असली उपयोगकर्ताओं को उनकी "विज़िट" से जुड़ी आर्टफ़ैक्ट (एक फ़ाइल) अपलोड करने के लिए कहता है. उपयोगकर्ता ऐसा कर सकते हैं या बाहर होने के लिए, "छोड़ें" को चुन सकते हैं. उपयोगकर्ता के फ़ैसले के बावजूद, अगला पेज इस ऐप्लिकेशन के पिछले वर्शन की तरह ही आउटपुट रेंडर करता है. इसमें हाल ही की विज़िट दिखती हैं. एक और दिलचस्प बात यह है कि आर्टफ़ैक्ट वाली विज़िट में, आर्टफ़ैक्ट को दिखाने के लिए "देखें" लिंक होता है. यह कोडलैब, पहले बताए गए माइग्रेशन को लागू करता है. साथ ही, बताई गई सुविधाओं को बनाए रखता है.
3. सेटअप/पहले से की जाने वाली तैयारी
ट्यूटोरियल के मुख्य हिस्से पर जाने से पहले, आइए अपना प्रोजेक्ट सेट अप करें, कोड पाएं, और फिर बेसलाइन ऐप्लिकेशन को डिप्लॉय करें. इससे हमें पता चलेगा कि हमने काम करने वाले कोड से शुरुआत की है.
1. प्रोजेक्ट सेटअप करना
अगर आपने मॉड्यूल 15 ऐप्लिकेशन को पहले ही डिप्लॉय कर दिया है, तो हमारा सुझाव है कि आप उसी प्रोजेक्ट (और कोड) का फिर से इस्तेमाल करें. इसके अलावा, एक नया प्रोजेक्ट बनाया जा सकता है या किसी दूसरे मौजूदा प्रोजेक्ट का फिर से इस्तेमाल किया जा सकता है. पक्का करें कि प्रोजेक्ट के लिए, बिलिंग खाता चालू हो और App Engine चालू हो.
2. बेसलाइन सैंपल ऐप्लिकेशन पाना
इस कोडलैब के लिए, आपके पास मॉड्यूल 15 का सैंपल के तौर पर मिला ऐप्लिकेशन होना चाहिए. अगर आपके पास यह ऐप्लिकेशन नहीं है, तो इसे मॉड्यूल 15 के "START" फ़ोल्डर से डाउनलोड किया जा सकता है. इसका लिंक नीचे दिया गया है. इस कोडलैब में, आपको हर चरण के बारे में बताया गया है. आखिर में, आपको मॉड्यूल 16 के "FINISH" फ़ोल्डर में मौजूद कोड जैसा कोड मिलेगा.
- शुरुआत: Module 15 folder (Python 2)
- पूरा करें: Module 16 folder (Python 2)
- पूरा डेटा स्टोर ( ZIP फ़ाइल को क्लोन या डाउनलोड करने के लिए)
मॉड्यूल 15 की शुरुआती फ़ाइलों की डायरेक्ट्री कुछ इस तरह दिखनी चाहिए:
$ ls README.md app.yaml main-gcs.py main.py templates
main-gcs.py फ़ाइल, मॉड्यूल 15 की main.py फ़ाइल का एक वैकल्पिक वर्शन है. इसकी मदद से, Cloud Storage बकेट को चुना जा सकता है. यह बकेट, प्रोजेक्ट के आईडी के आधार पर ऐप्लिकेशन को असाइन किए गए यूआरएल के डिफ़ॉल्ट बकेट से अलग होता है: PROJECT_ID.appspot.com. इस फ़ाइल का इस्तेमाल, इस (मॉड्यूल 16) कोडलैब में नहीं किया जाता. हालांकि, अगर आपको माइग्रेशन की ऐसी ही तकनीकों को इस फ़ाइल पर लागू करना है, तो ऐसा किया जा सकता है.
3. बेसलाइन ऐप्लिकेशन को (फिर से) डिप्लॉय करना
अब आपको ये काम करने होंगे:
gcloudकमांड-लाइन टूल के बारे में फिर से जानेंgcloud app deployकी मदद से, सैंपल के तौर पर मिले ऐप्लिकेशन को फिर से डिप्लॉय करें- पुष्टि करें कि ऐप्लिकेशन, App Engine पर बिना किसी समस्या के काम करता है
इन चरणों को पूरा करने के बाद, पुष्टि करें कि आपका Module 15 ऐप्लिकेशन काम कर रहा है. शुरुआती पेज पर, उपयोगकर्ताओं को एक फ़ॉर्म दिखता है. इसमें, विज़िट आर्टफ़ैक्ट फ़ाइल अपलोड करने के लिए कहा जाता है. साथ ही, "अभी नहीं" बटन का विकल्प भी होता है, ताकि वे इस प्रोसेस से बाहर निकल सकें:

फ़ाइल अपलोड करने या उसे स्किप करने के बाद, ऐप्लिकेशन "हाल ही में विज़िट किए गए पेज" दिखाता है:

जिन विज़िट में आर्टफ़ैक्ट मौजूद होगा उनके टाइमस्टैंप की दाईं ओर, "देखें" लिंक दिखेगा. इस लिंक पर क्लिक करके, आर्टफ़ैक्ट को देखा या डाउनलोड किया जा सकता है. ऐप्लिकेशन के काम करने के तरीके की पुष्टि करने के बाद, App Engine की लेगसी सेवाओं (webapp2, NDB, Blobstore) से आधुनिक विकल्पों (Flask, Cloud NDB, Cloud Storage) पर माइग्रेट किया जा सकता है.
4. कॉन्फ़िगरेशन फ़ाइलें अपडेट करना
हमारे ऐप्लिकेशन के अपडेट किए गए वर्शन के लिए, तीन कॉन्फ़िगरेशन फ़ाइलें इस्तेमाल की जाती हैं. ज़रूरी टास्क ये हैं:
app.yamlमें, तीसरे पक्ष की ज़रूरी लाइब्रेरी अपडेट करें. साथ ही, Python 3 पर माइग्रेट करने का विकल्प भी खुला रखेंrequirements.txtजोड़ें, जो उन सभी ज़रूरी लाइब्रेरी के बारे में बताता है जो पहले से मौजूद नहीं हैंappengine_config.pyजोड़ें, ताकि ऐप्लिकेशन में पहले से मौजूद और पहले से मौजूद नहीं, दोनों तरह की तीसरे पक्ष की लाइब्रेरी काम कर सकें
app.yaml
libraries सेक्शन को अपडेट करके, अपनी app.yaml फ़ाइल में बदलाव करें. jinja2 को हटाएं और grpcio, setuptools, और ssl को जोड़ें. तीनों लाइब्रेरी के लिए उपलब्ध सबसे नया वर्शन चुनें. Python 3 runtime डायरेक्टिव भी जोड़ें, लेकिन टिप्पणी के तौर पर मार्क करें. सेट अप पूरा करने के बाद, यह कुछ ऐसा दिखेगा (अगर आपने Python 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
ये बदलाव मुख्य रूप से, App Engine सर्वर पर उपलब्ध Python 2 की पहले से मौजूद लाइब्रेरी से जुड़े हैं. इसलिए, आपको उन्हें खुद बंडल करने की ज़रूरत नहीं है. हमने Jinja2 को हटा दिया है, क्योंकि यह Flask के साथ आता है. हम Flask को reqs.txt में जोड़ेंगे. जब भी Google Cloud की क्लाइंट लाइब्रेरी का इस्तेमाल किया जाता है, तब grpcio और setuptools की ज़रूरत होती है. जैसे, Cloud NDB और Cloud Storage के लिए. Cloud Storage को एसएसएल लाइब्रेरी की ज़रूरत होती है. सबसे ऊपर मौजूद रनटाइम डायरेक्टिव को टिप्पणी के तौर पर मार्क किया गया है. यह तब के लिए है, जब आपको इस ऐप्लिकेशन को Python 3 पर पोर्ट करना हो. हम इस ट्यूटोरियल के आखिर में इस विषय पर बात करेंगे.
requirements.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
अगर आपकी डेवलपमेंट मशीन पर Python 2 और 3, दोनों मौजूद हैं, तो आपको pip2 कमांड का इस्तेमाल करना पड़ सकता है. इससे यह पक्का किया जा सकेगा कि आपको इन लाइब्रेरी के Python 2 वर्शन मिलें. Python 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)
अभी-अभी पूरे किए गए चरण, App Engine के दस्तावेज़ों के Installing libraries for Python 2 apps सेक्शन में दिए गए चरणों से मिलते-जुलते या उनके जैसे होने चाहिए. खास तौर पर, appengine_config.py का कॉन्टेंट, वहां दिए गए पांचवें चरण से मैच होना चाहिए.
कॉन्फ़िगरेशन फ़ाइलों पर काम पूरा हो गया है. इसलिए, अब ऐप्लिकेशन पर आगे बढ़ते हैं.
5. ऐप्लिकेशन की फ़ाइलों में बदलाव करना
आयात
main.py के लिए किए गए बदलावों के पहले सेट में, उन सभी चीज़ों को हटाना शामिल है जिन्हें बदला जा रहा है. यहां बताया गया है कि क्या-क्या बदलाव किए जा रहे हैं:
webapp2की जगह Flask का इस्तेमाल किया जाता हैwebapp2_extrasके Jinja2 का इस्तेमाल करने के बजाय, Flask के साथ आने वाले Jinja2 का इस्तेमाल करें- App Engine Blobstore और NDB की जगह, Cloud NDB और Cloud Storage का इस्तेमाल किया जाता है
webappमें मौजूद Blobstore हैंडलर कोioस्टैंडर्ड लाइब्रेरी मॉड्यूल, Flask, औरwerkzeugयूटिलिटी के कॉम्बिनेशन से बदल दिया जाता है- डिफ़ॉल्ट रूप से, Blobstore आपके ऐप्लिकेशन के यूआरएल (
PROJECT_ID.appspot.com) के नाम वाली Cloud Storage बकेट में डेटा सेव करता है. हम 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 है. इसे बदलने के लिए, webapp2_extras से Jinja2 का इस्तेमाल करें. इसकी ज़रूरत नहीं है, क्योंकि Jinja2, Flask के साथ आता है और यह इसका डिफ़ॉल्ट टेंप्लेट इंजन है. इसलिए, इसे हटा दें.
मॉड्यूल 16 में, उन ऑब्जेक्ट को इंस्टैंशिएट करें जो पुराने ऐप्लिकेशन में नहीं थे. इसमें Flask ऐप्लिकेशन को शुरू करना और 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
डेटास्टोर का ऐक्सेस अपडेट करना
Cloud NDB, App Engine NDB के साथ काम करता है. एक अंतर यह है कि आपको एपीआई क्लाइंट की ज़रूरत होगी. इसके बारे में पहले ही बताया जा चुका है. दूसरा अंतर यह है कि Datastore के ऐक्सेस को एपीआई क्लाइंट के Python कॉन्टेक्स्ट मैनेजर से कंट्रोल करना ज़रूरी है. इसका मतलब है कि Cloud NDB क्लाइंट लाइब्रेरी का इस्तेमाल करके, Datastore को ऐक्सेस करने वाले सभी कॉल सिर्फ़ Python with ब्लॉक में हो सकते हैं.
यह एक बदलाव है.दूसरा बदलाव यह है कि Blobstore और उसके ऑब्जेक्ट, जैसे कि BlobKey, 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 में ये फ़ंक्शन होते हैं. एचटीटीपी वर्ब मेथड के बजाय, 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 ऐसा नहीं करता. इसलिए, आपको नया कोड दिखता है, जो फ़ाइल के ब्लॉब ऑब्जेक्ट और जगह (बकेट) को सेट करता है. साथ ही, आपको वह कॉल भी दिखता है जो असल में अपलोड करता है. (
upload_from_file()). webapp2, ऐप्लिकेशन फ़ाइल के सबसे नीचे मौजूद रूटिंग टेबल का इस्तेमाल करता है. वहीं, Flask रूट हर डेकोरेटेड हैंडलर में मिलते हैं.- दोनों हैंडलर, होम पेज (
/) पर रीडायरेक्ट करके अपनी प्रोसेस पूरी करते हैं. साथ ही, एचटीटीपी 307 रिटर्न कोड के साथPOSTअनुरोध को सुरक्षित रखते हैं.
डाउनलोड हैंडलर
डाउनलोड हैंडलर को अपडेट करने का तरीका, अपलोड हैंडलर को अपडेट करने के तरीके जैसा ही है. हालांकि, इसमें कोड बहुत कम होता है. 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 के ('/view/<path:fname>') को पहचानें. - अपलोड हैंडलर की तरह ही, Blobstore हैंडलर से हटाई गई सुविधाओं के लिए, Cloud Storage में थोड़ा और काम करना पड़ता है. जैसे, फ़ाइल (ब्लॉब) की पहचान करना और बाइनरी को साफ़ तौर पर डाउनलोड करना. इसके मुकाबले, Blobstore हैंडलर के लिए,
send_blob()को कॉल करने का एक ही तरीका होता है. - दोनों ही मामलों में, अगर आर्टफ़ैक्ट नहीं मिलता है, तो उपयोगकर्ता को एचटीटीपी 404 गड़बड़ी का मैसेज दिखता है.
मुख्य हैंडलर
मुख्य ऐप्लिकेशन में आखिरी बदलाव, मुख्य हैंडलर में किए जाते हैं. webapp2 एचटीटीपी वर्ब मेथड को एक ही फ़ंक्शन से बदल दिया गया है. इसमें दोनों मेथड की सुविधाएं शामिल हैं. 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() के अलग-अलग तरीकों के बजाय, ये root() में if-else स्टेटमेंट होते हैं. इसके अलावा, root() एक ही फ़ंक्शन है. इसलिए, GET और POST, दोनों के लिए टेंप्लेट को रेंडर करने के लिए सिर्फ़ एक कॉल किया जाता है. हालांकि, webapp2 में ऐसा करना मुमकिन नहीं है.
main.py में किए जाने वाले बदलावों के दूसरे और आखिरी सेट को यहां इमेज के ज़रिए दिखाया गया है:

(ज़रूरी नहीं) पुराने सिस्टम के साथ काम करने की सुविधा को "बेहतर बनाना"
ऊपर बताया गया तरीका पूरी तरह से काम करता है... हालांकि, यह सिर्फ़ तब काम करता है, जब आपने शुरुआत से काम शुरू किया हो और आपके पास Blobstore से बनाई गई फ़ाइलें न हों. हमने ऐप्लिकेशन को अपडेट किया है, ताकि वह BlobKey के बजाय फ़ाइल नाम से फ़ाइलों की पहचान कर सके. इसलिए, मॉड्यूल 16 का पूरा ऐप्लिकेशन, Blobstore की फ़ाइलों को नहीं देख पाएगा. दूसरे शब्दों में, हमने इस माइग्रेशन को पूरा करने के लिए, पुराने सिस्टम के साथ काम न करने वाला बदलाव किया है. अब हम main.py का एक वैकल्पिक वर्शन पेश कर रहे हैं, जिसे main-migrate.py कहा जाता है. यह वर्शन, रेपो में मौजूद है. इसका मकसद, इस अंतर को कम करना है.
Blobstore से बनाई गई फ़ाइलों के साथ काम करने वाला पहला "एक्सटेंशन", एक डेटा मॉडल है. इसमें BlobKeyProperty होता है. साथ ही, Cloud Storage से बनाई गई फ़ाइलों के लिए 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_blob के बजाय file_gcs में साफ़ तौर पर कोई वैल्यू सेव करें, ताकि 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 मौजूद है या नहीं. अगर कोई फ़ाइल उपलब्ध है, तो वह फ़ाइल चुनें जो मौजूद है और उस आइडेंटिफ़ायर का इस्तेमाल करें. Blobstore से बनाई गई फ़ाइलों के लिए BlobKey या Cloud Storage से बनाई गई फ़ाइलों के लिए फ़ाइल नाम का इस्तेमाल करें. "Cloud Storage में बनाई गई फ़ाइलें" का मतलब है, Cloud Storage की क्लाइंट लाइब्रेरी का इस्तेमाल करके बनाई गई फ़ाइलें. Blobstore, Cloud Storage में भी डेटा सेव करता है. हालांकि, इस मामले में वे Blobstore से बनाई गई फ़ाइलें होंगी.
अब सबसे ज़रूरी बात, यह etl_visits() फ़ंक्शन क्या है, जिसका इस्तेमाल असली उपयोगकर्ता के लिए डेटा को सामान्य बनाने या ईटीएल (डेटा निकालना, बदलना, और लोड करना) के लिए किया जाता है? यह कुछ ऐसा दिखता है:
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 को चलाएं और पुष्टि करें कि ऐप्लिकेशन, मॉड्यूल 15 के ऐप्लिकेशन की तरह ही काम करता है. फ़ॉर्म की स्क्रीन कुछ इस तरह दिखती है:

हाल ही में विज़िट किए गए पेजों की सूची इस तरह दिखती है:

App Engine Blobstore को Cloud Storage से, App Engine NDB को Cloud NDB से, और webapp2 को Flask से बदलने का यह कोडलैब पूरा करने के लिए बधाई. अब आपका कोड, FINISH (Module 16) फ़ोल्डर में मौजूद कोड से मैच होना चाहिए. main-migrate.py का विकल्प भी उस फ़ोल्डर में मौजूद है.
Python 3 "माइग्रेशन"
इस ऐप्लिकेशन को Python 3 पर पोर्ट करने के लिए, app.yaml के सबसे ऊपर मौजूद, टिप्पणी के तौर पर मार्क किए गए Python 3 runtime डायरेक्टिव की ज़रूरत होती है. सोर्स कोड पहले से ही Python 3 के साथ काम करता है. इसलिए, इसमें कोई बदलाव करने की ज़रूरत नहीं है. इसे Python 3 ऐप्लिकेशन के तौर पर डिप्लॉय करने के लिए, यह तरीका अपनाएं:
app.yamlके सबसे ऊपर मौजूद, Python 3runtimeडायरेक्टिव से टिप्पणी हटाएं.app.yamlमें मौजूद अन्य सभी लाइनें मिटाएं.appengine_config.pyफ़ाइल मिटाएं. (Python 3 रनटाइम में इस्तेमाल नहीं किया गया)- अगर
libफ़ोल्डर मौजूद है, तो उसे मिटाएं. (Python 3 रनटाइम के साथ ज़रूरी नहीं है)
व्यवस्थित करें
सामान्य
अगर आपने अपना काम पूरा कर लिया है, तो हमारा सुझाव है कि आप App Engine ऐप्लिकेशन को बंद कर दें, ताकि आपको बिल न भरना पड़े. हालांकि, अगर आपको कुछ और टेस्ट या एक्सपेरिमेंट करने हैं, तो App Engine प्लैटफ़ॉर्म पर मुफ़्त कोटा उपलब्ध है. जब तक आप इस्तेमाल के उस टियर से ज़्यादा का इस्तेमाल नहीं करते, तब तक आपसे कोई शुल्क नहीं लिया जाएगा. यह शुल्क, कंप्यूट के लिए है. हालांकि, App Engine की सेवाओं के लिए भी शुल्क लिया जा सकता है. इसलिए, ज़्यादा जानकारी के लिए इसके कीमत वाले पेज पर जाएं. अगर इस माइग्रेशन में Cloud की अन्य सेवाएं शामिल हैं, तो उनके लिए अलग से बिल भेजा जाता है. दोनों ही मामलों में, अगर लागू हो, तो नीचे दिया गया "इस कोडलैब के लिए खास" सेक्शन देखें.
पूरी जानकारी के लिए, App Engine जैसे Google Cloud के बिना सर्वर वाले कंप्यूट प्लैटफ़ॉर्म पर डिप्लॉय करने पर, बिल्ड और स्टोरेज के लिए मामूली शुल्क लगता है. Cloud Build और Cloud Storage, दोनों के लिए बिना किसी शुल्क के इस्तेमाल करने का कोटा अलग-अलग होता है. उस इमेज को सेव करने के लिए, आपके कोटे का कुछ हिस्सा इस्तेमाल किया जाता है. हालांकि, ऐसा हो सकता है कि आप किसी ऐसे इलाके में रहते हों जहां यह फ़्री टियर उपलब्ध न हो. इसलिए, स्टोरेज के इस्तेमाल पर नज़र रखें, ताकि आपको ज़्यादा शुल्क न देना पड़े. Cloud Storage के कुछ "फ़ोल्डर" की समीक्षा करना ज़रूरी है. इनमें ये शामिल हैं:
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- ऊपर दिए गए स्टोरेज लिंक, आपके
PROJECT_IDऔर *LOC*पर निर्भर करते हैं. उदाहरण के लिए, अगर आपका ऐप्लिकेशन अमेरिका में होस्ट किया गया है, तो "us" डालें.
वहीं, अगर आपको इस ऐप्लिकेशन या माइग्रेशन से जुड़े अन्य कोडलैब का इस्तेमाल नहीं करना है और सब कुछ पूरी तरह से मिटाना है, तो अपना प्रोजेक्ट बंद करें.
इस कोडलैब के लिए खास तौर पर
यहां दी गई सेवाएं, इस कोडलैब के लिए यूनीक हैं. ज़्यादा जानकारी के लिए, हर प्रॉडक्ट का दस्तावेज़ देखें:
- App Engine Blobstore सेवा, स्टोर किए गए डेटा के कोटा और सीमाओं के तहत आती है. इसलिए, इसे और बंडल की गई लेगसी सेवाओं की कीमत वाले पेज को भी देखें.
- Cloud Storage में कुछ खास इलाकों के लिए, फ़्री टियर उपलब्ध है. ज़्यादा जानकारी के लिए, कीमत की जानकारी वाला पेज देखें.
- App Engine Datastore सेवा, Cloud Datastore (Datastore मोड में Cloud Firestore) उपलब्ध कराता है. इसमें फ़्री टियर भी शामिल है. ज़्यादा जानकारी के लिए, कीमत वाला पेज देखें.
ध्यान दें कि अगर आपने मॉड्यूल 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 पर माइग्रेट करें. इसके अलावा, अगर आपको किसी मोनोलिथिक ऐप्लिकेशन को फिर से इस्तेमाल किए जा सकने वाले कई कॉम्पोनेंट में बांटना है, तो भी Cloud Functions पर माइग्रेट करें. अगर कंटेनराइज़ेशन आपके ऐप्लिकेशन डेवलपमेंट वर्कफ़्लो का हिस्सा बन गया है, खास तौर पर तब, जब इसमें सीआई/सीडी (लगातार इंटिग्रेशन/लगातार डिलीवरी या डिप्लॉयमेंट) पाइपलाइन शामिल हो, तो Cloud Run पर माइग्रेट करें. इन स्थितियों के बारे में इन मॉड्यूल में बताया गया है:
- App Engine से Cloud Functions पर माइग्रेट करें: मॉड्यूल 11 देखें
- App Engine से Cloud Run पर माइग्रेट करें: Docker की मदद से अपने ऐप्लिकेशन को कंटेनर में बदलने के लिए, मॉड्यूल 4 देखें. इसके अलावा, कंटेनर, Docker की जानकारी या
Dockerfileके बिना ऐसा करने के लिए, मॉड्यूल 5 देखें
किसी दूसरे सर्वरलेस प्लैटफ़ॉर्म पर स्विच करना ज़रूरी नहीं है. हमारा सुझाव है कि कोई भी बदलाव करने से पहले, अपने ऐप्लिकेशन और इस्तेमाल के उदाहरणों के लिए सबसे सही विकल्प चुनें.
इससे कोई फ़र्क़ नहीं पड़ता कि आपको कौनसा माइग्रेशन मॉड्यूल चुनना है. Serverless Migration Station का पूरा कॉन्टेंट (कोडलैब, वीडियो, सोर्स कोड [उपलब्ध होने पर]) इसके ओपन सोर्स रिपॉज़िटरी पर ऐक्सेस किया जा सकता है. रिपॉज़िटरी का README यह भी बताता है कि किन माइग्रेशन पर विचार करना चाहिए. साथ ही, माइग्रेशन मॉड्यूल के किसी भी काम के "क्रम" के बारे में भी जानकारी देता है.
7. अन्य संसाधन
कोडलैब से जुड़ी समस्याएं/सुझाव/राय
अगर आपको इस कोडलैब में कोई समस्या मिलती है, तो कृपया शिकायत करने से पहले अपनी समस्या खोजें. समस्याएं खोजने और नई समस्याएं बनाने के लिए लिंक:
माइग्रेशन के लिए उपलब्ध संसाधन
मॉड्यूल 15 (START) और मॉड्यूल 16 (FINISH) के लिए, रेपो फ़ोल्डर के लिंक यहां दी गई टेबल में देखे जा सकते हैं. इन्हें सभी App Engine कोडलैब माइग्रेशन के लिए रेपो से भी ऐक्सेस किया जा सकता है. इसे क्लोन किया जा सकता है या ZIP फ़ाइल के तौर पर डाउनलोड किया जा सकता है.
Codelab | Python 2 | Python 3 |
मॉड्यूल 15 | लागू नहीं | |
मॉड्यूल 16 (यह कोडलैब) | (Python 2 की तरह) |
ऑनलाइन संसाधन
यहां कुछ ऑनलाइन संसाधन दिए गए हैं, जो इस ट्यूटोरियल के लिए काम के हो सकते हैं:
App Engine Blobstore और Cloud Storage
- App Engine Blobstore सेवा
- Cloud Storage क्लाइंट लाइब्रेरी पर माइग्रेट करना
- Cloud Storage का होम पेज
- Cloud Storage से जुड़ा दस्तावेज़
App Engine प्लैटफ़ॉर्म
- App Engine का दस्तावेज़
- Python 2 App Engine (स्टैंडर्ड एनवायरमेंट) रनटाइम
- Python 2 App Engine पर, App Engine की पहले से मौजूद लाइब्रेरी का इस्तेमाल करना
- Python 3 App Engine (स्टैंडर्ड एनवायरमेंट) रनटाइम
- Python 2 और 3 App Engine (स्टैंडर्ड एनवायरमेंट) रनटाइम के बीच अंतर
- Python 2 से 3 App Engine (स्टैंडर्ड एनवायरमेंट) पर माइग्रेट करने से जुड़ी गाइड
- App Engine की कीमत और कोटा की जानकारी
- सेकंड जनरेशन App Engine प्लैटफ़ॉर्म लॉन्च (2018)
- पहली और दूसरी जनरेशन के प्लैटफ़ॉर्म की तुलना करना
- लेगसी रनटाइम के लिए लंबे समय तक सहायता
- Documentation migration samples repo
- कम्यूनिटी के योगदान से तैयार की गई माइग्रेशन सैंपल की रिपॉज़िटरी
क्लाउड से जुड़ी अन्य जानकारी
- Google Cloud Platform पर Python
- Google Cloud Python क्लाइंट लाइब्रेरी
- Google Cloud का "हमेशा मुफ़्त" टियर
- Google Cloud SDK (
gcloudकमांड-लाइन टूल) - Google Cloud से जुड़े सभी दस्तावेज़
Python
- Django और Jinja2 टेंप्लेट सिस्टम
webapp2वेब फ़्रेमवर्कwebapp2दस्तावेज़webapp2_extrasलिंकwebapp2_extrasJinja2 दस्तावेज़- Flask वेब फ़्रेमवर्क
वीडियो
- Serverless Migration Station
- Serverless Expeditions
- Google Cloud Tech की सदस्यता लें
- Google Developers की सदस्यता लें
लाइसेंस
इस कॉन्टेंट को क्रिएटिव कॉमंस एट्रिब्यूशन 2.0 जेनरिक लाइसेंस के तहत लाइसेंस मिला है.