App Engine BLOBstore का इस्तेमाल कैसे करें (मॉड्यूल 15)

1. खास जानकारी

कोडलैब के बिना सर्वर वाले माइग्रेशन स्टेशन की सीरीज़ (अपने हिसाब से इस्तेमाल किए जाने वाले ट्यूटोरियल) और मिलते-जुलते वीडियो का मकसद, Google Cloud के बिना सर्वर वाले डेवलपर को अपने ऐप्लिकेशन को आधुनिक बनाने में मदद करना है. ऐसा करने के लिए, उन्हें लेगसी सेवाओं का इस्तेमाल बंद करना होगा. ऐसा करने के लिए, उन्हें एक या एक से ज़्यादा माइग्रेशन में मदद मिलेगी. ऐसा करने से, आपके ऐप्लिकेशन ज़्यादा पोर्टेबल बन जाते हैं. साथ ही, आपको ज़्यादा विकल्प और सुविधाएं भी मिलती हैं. इससे, क्लाउड प्रॉडक्ट की बड़ी रेंज को इंटिग्रेट किया जा सकता है और उन्हें ऐक्सेस किया जा सकता है. साथ ही, नई भाषाओं में रिलीज़ किए जाने वाले ऐप्लिकेशन पर आसानी से अपग्रेड किया जा सकता है. शुरुआत में App Engine (स्टैंडर्ड एनवायरमेंट) वाले डेवलपर पर ध्यान दिया जाता है. हालांकि, यह सीरीज़ इतनी बड़ी है कि इसमें Cloud Functions और Cloud Run जैसे बिना सर्वर वाले प्लैटफ़ॉर्म या लागू होने पर, उन्हें शामिल किया जा सकता है.

यह मॉड्यूल 15 कोडलैब, मॉड्यूल 0 से सैंपल ऐप्लिकेशन में App Engine blobstore के इस्तेमाल को जोड़ने का तरीका बताता है. इसके बाद, मॉड्यूल 16 में आगे इस इस्तेमाल को Cloud Storage में माइग्रेट किया जा सकेगा.

आपको इनके बारे में जानकारी मिलेगी

  • App Engine Blobstore API/लाइब्रेरी का इस्तेमाल जोड़ें
  • blobstore सेवा में उपयोगकर्ता के अपलोड संग्रहित करें
  • Cloud Storage में माइग्रेट करने के अगले चरण की तैयारी करें

आपको इनकी ज़रूरत होगी

सर्वे

इस ट्यूटोरियल का इस्तेमाल कैसे किया जाएगा?

इसे सिर्फ़ पढ़ें इसे पढ़ें और कसरतों को पूरा करें

Python के साथ अपने अनुभव को आप कितनी रेटिंग देंगे?

शुरुआती इंटरमीडिएट कुशल

Google Cloud की सेवाएं इस्तेमाल करने का आपका अनुभव कैसा रहा?

शुरुआती इंटरमीडिएट कुशल

2. बैकग्राउंड

App Engine Blobstore API से माइग्रेट करने के लिए, इसके इस्तेमाल को मॉड्यूल 0 से मौजूदा बेसलाइन App Engine ndb ऐप्लिकेशन में जोड़ें. नमूना ऐप्लिकेशन उपयोगकर्ता की सबसे हाल की दस विज़िट दिखाता है. हम ऐप्लिकेशन में बदलाव कर रहे हैं, ताकि असली उपयोगकर्ता को "वेबसाइट पर आने" से जुड़ा एक आर्टफ़ैक्ट (फ़ाइल) अपलोड करने का निर्देश दिया जा सके. अगर उपयोगकर्ता ऐसा नहीं करना चाहता है, तो "अभी नहीं" का विकल्प शामिल है. उपयोगकर्ता का फ़ैसला चाहे जो भी हो, अगला पेज वही आउटपुट रेंडर करता है जो मॉड्यूल 0 (और इस सीरीज़ के कई दूसरे मॉड्यूल) में मौजूद ऐप्लिकेशन की तरफ़ से मिलता है. इस App Engine blobstore इंटिग्रेशन को लागू करने के बाद, हम इसे अगले (मॉड्यूल 16) कोडलैब में Cloud Storage में माइग्रेट कर सकते हैं.

App Engine की मदद से, Django और Jinja2 टेंप्लेट का ऐक्सेस देता है. Blobstore का ऐक्सेस जोड़ने के अलावा, यह एक बात यह है कि यह मॉड्यूल 15 में मॉड्यूल 0 में Django से, Jinja2 तक स्विच करता है. App Engine ऐप्लिकेशन को आधुनिक बनाने का एक मुख्य कदम यह है कि वेब फ़्रेमवर्क को webapp2 से Flusk में माइग्रेट किया जाए. बाद में, Jinja2 अपने डिफ़ॉल्ट टेंप्लेट सिस्टम के तौर पर इस्तेमाल होता है. इसलिए, हम Blobstore का ऐक्सेस पाने के लिए, webapp2 पर रहते हुए Jinja2 को लागू करके, उस दिशा में आगे बढ़ना शुरू करते हैं. Flusk डिफ़ॉल्ट रूप से Jinja2 का इस्तेमाल करता है. इसका मतलब है कि मॉड्यूल 16 में, टेंप्लेट में कोई बदलाव करने की ज़रूरत नहीं है.

3. सेटअप/प्रीवर्क

ट्यूटोरियल के मुख्य हिस्से पर जाने से पहले, अपना प्रोजेक्ट सेट अप करें, कोड पाएं, और बेसलाइन ऐप्लिकेशन डिप्लॉय करें, ताकि काम करने वाले कोड के साथ शुरुआत की जा सके.

1. प्रोजेक्ट सेटअप करें

अगर आपने मॉड्यूल 0 ऐप्लिकेशन पहले ही डिप्लॉय कर लिया है, तो हमारा सुझाव है कि आप उसी प्रोजेक्ट (और कोड) का फिर से इस्तेमाल करें. इसके अलावा, नया प्रोजेक्ट बनाया जा सकता है या किसी मौजूदा प्रोजेक्ट का फिर से इस्तेमाल किया जा सकता है. पक्का करें कि प्रोजेक्ट में एक चालू बिलिंग खाता हो और App Engine चालू हो.

2. बेसलाइन ऐप्लिकेशन का नमूना डाउनलोड करें

इस कोडलैब के लिए एक ज़रूरी शर्त, काम करने वाला मॉड्यूल 0 सैंपल ऐप्लिकेशन होना है. अगर आपके पास यह नहीं है, तो इसे मॉड्यूल 0 "START" से लिया जा सकता है फ़ोल्डर (नीचे लिंक है). यह कोडलैब आपको हर चरण पर ले जाता है. इससे आखिर में एक कोड मिलता है, जो मॉड्यूल 15 के "FINISH" मॉड्यूल से मिलता-जुलता है फ़ोल्डर खोलें.

मॉड्यूल 0 STARTing फ़ाइलों की डायरेक्ट्री इस तरह दिखनी चाहिए:

$ ls
README.md               index.html
app.yaml                main.py

3. (फिर से) बेसलाइन ऐप्लिकेशन डिप्लॉय करें

कार्रवाई से पहले, इन चरणों को पूरा करें:

  1. gcloud कमांड-लाइन टूल का इस्तेमाल करके, फिर से जानें
  2. gcloud app deploy के साथ सैंपल ऐप्लिकेशन को फिर से डिप्लॉय करें
  3. पुष्टि करना कि ऐप्लिकेशन बिना किसी समस्या के App Engine पर चल रहा है

उन चरणों को सफलतापूर्वक पूरा कर लेने और अपने वेब ऐप्लिकेशन को काम करते हुए (नीचे दिए गए आउटपुट से मिलते-जुलते आउटपुट के साथ) देखने के बाद, आप अपने ऐप्लिकेशन में कैश मेमोरी का इस्तेमाल जोड़ने के लिए तैयार हैं.

a7a9d2b80d706a2b.png

4. कॉन्फ़िगरेशन फ़ाइलें अपडेट करना

app.yaml

ऐप्लिकेशन के कॉन्फ़िगरेशन में कोई अहम बदलाव नहीं किया गया है. हालांकि, जैसा कि पहले बताया गया है, हम Django टेंप्लेट (डिफ़ॉल्ट) से Jinja2 कर रहे हैं. इसलिए, स्विच करने के लिए, उपयोगकर्ताओं को App Engine सर्वर पर उपलब्ध Jinja2 का सबसे नया वर्शन तय करना होगा और आपको इसे 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 का इस्तेमाल करना और Django टेंप्लेट को Jinja2 से बदलना शामिल है. क्या-क्या बदलाव हो रहे हैं, इस बारे में यहां बताया गया है:

  1. os मॉड्यूल का मकसद, Django टेंप्लेट के लिए फ़ाइल का पाथ नेम बनाना है. अब हम Jinja2 पर स्विच कर रहे हैं, जहां इसे मैनेज किया जाता है. इसलिए, अब os और Django टेंप्लेट रेंडरर, google.appengine.ext.webapp.template के इस्तेमाल की ज़रूरत नहीं है. इसलिए, इन्हें हटाया जा रहा है.
  2. Blobstore API इंपोर्ट करें: google.appengine.ext.blobstore
  3. मूल webapp फ़्रेमवर्क में मिले Blobstore हैंडलर इंपोर्ट करें. ये webapp2 में उपलब्ध नहीं हैं: google.appengine.ext.webapp.blobstore_handlers
  4. webapp2_extras पैकेज से Jinja2 सहायता इंपोर्ट करें

पहले:

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

इंपोर्ट करने के बाद, webapp2_extras दस्तावेज़ में बताए गए तरीके से Jinja2 के इस्तेमाल के लिए, कुछ बॉयलरप्लेट कोड जोड़ें. यह कोड स्निपेट, स्टैंडर्ड 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 की सहायता टीम जोड़ें

हमने इस सीरीज़ में जो बदलाव किए हैं उनके उलट, हम सैंपल ऐप्लिकेशन के फ़ंक्शन या आउटपुट को एक जैसा (या करीब-करीब वैसा ही) रखते हैं और उपयोगकर्ता अनुभव में ज़्यादा बदलाव नहीं करते. इस उदाहरण में, इस स्टैंडर्ड के मुताबिक बदलाव किया गया है. तुरंत नई विज़िट रजिस्टर करने और सबसे हाल के दस को दिखाने के बजाय, हम ऐप्लिकेशन को अपडेट कर रहे हैं. इस अपडेट के ज़रिए, हम उपयोगकर्ता से फ़ाइल के एक आर्टफ़ैक्ट की मदद से विज़िट को रजिस्टर करने के लिए कह सकते हैं. इसके बाद, असली उपयोगकर्ता इससे जुड़ी फ़ाइल अपलोड कर सकते हैं या "अभी नहीं" चुन सकते हैं ताकि कुछ भी अपलोड न किया जा सके. यह चरण पूरा होने के बाद, "सबसे हाल की विज़िट" पेज दिखाई देता है.

इस बदलाव से हमारे ऐप्लिकेशन को हाल ही में विज़िट किए गए पेज पर, उस इमेज या अन्य फ़ाइल टाइप को सेव करने (और बाद में रेंडर करने) के लिए Blobstore सेवा का इस्तेमाल करने की अनुमति मिलती है.

डेटा मॉडल को अपडेट करना और इसका इस्तेमाल लागू करना

हम ज़्यादा डेटा सेव कर रहे हैं. खास तौर पर, Blobstore में अपलोड की गई फ़ाइल के आईडी (जिसे "BlobKey" कहा जाता है) को स्टोर करने के लिए, डेटा मॉडल को अपडेट कर रहे हैं. साथ ही, उसे 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)

यहां अब तक किए गए बदलावों को तस्वीरों के ज़रिए दिखाया गया है:

2270783776759f7f.png

सहायता के लिए फ़ाइल अपलोड करना

फ़ंक्शन में सबसे बड़ा बदलाव फ़ाइल अपलोड करने में मदद करना है. इससे कोई फ़र्क नहीं पड़ता कि लोगों को फ़ाइल अपलोड करने के लिए कहा जा रहा है या "स्किप" करने की सुविधा के लिए शामिल हैं या किसी विज़िट से जुड़ी फ़ाइल रेंडर की गई है. ये सभी चीज़ें तस्वीर का हिस्सा हैं. फ़ाइल अपलोड करने में मदद करने के लिए, ये बदलाव ज़रूरी हैं:

  1. मुख्य हैंडलर GET का अनुरोध, अब डिसप्ले के लिए सबसे हाल की विज़िट को फ़ेच नहीं करता. इसके बजाय, यह उपयोगकर्ता को फ़ाइल अपलोड करने के लिए कहता है.
  2. जब कोई असली उपयोगकर्ता उस प्रोसेस को अपलोड करने के लिए किसी फ़ाइल को सबमिट करता है या उसे स्किप करता है, तो फ़ॉर्म में मौजूद POST, google.appengine.ext.webapp.blobstore_handlers.BlobstoreUploadHandler से नए UploadHandler को कंट्रोल करता है.
  3. UploadHandler का POST तरीका अपलोड करता है, विज़िट को रजिस्टर करने के लिए store_visit() को कॉल करता है, और उपयोगकर्ता को "/" पर वापस भेजने के लिए एचटीटीपी 307 रीडायरेक्ट ट्रिगर करता है, जहां...
  4. मुख्य हैंडलर का POST तरीका, fetch_visits() के ज़रिए क्वेरी करता है और सबसे हाल की विज़िट दिखाता है. अगर उपयोगकर्ता "अभी नहीं" चुनता है, कोई फ़ाइल अपलोड नहीं की गई, लेकिन विज़िट अब भी रजिस्टर है और उसके बाद वही रीडायरेक्ट किया गया है.
  5. सबसे हाल की विज़िट में, उपयोगकर्ता को एक नया फ़ील्ड दिखाया जाता है. यह फ़ील्ड हाइपरलिंक किया गया "व्यू" हो सकता है अगर अपलोड की गई फ़ाइल उपलब्ध है या "कोई नहीं" है नहीं तो. ये बदलाव, एक अपलोड फ़ॉर्म के साथ एचटीएमएल टेंप्लेट में लागू किए जाते हैं. इस बारे में ज़्यादा जानकारी जल्द ही उपलब्ध होगी.
  6. अगर कोई असली उपयोगकर्ता "व्यू" पर क्लिक करता है लिंक पर क्लिक करता है, तो यह google.appengine.ext.webapp.blobstore_handlers.BlobstoreDownloadHandler से नए ViewBlobHandler पर GET अनुरोध करता है. यह google.appengine.ext.webapp.blobstore_handlers.BlobstoreDownloadHandler से मिलता है. अगर इमेज मौजूद है, तो फ़ाइल को रेंडर करता है (अगर यह सुविधा ब्राउज़र में काम करती है), तो डाउनलोड न होने की सूचना दिखाता है या नहीं मिलने पर एचटीटीपी 404 गड़बड़ी दिखाता है.
  7. ट्रैफ़िक भेजने के लिए, हैंडलर क्लास के नए जोड़े के साथ-साथ रूट की एक नई जोड़ी के साथ-साथ, मुख्य हैंडलर को ऊपर बताए गए 307 रीडायरेक्ट पाने के लिए एक नए POST तरीके की ज़रूरत होगी.

इन अपडेट से पहले, मॉड्यूल 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) "व्यू ब्लॉब" 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 पर कॉल किया जाएगा. यह कॉल, POST फ़ॉर्म का यूआरएल जनरेट करता है और फ़ाइल को Blobstore पर भेजने के लिए अपलोड हैंडलर को कॉल करता है.
  • UploadHandler.post बाद, blobstore_handlers.BlobstoreUploadHandler.get_uploads पर कॉल किया जाएगा. यह उस फ़ाइल को Blobstore में शामिल करता है और उस फ़ाइल के लिए एक यूनीक और परसिस्टेंट आईडी, यानी कि BlobKey दिखाता है.
  • ViewBlobHandler.get में, blobstore_handlers.BlobstoreDownloadHandler.send को किसी फ़ाइल के BlobKey के साथ कॉल करने पर, फ़ाइल फ़ेच की जाएगी और उसे असली उपयोगकर्ता के ब्राउज़र पर फ़ॉरवर्ड किया जाएगा

ये कॉल, ऐप्लिकेशन में जोड़ी गई सुविधाओं को बड़े पैमाने पर ऐक्सेस करते हैं. यहां main.py में हुए बदलावों के दूसरे और आखिरी सेट को तस्वीरों के ज़रिए दिखाया गया है:

da2960525ac1b90d.png

एचटीएमएल टेंप्लेट अपडेट करें

मुख्य ऐप्लिकेशन में किए गए कुछ अपडेट, ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) पर असर डालते हैं. इसलिए, वेब टेंप्लेट में संबंधित बदलाव करने होंगे. इनमें से दो:

  1. फ़ाइल अपलोड फ़ॉर्म में तीन इनपुट एलिमेंट होने चाहिए: फ़ाइल अपलोड करने और स्किप करने के लिए, एक फ़ाइल और सबमिट बटन की एक जोड़ी.
  2. "दृश्य" जोड़कर सबसे हाल की विज़िट का आउटपुट अपडेट करें संबंधित फ़ाइल अपलोड या "कोई नहीं" के साथ विज़िट का लिंक नहीं तो.

पहले:

<!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 के लिए ज़रूरी अपडेट दिखाए गए हैं:

8583e975f25aa9e7.png

एक आखिरी बदलाव यह है कि Jinja2 अपने टेंप्लेट को templates फ़ोल्डर में प्राथमिकता देता है, इसलिए वह फ़ोल्डर बनाएं और index.html को उसके अंदर ले जाएं. इस आखिरी बदलाव के बाद, अब आपने मॉड्यूल 0 सैंपल ऐप्लिकेशन में Blobstore के इस्तेमाल से जुड़े सभी ज़रूरी बदलाव कर लिए हैं.

(ज़रूरी नहीं) Cloud Storage "बेहतर बनाना"

Blobstore स्टोरेज, धीरे-धीरे Cloud Storage में बदल गया. इसका मतलब है कि Blobstore से किए गए अपलोड, Cloud Console में दिखते हैं. खास तौर पर, Cloud Storage ब्राउज़र में. सवाल यह है कि आप कहां हैं. जवाब है, आपके App Engine ऐप्लिकेशन का डिफ़ॉल्ट Cloud Storage बकेट. यह आपके App Engine ऐप्लिकेशन के पूरे डोमेन नेम PROJECT_ID.appspot.com का नाम है. यह बहुत आसान है, क्योंकि सभी प्रोजेक्ट आईडी यूनीक होते हैं, है न?

ऐप्लिकेशन के सैंपल में किए गए अपडेट, अपलोड की गई फ़ाइलों को उस बकेट में डाल देते हैं, लेकिन डेवलपर के पास ज़्यादा सटीक जगह चुनने का विकल्प होता है. डिफ़ॉल्ट बकेट को google.appengine.api.app_identity.get_default_gcs_bucket_name() से प्रोग्राम के हिसाब से ऐक्सेस किया जा सकता है. अगर आपको इस वैल्यू को ऐक्सेस करना है, तो इसे इंपोर्ट करने के लिए एक नया इंपोर्ट करना होगा. जैसे, अपलोड की गई फ़ाइलों को व्यवस्थित करने के लिए, प्रीफ़िक्स के तौर पर इस्तेमाल करें. उदाहरण के लिए, फ़ाइल टाइप के हिसाब से क्रम में लगाना:

f61f7a23a1518705.png

उदाहरण के लिए, इमेज के लिए इस तरह का कोड लागू करने के लिए, आपको कुछ इस तरह के कोड के साथ-साथ कुछ कोड भी मिलेंगे. यह कोड उन फ़ाइल टाइप को चुनता है जो अपनी पसंद के बकेट का नाम चुनने के लिए, इस तरह के फ़ाइल टाइप को चेक करते हैं:

ROOT_BUCKET = app_identity.get_default_gcs_bucket_name()
IMAGE_BUCKET = '%s/%s' % (ROOT_BUCKET, 'images')

इमेज टाइप की पुष्टि करने के लिए, आपको Python स्टैंडर्ड लाइब्रेरी imghdr मॉड्यूल जैसे टूल का इस्तेमाल करके अपलोड की गई इमेज की पुष्टि करनी होगी. आखिर में, बुरे मकसद से काम करने वाले लोगों या ग्रुप के मामले में, आपको अपलोड किए जाने वाले वीडियो का साइज़ सीमित करना चाहिए.

मान लीजिए, सभी काम हो गए. हम अपलोड की गई फ़ाइलें कहां सेव करनी हैं, यह बताने के लिए हम अपने ऐप्लिकेशन को कैसे अपडेट कर सकते हैं? मुख्य बात यह है कि MainHandler.get में blobstore.create_upload_url कॉल में बदलाव करके, Cloud Storage में अपनी पसंद की जगह तय की जा सकती है. इसके लिए, gs_bucket_name पैरामीटर को इस तरह से जोड़ें:

blobstore.create_upload_url('/upload', gs_bucket_name=IMAGE_BUCKET))

अगर आपको यह बताना है कि अपलोड को कहां किया जाना चाहिए, तो यह एक वैकल्पिक अपडेट है. इसलिए, यह रेपो में मौजूद main.py फ़ाइल का हिस्सा नहीं होता. इसके बजाय, डेटा स्टोर करने की जगह में आपकी समीक्षा के लिए, main-gcs.py नाम का दूसरा विकल्प उपलब्ध है. एक अलग बकेट "फ़ोल्डर" का उपयोग करने के बजाय, main-gcs.py का कोड, "रूट" में अपलोड स्टोर करता है बकेट (PROJECT_ID.appspot.com की तरह, main.py की तरह, लेकिन अगर आपको इस सेक्शन में बताए गए तरीके से सैंपल तैयार करना है, तो यह आपको ज़रूरत के हिसाब से स्कैफ़ोल्डिंग की सुविधा देता है. नीचे "अंतर" का एक उदाहरण दिया गया है main.py से main-gcs.py के बीच.

256e1ea68241a501.png

6. खास जानकारी/क्लीनअप

यह सेक्शन, कोडलैब के इस मॉड्यूल को रैप करके पूरा करता है. इसके लिए, ऐप्लिकेशन को डिप्लॉय किया जाता है. साथ ही, यह पुष्टि की जाती है कि यह सही तरीके से और किसी भी नतीजे पर दिखने वाले आउटपुट के हिसाब से काम करता है या नहीं. ऐप्लिकेशन की पुष्टि करने के बाद, क्लीनअप करने के लिए सभी चरणों को पूरा करें और आगे के चरणों के बारे में सोचें.

ऐप्लिकेशन डिप्लॉय करें और उसकी पुष्टि करें

gcloud app deploy के साथ अपने ऐप्लिकेशन को फिर से डिप्लॉय करें. साथ ही, यह पुष्टि करें कि ऐप्लिकेशन, विज्ञापन के हिसाब से काम करता हो. साथ ही, ऐप्लिकेशन, मॉड्यूल 0 ऐप्लिकेशन से अलग है और उपयोगकर्ता अनुभव (UX) के हिसाब से यह काम करता है. आपके ऐप्लिकेशन में अब दो अलग-अलग स्क्रीन उपलब्ध हैं. पहला, विज़िट फ़ाइल अपलोड फ़ॉर्म प्रॉम्प्ट:

f5b5f9f19d8ae978.pngइसके बाद, असली उपयोगकर्ता या तो फ़ाइल अपलोड करते हैं और "सबमिट करें" पर क्लिक करते हैं या "अभी नहीं" पर क्लिक करें कुछ भी अपलोड न हो. दोनों ही मामलों में, नतीजे के तौर पर सबसे हाल में देखी जाने वाली स्क्रीन दिखती है. इसे अब "व्यू" की मदद से बेहतर बनाया जाता है लिंक या "कोई नहीं" विज़िट टाइमस्टैंप और विज़िटर जानकारी के बीच:

f5ac6b98ee8a34cb.png

मॉड्यूल 0 नमूना ऐप्लिकेशन में App Engine Blobstore के उपयोग को जोड़कर, इस कोडलैब को पूरा करने के लिए बधाई. अब आपका कोड, FINISH (मॉड्यूल 15) फ़ोल्डर में मौजूद कोड से मेल खाना चाहिए. उस फ़ोल्डर में दूसरा main-gcs.py भी मौजूद है.

व्यवस्थित करें

सामान्य

अगर आपका काम अभी हो गया है, तो हमारा सुझाव है कि आप बिलिंग से बचने के लिए अपना App Engine ऐप्लिकेशन बंद कर दें. हालांकि, अगर आपको कुछ और टेस्ट या एक्सपेरिमेंट करना है, तो App Engine प्लैटफ़ॉर्म का एक मुफ़्त कोटा है. अगर इस्तेमाल के टीयर को पार नहीं किया जा रहा है, तो आपसे शुल्क नहीं लिया जाएगा. यह कंप्यूट के लिए है. हालांकि, काम के App Engine की सेवाओं के लिए भी शुल्क लिया जा सकता है. इसलिए, ज़्यादा जानकारी के लिए इसका कीमत पेज देखें. अगर इस माइग्रेशन में क्लाउड की अन्य सेवाएं शामिल हैं, तो उनका बिल अलग से भेजा जाता है. दोनों ही मामलों में, अगर लागू हो, तो "इस कोडलैब के लिए खास" सेक्शन देखें सेक्शन देखें.

अगर आपको पूरी जानकारी देनी है, तो App Engine जैसे Google Cloud के बिना सर्वर वाले कंप्यूट प्लैटफ़ॉर्म पर डिप्लॉय करने पर, मामूली बनाने और स्टोरेज का खर्च उठाना पड़ता है. Cloud Storage की तरह Cloud Build का अपना अलग कोटा होता है. उस इमेज का स्टोरेज, उसके कुछ हिस्से का इस्तेमाल करता है. हालांकि, हो सकता है कि आप किसी ऐसे क्षेत्र में हों जहां ऐसा कोई फ़्री टीयर उपलब्ध न हो. इसलिए, संभावित लागत को कम करने के लिए, अपने स्टोरेज के इस्तेमाल को ध्यान में रखें. 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" अगर आपका ऐप्लिकेशन अमेरिका में होस्ट किया जाता है.

दूसरी ओर, अगर आपको इस ऐप्लिकेशन या इससे जुड़े दूसरे माइग्रेशन कोडलैब का इस्तेमाल नहीं करना है और सब कुछ पूरी तरह से मिटाना है, तो अपना प्रोजेक्ट बंद कर दें.

इस कोडलैब के लिए खास

नीचे दी गई सेवाएं, इस कोडलैब के लिए यूनीक हैं. ज़्यादा जानकारी के लिए हर प्रॉडक्ट के दस्तावेज़ देखें:

अगले चरण

अगला लॉजिकल माइग्रेशन, मॉड्यूल 16 में शामिल किया गया है. इसमें, डेवलपर को यह बताया गया है कि वे App Engine Blobstore सेवा से Cloud Storage क्लाइंट लाइब्रेरी का इस्तेमाल करने के लिए कैसे माइग्रेट करें. अपग्रेड करने के फ़ायदों में, Cloud Storage की ज़्यादा सुविधाओं का ऐक्सेस होना, App Engine के बाहर के ऐप्लिकेशन के लिए काम करने वाली क्लाइंट लाइब्रेरी के बारे में जानना, चाहे वह Google क्लाउड हो, दूसरे क्लाउड में या ऑफ़िस में भी शामिल है. अगर आपको Cloud Storage की सभी सुविधाएं नहीं चाहिए या आप इसके खर्च पर होने वाले असर को लेकर परेशान हैं, तो आप App Engine Blobstore पर बने रह सकते हैं.

मॉड्यूल 16 के बाद, Cloud NDB और Cloud Datastore, Cloud Tasks या Cloud Memorystore जैसे अन्य माइग्रेशन की पूरी सूची है. Cloud Run और Cloud Functions के लिए, क्रॉस-प्रॉडक्ट माइग्रेशन भी उपलब्ध हैं. माइग्रेशन रेपो में सभी कोड सैंपल मौजूद होते हैं. यह आपको सभी उपलब्ध कोडलैब और वीडियो से लिंक करता है. साथ ही, इससे यह भी पता चलता है कि किस माइग्रेशन पर विचार करना है और क्या "ऑर्डर" लागू करना है माइग्रेशन हो सकता है.

7. अन्य संसाधन

कोडलैब (कोड बनाना सीखना) से जुड़ी समस्याएं/सुझाव/राय/शिकायत

अगर आपको इस कोडलैब के साथ कोई समस्या मिलती है, तो कृपया आवेदन करने से पहले अपनी समस्या का पता लगाएं. खोजने और नई समस्याएं बनाने के लिए लिंक:

माइग्रेशन के लिए संसाधन

यहां दी गई टेबल में, मॉड्यूल 0 (START) और मॉड्यूल 15 (FINISH) के रेपो फ़ोल्डर के लिंक दिए गए हैं. उन्हें सभी App Engine कोडलैब माइग्रेशन के लिए रेपो से भी ऐक्सेस किया जा सकता है, जिसका क्लोन बनाया जा सकता है या किसी ZIP फ़ाइल को डाउनलोड किया जा सकता है.

Codelab

Python 2

Python 3

मॉड्यूल 0

कोड

लागू नहीं

मॉड्यूल 15 (यह कोडलैब)

कोड

लागू नहीं

ऑनलाइन संसाधन

नीचे कुछ ऑनलाइन संसाधन दिए गए हैं, जो इस ट्यूटोरियल के लिए काम के हो सकते हैं:

App Engine

Google Cloud

Python

वीडियो

लाइसेंस

इस काम को क्रिएटिव कॉमंस एट्रिब्यूशन 2.0 जेनरिक लाइसेंस के तहत लाइसेंस मिला है.