Google Workspace में इमेज संग्रहित करना, उनका विश्लेषण करना, और रिपोर्ट जनरेट करना Google क्लाउड

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

इस कोडलैब में, एंटरप्राइज़ के संभावित वर्कफ़्लो के बारे में बताया गया है: इमेज को संग्रहित करना, उनका विश्लेषण करना, और रिपोर्ट जनरेट करना. मान लें कि आपके संगठन के पास कई इमेज हैं, जो सीमित संसाधन पर जगह घेर रही हैं. आपको उस डेटा को संग्रहित करना है, उन इमेज का विश्लेषण करना है, और सबसे अहम बात यह है कि आपको संग्रहित की गई जगहों और विश्लेषण के नतीजों की खास जानकारी देने वाली रिपोर्ट जनरेट करनी है. यह रिपोर्ट, मैनेजमेंट के इस्तेमाल के लिए तैयार होनी चाहिए. Google Cloud, ऐसा करने के लिए टूल उपलब्ध कराता है. इसके लिए, वह अपनी दो प्रॉडक्ट लाइनों, Google Workspace (पहले, G Suite या Google Apps) और Google Cloud (पहले, GCP) के एपीआई का इस्तेमाल करता है.

हमारे उदाहरण में, कारोबार के उपयोगकर्ता के पास Google Drive में इमेज होंगी. इसलिए, इन डेटा का बैक अप "कोल्डर" और कम कीमत वाले स्टोरेज में लेना बेहतर होता है. जैसे, Google Cloud Storage में उपलब्ध स्टोरेज क्लास. Google Cloud Vision की मदद से डेवलपर, ऐप्लिकेशन में विज़न डिटेक्ट करने की सुविधाओं को आसानी से इंटिग्रेट कर पाते हैं. जैसे, ऑब्जेक्ट और लैंडमार्क की पहचान करने, ऑप्टिकल कैरेक्टर रिकग्निशन (ओसीआर) वगैरह की सुविधा. आखिर में, Google Sheets स्प्रेडशीट, आपके बॉस के लिए इन सभी चीज़ों की खास जानकारी देने वाला एक उपयोगी विज़ुअलाइज़ेशन टूल है.

इस कोडलैब को पूरा करने के बाद, हमें उम्मीद है कि आपको Google Cloud की सभी सुविधाओं का इस्तेमाल करके, अपने संगठन या ग्राहकों के लिए ज़्यादा असरदार समाधान बनाने की प्रेरणा मिलेगी.

आपको क्या सीखने को मिलेगा

  • Cloud Shell का इस्तेमाल कैसे करें
  • एपीआई अनुरोधों की पुष्टि करने का तरीका
  • Python के लिए Google APIs क्लाइंट लाइब्रेरी इंस्टॉल करने का तरीका
  • Google API चालू करने का तरीका
  • Google Drive से फ़ाइलें डाउनलोड करने का तरीका
  • Cloud Storage में ऑब्जेक्ट/ब्लॉब अपलोड करने का तरीका
  • Cloud Vision की मदद से डेटा का विश्लेषण कैसे करें
  • Google Sheets में लाइनें लिखने का तरीका

आपको किन चीज़ों की ज़रूरत होगी

  • Google खाता (Google Workspace खातों के लिए, एडमिन की अनुमति ज़रूरी हो सकती है)
  • चालू Google Cloud बिलिंग खाते वाला Google Cloud प्रोजेक्ट
  • ऑपरेटिंग सिस्टम के टर्मिनल/शेल कमांड के बारे में जानकारी
  • Python (2 या 3) की बुनियादी जानकारी होनी चाहिए. हालांकि, किसी भी ऐसी भाषा का इस्तेमाल किया जा सकता है जो इस सुविधा के साथ काम करती है

ऊपर दिए गए चार Google Cloud प्रॉडक्ट के बारे में जानकारी होना फ़ायदेमंद होगा, लेकिन यह ज़रूरी नहीं है. अगर आपके पास समय है, तो पहले इन विषयों के बारे में अलग-अलग जानें. इसके बाद, यहां दिए गए अभ्यास को पूरा करें:

सर्वे

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

सिर्फ़ इसे पढ़ें इसे पढ़ें और एक्सरसाइज़ पूरी करें

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

शुरुआती सामान्य एडवांस

Google Cloud की सेवाओं को इस्तेमाल करने के अपने अनुभव को आप क्या रेटिंग देंगे?

शुरुआती सामान्य एडवांस

Google Workspace की डेवलपर सेवाओं को इस्तेमाल करने के अपने अनुभव को आप क्या रेटिंग देंगे?

शुरुआती सामान्य एडवांस

क्या आपको प्रॉडक्ट की सुविधाओं के बारे में बताने वाले कोडलैब के बजाय, "कारोबार से जुड़े" ज़्यादा कोडलैब देखने हैं?

हां नहीं दोनों में से ज़्यादा

2. सेटअप और ज़रूरी शर्तें

अपनी स्पीड से एनवायरमेंट सेट अप करना

  1. Google Cloud Console में साइन इन करें और नया प्रोजेक्ट बनाएं या किसी मौजूदा प्रोजेक्ट का फिर से इस्तेमाल करें. अगर आपके पास पहले से कोई Gmail या Google Workspace खाता नहीं है, तो आपको एक खाता बनाना होगा.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • प्रोजेक्ट का नाम, इस प्रोजेक्ट में हिस्सा लेने वाले लोगों के लिए डिसप्ले नेम होता है. यह एक वर्ण स्ट्रिंग है, जिसका इस्तेमाल Google API नहीं करते. इसे कभी भी अपडेट किया जा सकता है.
  • प्रोजेक्ट आईडी, सभी Google Cloud प्रोजेक्ट के लिए यूनीक होना चाहिए. साथ ही, इसे बदला नहीं जा सकता. Cloud Console, यूनीक स्ट्रिंग अपने-आप जनरेट करता है. आम तौर पर, आपको इससे कोई फ़र्क़ नहीं पड़ता कि यह क्या है. ज़्यादातर कोडलैब में, आपको प्रोजेक्ट आईडी का रेफ़रंस देना होगा. आम तौर पर, इसे PROJECT_ID के तौर पर पहचाना जाता है. अगर आपको जनरेट किया गया आईडी पसंद नहीं है, तो कोई दूसरा रैंडम आईडी जनरेट किया जा सकता है. इसके अलावा, आपके पास अपना नाम आज़माने का विकल्प भी है. इससे आपको पता चलेगा कि वह नाम उपलब्ध है या नहीं. इस चरण के बाद, इसे बदला नहीं जा सकता. यह प्रोजेक्ट की अवधि तक बना रहेगा.
  • आपकी जानकारी के लिए बता दें कि एक तीसरी वैल्यू भी होती है, जिसे प्रोजेक्ट नंबर कहते हैं. इसका इस्तेमाल कुछ एपीआई करते हैं. इन तीनों वैल्यू के बारे में ज़्यादा जानने के लिए, दस्तावेज़ देखें.
  1. इसके बाद, आपको Cloud Console में बिलिंग चालू करनी होगी, ताकि Cloud संसाधनों/एपीआई का इस्तेमाल किया जा सके. इस कोडलैब को पूरा करने में ज़्यादा खर्च नहीं आएगा. इस ट्यूटोरियल के बाद बिलिंग से बचने के लिए, बनाए गए संसाधनों को बंद किया जा सकता है. इसके लिए, बनाए गए संसाधनों को मिटाएं या पूरे प्रोजेक्ट को मिटाएं. Google Cloud के नए उपयोगकर्ताओं को, मुफ़्त में आज़माने के लिए 300 डॉलर का क्रेडिट मिलता है.

Cloud Shell शुरू करना

खास जानकारी

आपके पास अपने लैपटॉप पर कोड डेवलप करने का विकल्प होता है. हालांकि, इस कोडलैब का दूसरा मकसद यह है कि आपको Google Cloud Shell का इस्तेमाल करना सिखाया जाए. यह एक कमांड-लाइन एनवायरमेंट है, जो आपके मॉडर्न वेब ब्राउज़र के ज़रिए क्लाउड में चलता है.

Cloud Shell चालू करें

  1. Cloud Console में, Cloud Shell चालू करें 853e55310c205094.png पर क्लिक करें.

55efc1aaa7a4d3ad.png

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

9c92662c6a846a5c.png

Cloud Shell से कनेक्ट होने में कुछ ही सेकंड लगेंगे.

9f0e51b578fecce5.png

इस वर्चुअल मशीन में, डेवलपमेंट के लिए ज़रूरी सभी टूल पहले से मौजूद होते हैं. यह 5 जीबी की होम डायरेक्ट्री उपलब्ध कराता है और Google Cloud में चलता है. इससे नेटवर्क की परफ़ॉर्मेंस और पुष्टि करने की प्रोसेस बेहतर होती है. इस कोडलैब में ज़्यादातर काम, सिर्फ़ ब्राउज़र या Chromebook की मदद से किया जा सकता है.

Cloud Shell से कनेक्ट होने के बाद, आपको दिखेगा कि आपकी पुष्टि पहले ही हो चुकी है और प्रोजेक्ट को आपके प्रोजेक्ट आईडी पर पहले ही सेट कर दिया गया है.

  1. पुष्टि करें कि आपने Cloud Shell में पुष्टि कर ली है. इसके लिए, यह कमांड चलाएं:
gcloud auth list

कमांड आउटपुट

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. यह पुष्टि करने के लिए कि gcloud कमांड को आपके प्रोजेक्ट के बारे में पता है, Cloud Shell में यह कमांड चलाएं:
gcloud config list project

कमांड आउटपुट

[core]
project = <PROJECT_ID>

अगर ऐसा नहीं है, तो इस कमांड का इस्तेमाल करके इसे सेट किया जा सकता है:

gcloud config set project <PROJECT_ID>

कमांड आउटपुट

Updated property [core/project].

3. Python एनवायरमेंट की पुष्टि करना

इस कोडलैब के लिए, आपको Python भाषा का इस्तेमाल करना होगा. हालांकि, Google APIs की क्लाइंट लाइब्रेरी कई भाषाओं के साथ काम करती हैं. इसलिए, अपने पसंदीदा डेवलपमेंट टूल में इसके जैसा कुछ बनाएं और Python को सिर्फ़ स्यूडोकोड के तौर पर इस्तेमाल करें. खास तौर पर, यह कोडलैब Python 2 और 3 के साथ काम करता है. हालांकि, हमारा सुझाव है कि आप जल्द से जल्द 3.x पर माइग्रेट कर लें.

Cloud Shell एक सुविधाजनक टूल है. यह उपयोगकर्ताओं के लिए सीधे Cloud Console से उपलब्ध होता है. इसके लिए, लोकल डेवलपमेंट एनवायरमेंट की ज़रूरत नहीं होती. इसलिए, इस ट्यूटोरियल को वेब ब्राउज़र की मदद से पूरी तरह से क्लाउड में किया जा सकता है. खास तौर पर इस कोडलैब के लिए, Cloud Shell में Python के दोनों वर्शन पहले से इंस्टॉल हैं.

Cloud Shell में IPython भी इंस्टॉल है: यह एक इंटरैक्टिव Python इंटरप्रेटर है, जिसे हम इस्तेमाल करने का सुझाव देते हैं. खास तौर पर, अगर आप डेटा साइंस या मशीन लर्निंग कम्यूनिटी का हिस्सा हैं. अगर ऐसा है, तो IPython, Jupyter Notebooks और Google Research की ओर से होस्ट की जाने वाली Colab के लिए डिफ़ॉल्ट इंटरप्रेटर है.

IPython, सबसे पहले Python 3 इंटरप्रेटर को प्राथमिकता देता है. हालांकि, अगर 3.x उपलब्ध नहीं है, तो यह Python 2 पर वापस आ जाता है. IPython को Cloud Shell से ऐक्सेस किया जा सकता है. हालांकि, इसे लोकल डेवलपमेंट एनवायरमेंट में भी इंस्टॉल किया जा सकता है. ^D (Ctrl-d) दबाकर बाहर निकलें और बाहर निकलने के लिए ऑफ़र स्वीकार करें. ipython से शुरू होने वाले आउटपुट का उदाहरण यहां दिया गया है:

$ ipython
Python 3.7.3 (default, Mar  4 2020, 23:11:43)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.13.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

अगर आपको IPython का इस्तेमाल नहीं करना है, तो स्टैंडर्ड Python इंटरैक्टिव इंटरप्रेटर (Cloud Shell या आपका लोकल डेवलपमेंट एनवायरमेंट) का इस्तेमाल किया जा सकता है. इससे कोई समस्या नहीं होगी. साथ ही, ^D का इस्तेमाल करके भी बाहर निकला जा सकता है:

$ python
Python 2.7.13 (default, Sep 26 2018, 18:42:22)
[GCC 6.3.0 20170516] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
$ python3
Python 3.7.3 (default, Mar 10 2020, 02:33:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

इस कोडलैब में यह भी माना गया है कि आपके पास pip इंस्टॉलेशन टूल (Python पैकेज मैनेजर और डिपेंडेंसी रिज़ॉल्वर) है. यह 2.7.9+ या 3.4+ वर्शन के साथ बंडल किया गया है. अगर आपके पास Python का पुराना वर्शन है, तो इंस्टॉलेशन के निर्देशों के लिए यह गाइड देखें. आपके पास sudo या सुपरयूज़र का ऐक्सेस होना चाहिए. हालांकि, ऐसा हमेशा नहीं होता. pip को Python के किसी खास वर्शन पर चलाने के लिए, pip2 या pip3 का इस्तेमाल भी किया जा सकता है.

इस कोडलैब के बाकी हिस्से में, यह माना गया है कि Python 3 का इस्तेमाल किया जा रहा है. अगर Python 2 के निर्देश, 3.x से काफ़ी अलग हैं, तो उनके लिए अलग से निर्देश दिए जाएंगे.

[ज़रूरी नहीं] वर्चुअल एनवायरमेंट बनाना और उनका इस्तेमाल करना

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

virtualenv my_env

हालांकि, अगर आपके कंप्यूटर पर Python 2 और 3, दोनों हैं, तो हमारा सुझाव है कि आप Python 3 virtualenv इंस्टॉल करें. इसके लिए, -p flag का इस्तेमाल इस तरह करें:

virtualenv -p python3 my_env

यहां दिए गए तरीके से, अभी-अभी बनाए गए virtualenv को "चालू करें":

source my_env/bin/activate

पुष्टि करें कि आप एनवायरमेंट में हैं.इसके लिए, देखें कि क्या आपके शेल प्रॉम्प्ट से पहले अब आपके एनवायरमेंट का नाम दिख रहा है. जैसे,

(my_env) $ 

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

4. Python के लिए Google APIs क्लाइंट लाइब्रेरी इंस्टॉल करना

इस कोडलैब के लिए, Python के लिए Google API की क्लाइंट लाइब्रेरी का इस्तेमाल करना ज़रूरी है. इसलिए, इसे इंस्टॉल करना आसान है. इसके अलावा, हो सकता है कि आपको कुछ भी न करना पड़े.

हमने आपको पहले सुझाव दिया था कि आप आसानी से काम करने के लिए, Cloud Shell का इस्तेमाल करें. क्लाउड में मौजूद वेब ब्राउज़र से, पूरा ट्यूटोरियल देखा जा सकता है. Cloud Shell का इस्तेमाल करने की एक और वजह यह है कि इसमें कई लोकप्रिय डेवलपमेंट टूल और ज़रूरी लाइब्रेरी पहले से प्री-इंस्टॉल होती हैं.

*क्लाइंट लाइब्रेरी इंस्टॉल करना

(ज़रूरी नहीं) अगर Cloud Shell या ऐसे लोकल एनवायरमेंट का इस्तेमाल किया जा रहा है जहां आपने पहले से ही क्लाइंट लाइब्रेरी इंस्टॉल की हैं, तो इस चरण को छोड़ा जा सकता है. आपको ऐसा सिर्फ़ तब करना होगा, जब ऐप्लिकेशन को स्थानीय तौर पर डेवलप किया जा रहा हो और आपने उन्हें इंस्टॉल न किया हो या आपको यह पक्का न हो कि आपने उन्हें इंस्टॉल किया है या नहीं. इसे इंस्टॉल करने का सबसे आसान तरीका है pip (या pip3) का इस्तेमाल करना. अगर ज़रूरी हो, तो pip को अपडेट करने के लिए भी इसका इस्तेमाल किया जा सकता है:

pip install -U pip google-api-python-client oauth2client

इंस्टॉल किए जाने की पुष्टि करना

इस कमांड से क्लाइंट लाइब्रेरी के साथ-साथ, उससे जुड़े सभी पैकेज भी इंस्टॉल हो जाते हैं. चाहे Cloud Shell का इस्तेमाल किया जा रहा हो या अपने एनवायरमेंट का, यह पुष्टि करें कि क्लाइंट लाइब्रेरी इंस्टॉल है. इसके लिए, ज़रूरी पैकेज इंपोर्ट करें और पुष्टि करें कि इंपोर्ट करने में कोई गड़बड़ी नहीं हुई है और न ही कोई आउटपुट मिला है:

python3 -c "import googleapiclient, httplib2, oauth2client"

अगर Cloud Shell से Python 2 का इस्तेमाल किया जाता है, तो आपको यह चेतावनी मिलेगी कि अब यह काम नहीं करता:

*******************************************************************************
Python 2 is deprecated. Upgrade to Python 3 as soon as possible.
See https://cloud.google.com/python/docs/python2-sunset

To suppress this warning, create an empty ~/.cloudshell/no-python-warning file.
The command will automatically proceed in  seconds or on any key.
*******************************************************************************

जब इंपोर्ट "टेस्ट" कमांड को बिना किसी गड़बड़ी के चलाया जा सके, तब Google API का इस्तेमाल शुरू किया जा सकता है!

खास जानकारी

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

5. *एपीआई अनुरोधों को अनुमति देना (उपयोगकर्ता की अनुमति)

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

अनुमति के बारे में जानकारी (साथ ही, कुछ पुष्टि करने के तरीके)

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

Google API कई तरह की अनुमतियों के साथ काम करते हैं. हालांकि, G Suite API का इस्तेमाल करने वाले लोगों के लिए, उपयोगकर्ता की अनुमति सबसे आम है. ऐसा इसलिए, क्योंकि इस कोडलैब में मौजूद उदाहरण ऐप्लिकेशन, असली उपयोगकर्ताओं के डेटा को ऐक्सेस करता है. उन उपयोगकर्ताओं को आपके ऐप्लिकेशन को अपना डेटा ऐक्सेस करने की अनुमति देनी होगी. इसका मतलब है कि आपके कोड को उपयोगकर्ता खाते के OAuth2 क्रेडेंशियल पाने होंगे.

उपयोगकर्ता की पुष्टि करने के लिए OAuth2 क्रेडेंशियल पाने के लिए, एपीआई मैनेजर पर वापस जाएं और बाएं नेविगेशन में मौजूद "क्रेडेंशियल" टैब चुनें:

635af008256d323.png

इस पेज पर, आपको अपने सभी क्रेडेंशियल तीन अलग-अलग सेक्शन में दिखेंगे:

fd2f4133b406d572.png

पहला एपीआई कुंजियों के लिए, दूसरा OAuth 2.0 क्लाइंट आईडी के लिए,और तीसरा OAuth2 सेवा खातों के लिए है. हम बीच वाले का इस्तेमाल कर रहे हैं.

क्रेडेंशियल बनाना

क्रेडेंशियल पेज पर, सबसे ऊपर मौजूद + क्रेडेंशियल बनाएं बटन पर क्लिक करें. इसके बाद, आपको एक डायलॉग दिखेगा. इसमें "OAuth क्लाइंट आईडी:" चुनें:

b17b663668e38787.png

अगली स्क्रीन पर, आपके पास दो विकल्प होते हैं: अपने ऐप्लिकेशन की अनुमति के लिए "सहमति स्क्रीन" कॉन्फ़िगर करना और ऐप्लिकेशन का टाइप चुनना:

4e0b967c9d70d262.png

अगर आपने सहमति लेने के लिए स्क्रीन सेट नहीं की है, तो आपको कंसोल में चेतावनी दिखेगी. आपको अब ऐसा करना होगा. (अगर आपने पहले ही सहमति लेने के लिए स्क्रीन सेट अप कर ली है, तो इन चरणों को छोड़ दें.)

"सहमति स्क्रीन कॉन्फ़िगर करें" पर क्लिक करें. यहां आपको "बाहरी" ऐप्लिकेशन (या अगर आप G Suite के ग्राहक हैं, तो "इंटरनल") चुनना होगा:

f17e97b30d994b0c.png

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

b107ab81349bdad2.png

इस समय आपको सिर्फ़ ऐप्लिकेशन के नाम की ज़रूरत है. इसलिए, ऐसा नाम चुनें जो आपके कोडलैब को दिखाता हो. इसके बाद, सेव करें पर क्लिक करें.

OAuth क्लाइंट आईडी बनाना (उपयोगकर्ता खाते की पुष्टि)

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

5ddd365ac0af1e34.png

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

आपके क्रेडेंशियल सेव किए जा रहे हैं

  1. नए क्रेडेंशियल वाला डायलॉग बॉक्स दिखता है; इसे बंद करने के लिए, ठीक है पर क्लिक करें

8bec84d82cb104d7.png

  1. क्रेडेंशियल पेज पर वापस जाएं. इसके बाद, नीचे की ओर स्क्रोल करके "OAuth2 क्लाइंट आईडी" सेक्शन पर जाएं. यहां, आपको अपने नए क्लाइंट आईडी के सबसे दाईं ओर नीचे की ओर, डाउनलोड आइकॉन f54b28417901b3aa.png दिखेगा. इस पर क्लिक करें. 1b4e8d248274a338.png
  2. इससे client_secret-LONG-HASH-STRING.apps.googleusercontent.com.json नाम की फ़ाइल को सेव करने के लिए, एक डायलॉग बॉक्स खुलता है. यह फ़ाइल, आपके डाउनलोड फ़ोल्डर में सेव होती है. हमारा सुझाव है कि आप इसे छोटा करके client_secret.json जैसा कोई आसान नाम दें. यह नाम, सैंपल ऐप्लिकेशन में इस्तेमाल किया गया है. इसके बाद, इसे उस डायरेक्ट्री/फ़ोल्डर में सेव करें जहां आपको इस कोडलैब में सैंपल ऐप्लिकेशन बनाना है.

खास जानकारी

अब इस कोडलैब में इस्तेमाल किए गए Google API को चालू किया जा सकता है. साथ ही, OAuth की सहमति वाली स्क्रीन पर ऐप्लिकेशन के नाम के लिए, हमने "Vision API demo" चुना है. इसलिए, आने वाले समय में कुछ स्क्रीनशॉट में आपको यह नाम दिखेगा.

6. Google API चालू करना

इस कोडलैब में, Google Cloud के चार (4) एपीआई का इस्तेमाल किया गया है. इनमें से दो Google Cloud के हैं (Cloud Storage और Cloud Vision) और दो Google Workspace के हैं (Google Drive और Google Sheets). Google API चालू करने के लिए, यहां सामान्य निर्देश दिए गए हैं. किसी एक एपीआई को चालू करने का तरीका जानने के बाद, अन्य एपीआई को चालू करना भी आसान हो जाता है.

आपको अपने ऐप्लिकेशन में जिस भी Google API का इस्तेमाल करना है उसे चालू करना होगा. एपीआई को कमांड-लाइन या Cloud Console से चालू किया जा सकता है. एपीआई चालू करने की प्रोसेस एक जैसी होती है. इसलिए, एक एपीआई चालू करने के बाद, इसी तरीके से अन्य एपीआई भी चालू किए जा सकते हैं.

पहला विकल्प: gcloud कमांड-लाइन इंटरफ़ेस (Cloud Shell या लोकल एनवायरमेंट)

Cloud Console से एपीआई चालू करना ज़्यादा आम है. हालांकि, कुछ डेवलपर कमांड लाइन से ही सब कुछ करना पसंद करते हैं. इसके लिए, आपको किसी एपीआई का "सेवा का नाम" देखना होगा. यह एक यूआरएल जैसा दिखता है: SERVICE_NAME.googleapis.com. इन्हें एपीआई के साथ काम करने वाले प्रॉडक्ट के चार्ट में देखा जा सकता है. इसके अलावा, Google Discovery API का इस्तेमाल करके, इनके बारे में प्रोग्राम के ज़रिए क्वेरी की जा सकती है.

इस जानकारी के साथ, Cloud Shell का इस्तेमाल करके (या gcloud कमांड-लाइन टूल इंस्टॉल करके अपने लोकल डेवलपमेंट एनवायरमेंट का इस्तेमाल करके), किसी एपीआई या सेवा को चालू किया जा सकता है. इसके लिए, यह तरीका अपनाएं:

gcloud services enable SERVICE_NAME.googleapis.com

पहला उदाहरण: Cloud Vision API को चालू करना

gcloud services enable vision.googleapis.com

दूसरा उदाहरण: Google App Engine सर्वरलेस कंप्यूट प्लैटफ़ॉर्म चालू करना

gcloud services enable appengine.googleapis.com

तीसरा उदाहरण: एक अनुरोध से कई एपीआई चालू करना. उदाहरण के लिए, अगर इस कोडलैब में दर्शकों को Cloud Translation API का इस्तेमाल करके, App Engine, Cloud Functions, और Cloud Run पर कोई ऐप्लिकेशन डिप्लॉय करना है, तो कमांड लाइन यह होगी:

gcloud services enable appengine.googleapis.com cloudfunctions.googleapis.com artifactregistry.googleapis.com run.googleapis.com translate.googleapis.com

इस कमांड से App Engine, Cloud Functions, Cloud Run, और Cloud Translation API चालू हो जाते हैं. इसके अलावा, यह Cloud Artifact Registry को चालू करता है. ऐसा इसलिए, क्योंकि Cloud Run पर डिप्लॉय करने के लिए, Cloud Build सिस्टम को कंटेनर इमेज रजिस्टर करनी होती हैं.

एपीआई को चालू करने के लिए क्वेरी करने या आपके प्रोजेक्ट के लिए पहले से चालू किए गए एपीआई के बारे में जानने के लिए, कुछ कमांड भी उपलब्ध हैं.

चौथा उदाहरण: आपके प्रोजेक्ट के लिए चालू किए जा सकने वाले Google API के बारे में क्वेरी करना

gcloud services list --available --filter="name:googleapis.com"

पांचवां उदाहरण: आपके प्रोजेक्ट के लिए चालू किए गए Google API के लिए क्वेरी

gcloud services list

ऊपर दिए गए निर्देशों के बारे में ज़्यादा जानने के लिए, सेवाएं चालू और बंद करना और सेवाएं दिखाना से जुड़े दस्तावेज़ देखें.

दूसरा विकल्प: Cloud Console

एपीआई मैनेजर में जाकर भी Google API चालू किए जा सकते हैं. Cloud Console में, एपीआई मैनेजर पर जाएं. इस डैशबोर्ड पेज पर, आपको अपने ऐप्लिकेशन के लिए ट्रैफ़िक की कुछ जानकारी दिखेगी. साथ ही, ऐप्लिकेशन के अनुरोधों, आपके ऐप्लिकेशन से जनरेट हुई गड़बड़ियों, और आपके ऐप्लिकेशन के जवाब देने में लगने वाले समय को दिखाने वाले ग्राफ़ भी दिखेंगे:

df4a0a5e00d29ffc.png

इन चार्ट के नीचे, आपके प्रोजेक्ट के लिए चालू किए गए Google API की सूची दी गई है:

5fcf10e5a05cfb97.png

एपीआई चालू (या बंद) करने के लिए, सबसे ऊपर मौजूद एपीआई और सेवाएं चालू करें पर क्लिक करें:

eef4e5e863f4db66.png

इसके अलावा, बाईं ओर मौजूद नेविगेशन बार पर जाएं और एपीआई और सेवाएंलाइब्रेरी चुनें:

6eda5ba145b30b97.png

दोनों ही तरीकों से, आपको एपीआई लाइब्रेरी पेज पर ले जाया जाएगा:

5d4f1c8e7cf8df28.png

मिलते-जुलते नतीजे देखने के लिए, एपीआई का नाम डालें:

35bc4b9cf72ce9a4.png

वह एपीआई चुनें जिसे आपको चालू करना है. इसके बाद, चालू करें बटन पर क्लिक करें:

9574a69ef8d9e8d2.png

सभी एपीआई चालू करने की प्रोसेस एक जैसी होती है. इससे कोई फ़र्क़ नहीं पड़ता कि आपको कौनसा Google API इस्तेमाल करना है.

लागत

कई Google API का इस्तेमाल बिना किसी शुल्क के किया जा सकता है. हालांकि, ज़्यादातर Google Cloud प्रॉडक्ट और एपीआई का इस्तेमाल करने पर शुल्क लगता है. Cloud API चालू करते समय, आपसे चालू बिलिंग खाते के बारे में पूछा जा सकता है. हालांकि, Google Cloud के कुछ प्रॉडक्ट में "हमेशा मुफ़्त" टियर की सुविधा होती है. बिलिंग के शुल्क तब तक नहीं लगते, जब तक आप इस टियर की सीमा से ज़्यादा इस्तेमाल न कर लें.

Google Cloud के नए उपयोगकर्ताओं को मुफ़्त में आज़माने की सुविधा मिलती है. फ़िलहाल, इसके लिए 300 डॉलर का क्रेडिट मिलता है. इसे 90 दिनों के अंदर ही इस्तेमाल किया जा सकता है. आम तौर पर, कोडलैब के लिए ज़्यादा या कोई बिलिंग नहीं होती है. इसलिए, हमारा सुझाव है कि जब तक आप इसे आज़माने के लिए पूरी तरह से तैयार न हों, तब तक बिना किसी शुल्क आज़माने की सुविधा का इस्तेमाल न करें. खास तौर पर, इसलिए क्योंकि यह ऑफ़र सिर्फ़ एक बार मिलता है. फ़्री टियर के कोटे की समयसीमा खत्म नहीं होती है. साथ ही, ये कोटे तब भी लागू होते हैं, जब आपने मुफ़्त में आज़माने की सुविधा का इस्तेमाल न किया हो.

किसी भी एपीआई को चालू करने से पहले, उपयोगकर्ताओं को उसकी कीमत की जानकारी देख लेनी चाहिए. उदाहरण के लिए: Cloud Vision API की कीमत पेज. उन्हें यह भी देख लेना चाहिए कि क्या एपीआई को बिना किसी शुल्क के इस्तेमाल किया जा सकता है. अगर हां, तो इसकी सीमा क्या है. अगर आपने हर दिन या हर महीने के लिए तय की गई सीमा के अंदर एपीआई का इस्तेमाल किया है, तो आपसे कोई शुल्क नहीं लिया जाएगा. Google के प्रॉडक्ट ग्रुप एपीआई के लिए, कीमत और मुफ़्त टियर अलग-अलग होते हैं. उदाहरण:

  • Google Cloud — हर प्रॉडक्ट के लिए अलग-अलग बिलिंग होती है. आम तौर पर, इस्तेमाल के हिसाब से शुल्क लिया जाता है. बिना किसी शुल्क के इस्तेमाल की सुविधा के बारे में ऊपर देखें.
  • Google Maps — इसमें एपीआई का एक सुइट शामिल है. साथ ही, यह उपयोगकर्ताओं को हर महीने 200 डॉलर का मुफ़्त क्रेडिट देता है.
  • Google Workspace (पहले G Suite) के एपीआई — इनका इस्तेमाल, Google Workspace की मासिक सदस्यता के शुल्क में शामिल होता है. हालांकि, इनका इस्तेमाल कुछ सीमाओं तक ही किया जा सकता है. इसलिए, Gmail, Google Drive, Calendar, Docs, Sheets या Slides जैसे ऐप्लिकेशन के लिए एपीआई इस्तेमाल करने पर, सीधे तौर पर बिलिंग नहीं की जाती.

Google के अलग-अलग प्रॉडक्ट के लिए बिलिंग अलग-अलग तरीके से की जाती है. इसलिए, इस बारे में जानकारी पाने के लिए सही दस्तावेज़ देखें.

खास जानकारी

Cloud Vision API चालू होने के बाद, Google Drive, Cloud Storage, और Google Sheets के तीन अन्य एपीआई को भी इसी तरह चालू करें. Cloud Shell से gcloud services enable का इस्तेमाल करें या Cloud Console से:

  1. एपीआई लाइब्रेरी पर वापस जाएं
  2. नाम के कुछ अक्षर टाइप करके खोज शुरू करें
  3. अपनी पसंद का एपीआई चुनें. इसके बाद,
  4. चालू करें

झाग बनाएं, धोएं, और दोहराएं. Cloud Storage के लिए, कई विकल्प उपलब्ध हैं: "Google Cloud Storage JSON API" चुनें. Cloud Storage API को भी चालू बिलिंग खाते की ज़रूरत होगी.

7. सबसे पहले: इंपोर्ट और ऑथराइज़ेशन कोड सेट अप करना

यह कोड का एक मीडियम साइज़ का हिस्सा है. इसलिए, एजाइल तरीकों का इस्तेमाल करने से, मुख्य ऐप्लिकेशन को ठीक करने से पहले, एक सामान्य, स्थिर, और काम करने वाला इन्फ़्रास्ट्रक्चर तैयार करने में मदद मिलती है. दोबारा जांच करें कि आपकी मौजूदा डायरेक्ट्री में client_secret.json उपलब्ध है या नहीं. इसके बाद, स्टार्टअप ipython करें और नीचे दिया गया कोड स्निपेट डालें. इसके अलावा, इसे analyze_gsimg.py में सेव करके शेल से भी चलाया जा सकता है. हमारा सुझाव है कि आप इसे शेल से चलाएं, क्योंकि हम कोड के सैंपल में बदलाव करते रहेंगे:

from __future__ import print_function

from googleapiclient import discovery, http
from httplib2 import Http
from oauth2client import file, client, tools

# process credentials for OAuth2 tokens
SCOPES = 'https://www.googleapis.com/auth/drive.readonly'
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
    creds = tools.run_flow(flow, store)

# create API service endpoints
HTTP = creds.authorize(Http())
DRIVE  = discovery.build('drive',   'v3', http=HTTP)

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

  • print() फ़ंक्शन को इंपोर्ट करने से, यह सैंपल Python 2 और 3 के साथ काम करता है. साथ ही, Google लाइब्रेरी इंपोर्ट करने से, Google API के साथ कम्यूनिकेट करने के लिए ज़रूरी सभी टूल मिल जाते हैं.
  • SCOPES वैरिएबल, उपयोगकर्ता से अनुरोध करने की अनुमतियों को दिखाता है. फ़िलहाल, सिर्फ़ एक अनुमति है: उनके Google Drive से डेटा पढ़ने की अनुमति
  • क्रेडेंशियल प्रोसेस करने वाले कोड का बाकी हिस्सा, कैश मेमोरी में सेव किए गए OAuth2 टोकन को पढ़ता है. अगर ओरिजनल ऐक्सेस टोकन की समयसीमा खत्म हो गई है, तो हो सकता है कि यह रीफ़्रेश टोकन के साथ नए ऐक्सेस टोकन में अपडेट हो जाए.
  • अगर कोई टोकन नहीं बनाया गया है या किसी अन्य वजह से मान्य ऐक्सेस टोकन नहीं मिल सका है, तो उपयोगकर्ता को OAuth2 3-लेग्ड फ़्लो (3LO) का इस्तेमाल करना होगा: अनुरोध की गई अनुमतियों के साथ डायलॉग बनाएं और उपयोगकर्ता को स्वीकार करने के लिए प्रॉम्प्ट करें. अगर ऐसा होता है, तो ऐप्लिकेशन जारी रहता है. अगर ऐसा नहीं होता है, तो tools.run_flow() एक अपवाद दिखाता है और एक्ज़ीक्यूशन रुक जाता है.
  • उपयोगकर्ता से अनुमति मिलने के बाद, सर्वर से कम्यूनिकेट करने के लिए एक एचटीटीपी क्लाइंट बनाया जाता है. साथ ही, सुरक्षा के लिए सभी अनुरोधों पर उपयोगकर्ता के क्रेडेंशियल से हस्ताक्षर किए जाते हैं. इसके बाद, उस एचटीटीपी क्लाइंट की मदद से Google Drive API (वर्शन 3) के लिए एक सेवा एंडपॉइंट बनाया जाता है. इसके बाद, इसे DRIVE को असाइन कर दिया जाता है.

ऐप्लिकेशन चलाना

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

$ python3 ./analyze_gsimg.py
/usr/local/lib/python3.6/site-packages/oauth2client/_helpers.py:255: UserWarning: Cannot access storage.json: No such file or directory
  warnings.warn(_MISSING_FILE_MESSAGE.format(filename))

Your browser has been opened to visit:
    https://accounts.google.com/o/oauth2/auth?client_id=LONG-STRING.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.readonly&access_type=offline&response_type=code

If your browser is on a different machine then exit and re-run this
application with the command-line parameter

  --noauth_local_webserver

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

लोकल डेवलपमेंट एनवायरमेंट से

ब्राउज़र विंडो खुलने पर, कमांड-लाइन स्क्रिप्ट को रोक दिया जाता है. आपको डरावनी दिखने वाली चेतावनी वाला पेज दिख सकता है. यह पेज इस तरह दिखता है:

149241d33871a141.png

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

"'सुरक्षित नहीं है' ऐप्लिकेशन पर जाएं" लिंक पर क्लिक करने के बाद, आपको OAuth2 अनुमतियों वाला एक डायलॉग दिखेगा. यह कुछ इस तरह का होगा—हम अपने यूज़र इंटरफ़ेस को हमेशा बेहतर बनाते रहते हैं. इसलिए, अगर यह डायलॉग बिलकुल ऐसा नहीं दिखता है, तो चिंता न करें:

a122eb7468d0d34e.png

OAuth2 फ़्लो डायलॉग में, डेवलपर की ओर से मांगी गई अनुमतियां दिखती हैं. ये अनुमतियां, SCOPES वैरिएबल के ज़रिए मांगी जाती हैं. इस मामले में, उपयोगकर्ता के Google Drive से फ़ाइलें देखने और डाउनलोड करने की अनुमति दी जाती है. ऐप्लिकेशन कोड में, अनुमति के ये स्कोप यूआरआई के तौर पर दिखते हैं. हालांकि, इन्हें उपयोगकर्ता की स्थानीय भाषा में बदल दिया जाता है. यहां उपयोगकर्ता को, मांगी गई अनुमतियों के लिए साफ़ तौर पर अनुमति देनी होगी. ऐसा न करने पर, एक अपवाद थ्रो किया जाता है, ताकि स्क्रिप्ट आगे न बढ़ सके.

आपको एक और डायलॉग बॉक्स भी दिख सकता है. इसमें आपसे पुष्टि करने के लिए कहा जाएगा:

bf171080dcd6ec5.png

NOTE: कुछ लोग अलग-अलग खातों में लॉग इन करके, एक से ज़्यादा वेब ब्राउज़र का इस्तेमाल करते हैं. इसलिए, हो सकता है कि पुष्टि करने का यह अनुरोध, गलत ब्राउज़र टैब/विंडो पर चला जाए. ऐसे में, आपको इस अनुरोध के लिंक को उस ब्राउज़र में कट-एंड-पेस्ट करना पड़ सकता है जिसमें सही खाते से लॉग इन किया गया है.

Cloud Shell से

Cloud Shell से कोई ब्राउज़र विंडो पॉप-अप नहीं होती है. इस वजह से, आपको समस्या का सामना करना पड़ता है. सबसे नीचे मौजूद डाइग्नोस्टिक मैसेज को समझें:

If your browser is on a different machine then exit and re-run this
application with the command-line parameter

  --noauth_local_webserver

आपको ^C (स्क्रिप्ट को रोकने के लिए Ctrl-C या अन्य कीप्रेस) का इस्तेमाल करना होगा. इसके बाद, अतिरिक्त फ़्लैग के साथ इसे अपने शेल से चलाना होगा. इस तरह से चलाने पर, आपको यह आउटपुट मिलेगा:

$ python3 analyze_gsimg.py --noauth_local_webserver
/usr/local/lib/python3.7/site-packages/oauth2client/_helpers.py:255: UserWarning: Cannot access storage.json: No such file or directory
  warnings.warn(_MISSING_FILE_MESSAGE.format(filename))

Go to the following link in your browser:

    https://accounts.google.com/o/oauth2/auth?client_id=LONG-STRING.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.readonly&access_type=offline&response_type=code

Enter verification code:

(चेतावनी को अनदेखा करें, क्योंकि हमें पता है कि storage.json को अभी तक नहीं बनाया गया है और) उस यूआरएल के साथ किसी अन्य ब्राउज़र टैब में दिए गए निर्देशों का पालन करने पर, आपको स्थानीय डेवलपमेंट एनवायरमेंट के लिए ऊपर बताए गए तरीके के जैसा ही अनुभव मिलेगा. (ऊपर दिए गए स्क्रीनशॉट देखें). आखिर में, एक फ़ाइनल स्क्रीन दिखेगी. इसमें पुष्टि करने के लिए कोड दिया गया होगा. इस कोड को Cloud Shell में डालना होगा:

40a567cda0f31cc9.png

इस कोड को कॉपी करके, टर्मिनल विंडो में चिपकाएं.

खास जानकारी

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

समस्या का हल

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

8. पहला चरण: Google Drive से इमेज डाउनलोड करना

पिछले चरण में, हमने कोड को analyze_gsimg.py के तौर पर बनाने और उसमें बदलाव करने का सुझाव दिया था. सभी कोड को सीधे तौर पर iPython या स्टैंडर्ड Python शेल में कट-एंड-पेस्ट भी किया जा सकता है. हालांकि, यह ज़्यादा मुश्किल है, क्योंकि हम ऐप्लिकेशन को एक-एक करके बनाते रहेंगे.

मान लें कि आपके ऐप्लिकेशन को अनुमति मिल गई है और एपीआई सेवा का एंडपॉइंट बना दिया गया है. आपके कोड में, इसे DRIVE वैरिएबल से दिखाया जाता है. अब Google Drive में मौजूद कोई इमेज फ़ाइल ढूंढें और

इसे NAME नाम के वैरिएबल पर सेट करें. इसके बाद, चरण 0 में दिए गए कोड के ठीक नीचे, यह drive_get_img() फ़ंक्शन डालें:

FILE = 'YOUR_IMG_ON_DRIVE'  # fill-in with name of your Drive file

def drive_get_img(fname):
    'download file from Drive and return file info & binary if found'

    # search for file on Google Drive
    rsp = DRIVE.files().list(q="name='%s'" % fname,
            fields='files(id,name,mimeType,modifiedTime)'
    ).execute().get('files', [])

    # download binary & return file info if found, else return None
    if rsp:
        target = rsp[0]  # use first matching file
        fileId = target['id']
        fname = target['name']
        mtype = target['mimeType']
        binary = DRIVE.files().get_media(fileId=fileId).execute()
        return fname, mtype, target['modifiedTime'], binary

Drive files() कलेक्शन में list() तरीका होता है. यह तरीका, तय की गई फ़ाइल के लिए क्वेरी (q पैरामीटर) करता है. fields पैरामीटर का इस्तेमाल यह तय करने के लिए किया जाता है कि आपको किन रिटर्न वैल्यू में दिलचस्पी है. अगर आपको अन्य वैल्यू से कोई मतलब नहीं है, तो सभी वैल्यू वापस पाने और प्रोसेस को धीमा करने की क्या ज़रूरत है? अगर आपको एपीआई से मिली वैल्यू को फ़िल्टर करने के लिए, फ़ील्ड मास्क के बारे में नहीं पता है, तो यह ब्लॉग पोस्ट और वीडियो देखें. इसके अलावा, क्वेरी को एक्ज़ीक्यूट करें और files एट्रिब्यूट की वैल्यू पाएं. अगर कोई मैच नहीं मिलता है, तो डिफ़ॉल्ट रूप से खाली सूची वाला ऐरे दिखेगा.

अगर कोई नतीजा नहीं मिलता है, तो फ़ंक्शन के बाकी हिस्से को छोड़ दिया जाता है और None (इंप्लिसिट तौर पर) दिखाया जाता है. अगर ऐसा नहीं होता है, तो मैच करने वाले पहले जवाब (rsp[0]) को चुनें. इसके बाद, फ़ाइल का नाम, उसका MIMEtype, पिछली बार बदलाव करने का टाइमस्टैंप, और आखिर में उसका बाइनरी पेलोड दिखाएं. यह पेलोड, get_media() फ़ंक्शन (फ़ाइल आईडी के ज़रिए) से वापस पाया गया है. इसे files() कलेक्शन में भी दिखाएं. (अन्य भाषा की क्लाइंट लाइब्रेरी में, तरीके के नाम थोड़े अलग हो सकते हैं.)

आखिरी हिस्सा "main" बॉडी है, जो पूरे ऐप्लिकेशन को चलाती है:

if __name__ == '__main__':
    # download img file & info from Drive
    rsp = drive_get_img(FILE)
    if rsp:
        fname, mtype, ftime, data = rsp
        print('Downloaded %r (%s, %s, size: %d)' % (fname, mtype, ftime, len(data)))
    else:
        print('ERROR: Cannot download %r from Drive' % fname)

मान लें कि Drive पर section-work-card-img_2x.jpg नाम की कोई इमेज है और उसे FILE पर सेट किया गया है. स्क्रिप्ट के सही तरीके से चलने पर, आपको ऐसा आउटपुट दिखेगा जिससे पुष्टि होती है कि स्क्रिप्ट, Drive से फ़ाइल को पढ़ सकती है. हालांकि, यह फ़ाइल आपके कंप्यूटर पर सेव नहीं की गई है:

$ python3 analyze_gsimg.py
Downloaded 'section-work-card-img_2x.jpg' (image/jpeg, 2020-02-27T09:27:22.095Z, size: 27781)

समस्या का हल

अगर आपको ऊपर दिए गए उदाहरण जैसा नतीजा नहीं मिलता है, तो इसकी एक या उससे ज़्यादा वजहें हो सकती हैं. शायद इसकी वजह यह हो:

खास जानकारी

इस सेक्शन में, आपने यह सीखा कि किसी फ़ाइल के लिए क्वेरी करने और उसे डाउनलोड करने के लिए, Drive API से कैसे कनेक्ट किया जाता है. इसके लिए, दो अलग-अलग एपीआई कॉल किए जाते हैं. कारोबार के लिए इस्तेमाल का उदाहरण: अपने Drive डेटा को संग्रहित करना और शायद उसका विश्लेषण करना. जैसे, Google Cloud टूल का इस्तेमाल करके. इस चरण में आपके ऐप्लिकेशन का कोड, इस repo मेंstep1-drive/analyze_gsimg.py मौजूद कोड से मेल खाना चाहिए.

Google Drive पर फ़ाइलें डाउनलोड करने के बारे में ज़्यादा जानने के लिए, यहां जाएं या यह ब्लॉग पोस्ट और वीडियो देखें. इस कोडलैब का यह हिस्सा, Google Workspace API के बारे में जानकारी देने वाले कोडलैब के लगभग एक जैसा है. इसमें फ़ाइल डाउनलोड करने के बजाय, उपयोगकर्ता के Google Drive में मौजूद पहली 100 फ़ाइलें/फ़ोल्डर दिखाए जाते हैं. साथ ही, इसमें ज़्यादा पाबंदियों वाला स्कोप इस्तेमाल किया जाता है.

9. दूसरा चरण: फ़ाइल को Cloud Storage में संग्रहित करना

अगले चरण में, Google Cloud Storage के लिए सहायता जोड़ें. इसके लिए, हमें एक और Python पैकेज, io इंपोर्ट करना होगा. पक्का करें कि इंपोर्ट किए गए डेटा का सबसे ऊपर वाला सेक्शन अब ऐसा दिखता हो:

from __future__ import print_function                   
import io

हमें Drive में मौजूद फ़ाइल के नाम के साथ-साथ, यह जानकारी भी चाहिए कि इस फ़ाइल को Cloud Storage में कहां सेव करना है. खास तौर पर, हमें उस "बकेट" का नाम चाहिए जिसमें आपको इसे सेव करना है. साथ ही, हमें "पैरंट फ़ोल्डर" के प्रीफ़िक्स की जानकारी भी चाहिए. इस बारे में यहां ज़्यादा जानें:

FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = ''     # YOUR IMG FILE PREFIX                  

बकेट के बारे में जानकारी: Cloud Storage, अमॉर्फ़स ब्लब स्टोरेज उपलब्ध कराता है. Google Drive की तरह, यह फ़ाइल टाइप, एक्सटेंशन वगैरह के कॉन्सेप्ट को नहीं समझता. Cloud Storage के लिए, ये सिर्फ़ "ब्लॉब" होते हैं. इसके अलावा, Cloud Storage में फ़ोल्डर या सबडायरेक्ट्री का कोई कॉन्सेप्ट नहीं है.

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

ऊपर दिए गए पहले चरण में, Drive के लिए रीड ओनली स्कोप का अनुरोध किया गया था. उस समय, आपको सिर्फ़ इसी जानकारी की ज़रूरत थी. अब, Cloud Storage में अपलोड करने (पढ़ने और लिखने) की अनुमति ज़रूरी है. SCOPES को एक स्ट्रिंग वैरिएबल से बदलकर, अनुमति के स्कोप की एक श्रेणी (Python टपल [या सूची]) में बदलें, ताकि यह इस तरह दिखे:

SCOPES = (
    'https://www.googleapis.com/auth/drive.readonly',
    'https://www.googleapis.com/auth/devstorage.full_control',
)                  

अब Drive के लिए बनाए गए सर्विस एंडपॉइंट के ठीक नीचे, Cloud Storage के लिए एक सर्विस एंडपॉइंट बनाएं. ध्यान दें कि हमने कॉल में थोड़ा बदलाव किया है, ताकि एक ही एचटीटीपी क्लाइंट ऑब्जेक्ट का फिर से इस्तेमाल किया जा सके. ऐसा इसलिए, क्योंकि जब इसे शेयर किए गए संसाधन के तौर पर इस्तेमाल किया जा सकता है, तो नया ऑब्जेक्ट बनाने की कोई ज़रूरत नहीं है.

# create API service endpoints
HTTP = creds.authorize(Http())
DRIVE  = discovery.build('drive',   'v3', http=HTTP)
GCS    = discovery.build('storage', 'v1', http=HTTP)                  

अब इस फ़ंक्शन को (drive_get_img() के बाद) जोड़ें. यह फ़ंक्शन, Cloud Storage में अपलोड करता है:

def gcs_blob_upload(fname, bucket, media, mimetype):
    'upload an object to a Google Cloud Storage bucket'

    # build blob metadata and upload via GCS API
    body = {'name': fname, 'uploadType': 'multipart', 'contentType': mimetype}
    return GCS.objects().insert(bucket=bucket, body=body,
            media_body=http.MediaIoBaseUpload(io.BytesIO(media), mimetype),
            fields='bucket,name').execute()

objects.().insert() कॉल के लिए, बकेट का नाम, फ़ाइल का मेटाडेटा, और बाइनरी ब्लॉब की ज़रूरत होती है. fields वैरिएबल, एपीआई से मिले सिर्फ़ बकेट और ऑब्जेक्ट के नामों का अनुरोध करता है, ताकि रिटर्न वैल्यू को फ़िल्टर किया जा सके. एपीआई से डेटा पढ़ने के अनुरोधों पर इन फ़ील्ड मास्क के बारे में ज़्यादा जानने के लिए, यह पोस्ट और वीडियो देखें.

अब gcs_blob_upload() को मुख्य ऐप्लिकेशन में इंटिग्रेट करें:

        # upload file to GCS
        gcsname = '%s/%s'% (PARENT, fname)
        rsp = gcs_blob_upload(gcsname, BUCKET, data, mtype)
        if rsp:
            print('Uploaded %r to GCS bucket %r' % (rsp['name'], rsp['bucket']))
        else:
            print('ERROR: Cannot upload %r to Cloud Storage' % gcsname)

gcsname वैरिएबल, फ़ाइल के नाम के साथ जोड़े गए "पैरंट सबडायरेक्ट्री" के नाम को मर्ज करता है. साथ ही, बकेट के नाम के साथ प्रीफ़िक्स करने पर, ऐसा लगता है कि फ़ाइल को "/bucket/parent.../filename" पर संग्रहित किया जा रहा है. इस चंक को else क्लॉज़ के ठीक ऊपर, पहले print() फ़ंक्शन के बाद रखें, ताकि पूरा "main" ऐसा दिखे:

if __name__ == '__main__':
    # download img file & info from Drive
    rsp = drive_get_img(FILE)
    if rsp:
        fname, mtype, ftime, data = rsp
        print('Downloaded %r (%s, %s, size: %d)' % (fname, mtype, ftime, len(data)))

        # upload file to GCS
        gcsname = '%s/%s'% (PARENT, fname)
        rsp = gcs_blob_upload(gcsname, BUCKET, data, mtype)
        if rsp:
            print('Uploaded %r to GCS bucket %r' % (rsp['name'], rsp['bucket']))
        else:
            print('ERROR: Cannot upload %r to Cloud Storage' % gcsname)
    else:
        print('ERROR: Cannot download %r from Drive' % fname)

मान लीजिए कि हमने "vision-demo" नाम का एक बकेट बनाया है और "analyzed_imgs" को "पैरंट सबडाइरेक्ट्री" के तौर पर सेट किया है. उन वैरिएबल को सेट करने और स्क्रिप्ट को फिर से चलाने पर, section-work-card-img_2x.jpg को Drive से डाउनलोड किया जाएगा. इसके बाद, इसे Cloud Storage पर अपलोड किया जाएगा, है न? नहीं!

$ python3 analyze_gsimg.py 
Downloaded 'section-work-card-img_2x.jpg' (image/jpeg, 2020-02-27T09:27:22.095Z, size: 27781)
Traceback (most recent call last):
  File "analyze_gsimg.py", line 85, in <module>
    io.BytesIO(data), mimetype=mtype), mtype)
  File "analyze_gsimg.py", line 72, in gcs_blob_upload
    media_body=media, fields='bucket,name').execute()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/googleapiclient/_helpers.py", line 134, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/googleapiclient/http.py", line 898, in execute
    raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://storage.googleapis.com/upload/storage/v1/b/PROJECT_ID/o?fields=bucket%2Cname&alt=json&uploadType=multipart returned "Insufficient Permission">

ध्यान से देखें, Drive में डाउनलोड करने की प्रोसेस पूरी हो गई है, लेकिन Cloud Storage में अपलोड करने की प्रोसेस पूरी नहीं हुई है. क्यों?

इसकी वजह यह है कि हमने पहले चरण में इस ऐप्लिकेशन को अनुमति देते समय, Google Drive को सिर्फ़ पढ़ने का ऐक्सेस दिया था. हमने Cloud Storage के लिए, पढ़ने और लिखने का स्कोप जोड़ा है. हालांकि, हमने कभी भी उपयोगकर्ता से उस ऐक्सेस की अनुमति नहीं मांगी. इसे काम करने के लिए, हमें storage.json फ़ाइल को मिटाना होगा. इसमें यह स्कोप मौजूद नहीं है. इसके बाद, इसे फिर से चलाना होगा.

फिर से अनुमति देने के बाद (इसकी पुष्टि करने के लिए, storage.json में जाकर देखें और वहां दोनों स्कोप देखें), आपको उम्मीद के मुताबिक आउटपुट मिलेगा:

$ python3 analyze_gsimg.py

    . . .

Authentication successful.
Downloaded 'section-work-card-img_2x.jpg' (image/jpeg, 2020-02-27T09:27:22.095Z, size: 27781)
Uploaded 'analyzed_imgs/section-work-card-img_2x.jpg' to GCS bucket 'vision-demo'

खास जानकारी

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

डेवलपर हमसे समय-समय पर यह सवाल पूछते हैं कि Google Drive और Cloud Storage, दोनों क्यों मौजूद हैं. आखिरकार, क्या ये दोनों क्लाउड में फ़ाइलें सेव करने की सुविधा नहीं देते हैं? इसलिए, हमने यह वीडियो बनाया है. इस चरण में आपका कोड, repo में मौजूद कोडstep2-gcs/analyze_gsimg.py से मेल खाना चाहिए.

10. तीसरा चरण: Cloud Vision की मदद से विश्लेषण करना

अब हमें पता है कि Google Cloud और Google Workspace के बीच डेटा ट्रांसफ़र किया जा सकता है. हालांकि, हमने अब तक कोई विश्लेषण नहीं किया है. इसलिए, इमेज को Cloud Vision पर भेजें, ताकि लेबल एनोटेशन यानी ऑब्जेक्ट का पता लगाया जा सके. इसके लिए, हमें डेटा को Base64-encode करना होगा. इसका मतलब है कि हमें एक और Python मॉड्यूल, base64 की ज़रूरत होगी. पक्का करें कि अब आपका टॉप इंपोर्ट सेक्शन ऐसा दिखता हो:

from __future__ import print_function
import base64
import io

डिफ़ॉल्ट रूप से, Vision API को मिले सभी लेबल दिखाता है. चीज़ों को एक जैसा रखने के लिए, सिर्फ़ टॉप 5 की जानकारी का अनुरोध करते हैं. हालांकि, उपयोगकर्ता इसे अपनी ज़रूरत के हिसाब से बदल सकता है. इसके लिए, हम कॉन्स्टेंट वैरिएबल TOP का इस्तेमाल करेंगे. इसे अन्य सभी कॉन्स्टेंट के नीचे जोड़ें:

FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = ''   # YOUR IMG FILE PREFIX 
TOP = 5       # TOP # of VISION LABELS TO SAVE                 

पिछले चरणों की तरह, हमें एक और अनुमति के दायरे की ज़रूरत है. इस बार, यह Vision API के लिए है. इसकी स्ट्रिंग का इस्तेमाल करके, SCOPES को अपडेट करें:

SCOPES = (
    'https://www.googleapis.com/auth/drive.readonly',
    'https://www.googleapis.com/auth/devstorage.full_control',
    'https://www.googleapis.com/auth/cloud-vision',
)                  

अब Cloud Vision के लिए एक सेवा एंडपॉइंट बनाएं, ताकि यह अन्य सेवाओं के साथ इस तरह से काम कर सके:

# create API service endpoints
HTTP = creds.authorize(Http())
DRIVE  = discovery.build('drive',   'v3', http=HTTP)
GCS    = discovery.build('storage', 'v1', http=HTTP)
VISION = discovery.build('vision',  'v1', http=HTTP)

अब यह फ़ंक्शन जोड़ें, जो इमेज पेलोड को Cloud Vision पर भेजता है:

def vision_label_img(img, top):
    'send image to Vision API for label annotation'

    # build image metadata and call Vision API to process
    body = {'requests': [{
                'image':     {'content': img},
                'features': [{'type': 'LABEL_DETECTION', 'maxResults': top}],
    }]}
    rsp = VISION.images().annotate(body=body).execute().get('responses', [{}])[0]

    # return top labels for image as CSV for Sheet (row)
    if 'labelAnnotations' in rsp:
        return ', '.join('(%.2f%%) %s' % (
                label['score']*100., label['description']) \
                for label in rsp['labelAnnotations'])

images().annotate() कॉल के लिए, डेटा के साथ-साथ एपीआई की ज़रूरी सुविधाओं की भी ज़रूरत होती है. टॉप 5 लेबल की सीमा भी पेलोड का हिस्सा है. हालांकि, यह ज़रूरी नहीं है. अगर कॉल पूरा होता है, तो पेलोड में ऑब्जेक्ट के टॉप 5 लेबल के साथ-साथ, कॉन्फ़िडेंस स्कोर भी दिखता है. इससे पता चलता है कि इमेज में कोई ऑब्जेक्ट मौजूद है या नहीं. (अगर कोई जवाब नहीं मिलता है, तो एक खाली Python डिक्शनरी असाइन करें, ताकि नीचे दिया गया if स्टेटमेंट काम करे.) यह फ़ंक्शन, उस डेटा को CSV स्ट्रिंग में इकट्ठा करता है, ताकि हम उसे अपनी रिपोर्ट में इस्तेमाल कर सकें.

vision_label_img() को कॉल करने वाली इन पांच लाइनों को, Cloud Storage पर अपलोड करने के बाद तुरंत रखा जाना चाहिए:

            # process w/Vision
            rsp = vision_label_img(base64.b64encode(data).decode('utf-8'), TOP)
            if rsp:
                print('Top %d labels from Vision API: %s' % (TOP, rsp))
            else:
                print('ERROR: Vision API cannot analyze %r' % fname)

इसके बाद, मुख्य ड्राइवर कुछ ऐसा दिखेगा:

if __name__ == '__main__':
    # download img file & info from Drive
    rsp = drive_get_img(FILE)
    if rsp:
        fname, mtype, ftime, data = rsp
        print('Downloaded %r (%s, %s, size: %d)' % (fname, mtype, ftime, len(data)))

        # upload file to GCS
        gcsname = '%s/%s'% (PARENT, fname)
        rsp = gcs_blob_upload(gcsname, BUCKET, data, mtype)
        if rsp:
            print('Uploaded %r to GCS bucket %r' % (rsp['name'], rsp['bucket']))

            # process w/Vision
            rsp = vision_label_img(base64.b64encode(data).decode('utf-8'), TOP)
            if rsp:
                print('Top %d labels from Vision API: %s' % (TOP, rsp))
            else:
                print('ERROR: Vision API cannot analyze %r' % fname)
        else:
            print('ERROR: Cannot upload %r to Cloud Storage' % gcsname)
    else:
        print('ERROR: Cannot download %r from Drive' % fname)

स्कोप को रीफ़्रेश करने के लिए storage.json को मिटाएं. इसके बाद, अपडेट किए गए ऐप्लिकेशन को फिर से चलाएं. इससे आपको कुछ इस तरह का आउटपुट मिलेगा. इसमें Cloud Vision के विश्लेषण को जोड़ा गया है:

$ python3 analyze_gsimg.py

    . . .

Authentication successful.
Downloaded 'section-work-card-img_2x.jpg' (image/jpeg, 2020-02-27T09:27:22.095Z, size: 27781)
Uploaded 'analyzed_imgs/section-work-card-img_2x.jpg' to GCS bucket 'vision-demo'
Top 5 labels from Vision API: (89.94%) Sitting, (86.09%) Interior design, (82.08%) Furniture, (81.52%) Table, (80.85%) Room

खास जानकारी

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

अगर आप डेवलपर हैं और एपीआई को कॉल कर सकते हैं, तो मशीन लर्निंग का इस्तेमाल किया जा सकता है. Cloud Vision, एपीआई की उन सेवाओं में से एक है जिनका इस्तेमाल करके अपने डेटा का विश्लेषण किया जा सकता है. अन्य के बारे में यहां जानें. आपका कोड अब repo में मौजूद कोडstep3-vision/analyze_gsimg.py से मेल खाना चाहिए.

11. चौथा चरण: Google Sheets की मदद से रिपोर्ट जनरेट करना

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

Google Sheets API के लिए, किसी और इंपोर्ट की ज़रूरत नहीं होती. साथ ही, सिर्फ़ एक नई जानकारी की ज़रूरत होती है. यह जानकारी, पहले से फ़ॉर्मैट की गई और डेटा की नई लाइन का इंतज़ार कर रही मौजूदा स्प्रेडशीट का फ़ाइल आईडी होती है. इसलिए, SHEET कॉन्स्टेंट का इस्तेमाल किया जाता है. हमारा सुझाव है कि आप ऐसी नई स्प्रेडशीट बनाएं जो यहां दी गई स्प्रेडशीट की तरह दिखती हो:

4def78583d05300.png

उस स्प्रैडशीट का यूआरएल कुछ ऐसा दिखेगा: https://docs.google.com/spreadsheets/d/FILE_ID/edit. उस FILE_ID को चुनें और उसे SHEET के लिए स्टिंग के तौर पर असाइन करें.

हमने k_ize() नाम का एक छोटा फ़ंक्शन भी जोड़ा है. यह फ़ंक्शन बाइट को किलोबाइट में बदलता है. हमने इसे Python lambda के तौर पर तय किया है, क्योंकि यह एक लाइन का आसान फ़ंक्शन है. अन्य कॉन्स्टेंट के साथ इंटिग्रेट किए गए ये दोनों कॉन्स्टेंट, इस तरह दिखते हैं:

k_ize =  lambda b: '%6.2fK' % (b/1000.)  # bytes to kBs
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = ''     # YOUR IMG FILE PREFIX
SHEET = 'YOUR_SHEET_ID'
TOP = 5       # TOP # of VISION LABELS TO SAVE                 

पिछले चरणों की तरह, हमें एक और अनुमति के दायरे की ज़रूरत है. इस बार, Sheets API के लिए पढ़ने और लिखने की अनुमति. SCOPES के पास अब ये चारों ज़रूरी चीज़ें हैं:

SCOPES = (
    'https://www.googleapis.com/auth/drive.readonly',
    'https://www.googleapis.com/auth/devstorage.full_control',
    'https://www.googleapis.com/auth/cloud-vision',
    'https://www.googleapis.com/auth/spreadsheets',
)                  

अब Google Sheets के लिए, अन्य एंडपॉइंट के पास एक सेवा एंडपॉइंट बनाएं, ताकि यह ऐसा दिखे:

# create API service endpoints
HTTP = creds.authorize(Http())
DRIVE  = discovery.build('drive',   'v3', http=HTTP)
GCS    = discovery.build('storage', 'v1', http=HTTP)
VISION = discovery.build('vision',  'v1', http=HTTP)
SHEETS = discovery.build('sheets',  'v4', http=HTTP)

sheet_append_row() का फ़ंक्शन आसान है: डेटा की एक लाइन और शीट का आईडी लें. इसके बाद, उस लाइन को उस शीट में जोड़ें:

def sheet_append_row(sheet, row):
    'append row to a Google Sheet, return #cells added'

    # call Sheets API to write row to Sheet (via its ID)
    rsp = SHEETS.spreadsheets().values().append(
            spreadsheetId=sheet, range='Sheet1',
            valueInputOption='USER_ENTERED', body={'values': [row]}
    ).execute()
    if rsp:
        return rsp.get('updates').get('updatedCells')

spreadsheets().values().append() कॉल के लिए, शीट के फ़ाइल आईडी, सेल की रेंज, डेटा को कैसे डाला जाना चाहिए, और डेटा की ज़रूरत होती है. फ़ाइल आईडी साफ़ तौर पर दिया गया है. साथ ही, सेल की रेंज को A1 नोटेशन में दिया गया है. "Sheet1" का मतलब पूरी शीट है. इससे एपीआई को यह सिग्नल मिलता है कि वह शीट में मौजूद सभी डेटा के बाद पंक्ति को जोड़े. डेटा को शीट में कैसे जोड़ा जाना चाहिए, इसके लिए दो विकल्प हैं: "RAW" (स्ट्रिंग डेटा को हूबहू वैसे ही डालें) या "USER_ENTERED" (डेटा को इस तरह लिखें जैसे किसी उपयोगकर्ता ने Google Sheets ऐप्लिकेशन में अपने कीबोर्ड से डाला हो. इससे सेल फ़ॉर्मैटिंग की सभी सुविधाएं बनी रहेंगी).

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

                # push results to Sheet, get cells-saved count
                fsize = k_ize(len(data))
                row = [PARENT,
                        '=HYPERLINK("storage.cloud.google.com/%s/%s", "%s")' % (
                        BUCKET, gcsname, fname), mtype, ftime, fsize, rsp
                ]
                rsp = sheet_append_row(SHEET, row)
                if rsp:
                    print('Updated %d cells in Google Sheet' % rsp)
                else:
                    print('ERROR: Cannot write row to Google Sheets')

Google शीट में ऐसे कॉलम होते हैं जो डेटा को दिखाते हैं. जैसे, कोई पैरंट "सबडायरेक्ट्री", Cloud Storage पर संग्रहित की गई फ़ाइल की जगह (बकेट + फ़ाइल का नाम), फ़ाइल का MIMEtype, फ़ाइल का साइज़ (मूल रूप से बाइट में, लेकिन k_ize() के साथ किलोबाइट में बदल दिया गया है), और Cloud Vision के लेबल स्ट्रिंग. यह भी ध्यान दें कि संग्रह की गई जगह एक हाइपरलिंक है, ताकि आपका मैनेजर इस पर क्लिक करके पुष्टि कर सके कि इसका सुरक्षित तरीके से बैक अप लिया गया है.

Cloud Vision से मिले नतीजों को दिखाने के ठीक बाद, ऊपर दिए गए कोड का ब्लॉक जोड़ने पर, ऐप्लिकेशन को चलाने वाला मुख्य हिस्सा अब पूरा हो गया है. हालांकि, यह स्ट्रक्चर के हिसाब से थोड़ा मुश्किल है:

if __name__ == '__main__':
    # download img file & info from Drive
    rsp = drive_get_img(FILE)
    if rsp:
        fname, mtype, ftime, data = rsp
        print('Downloaded %r (%s, %s, size: %d)' % (fname, mtype, ftime, len(data)))

        # upload file to GCS
        gcsname = '%s/%s'% (PARENT, fname)
        rsp = gcs_blob_upload(gcsname, BUCKET, data, mtype)
        if rsp:
            print('Uploaded %r to GCS bucket %r' % (rsp['name'], rsp['bucket']))

            # process w/Vision
            rsp = vision_label_img(base64.b64encode(data).decode('utf-8'))
            if rsp:
                print('Top %d labels from Vision API: %s' % (TOP, rsp))

                # push results to Sheet, get cells-saved count
                fsize = k_ize(len(data))
                row = [PARENT,
                        '=HYPERLINK("storage.cloud.google.com/%s/%s", "%s")' % (
                        BUCKET, gcsname, fname), mtype, ftime, fsize, rsp
                ]
                rsp = sheet_append_row(SHEET, row)
                if rsp:
                    print('Updated %d cells in Google Sheet' % rsp)
                else:
                    print('ERROR: Cannot write row to Google Sheets')
            else:
                print('ERROR: Vision API cannot analyze %r' % fname)
        else:
            print('ERROR: Cannot upload %r to Cloud Storage' % gcsname)
    else:
        print('ERROR: Cannot download %r from Drive' % fname)

storage.json को आखिरी बार मिटाने और अपडेट किए गए ऐप्लिकेशन को फिर से चलाने पर, आपको कुछ इस तरह का आउटपुट दिखेगा. इसमें Cloud Vision के विश्लेषण को शामिल किया गया है:

$ python3 analyze_gsimg.py

    . . .

Authentication successful.
Downloaded 'section-work-card-img_2x.jpg' (image/jpeg, 2020-02-27T09:27:22.095Z, size: 27781)
Uploaded 'analyzed_imgs/section-work-card-img_2x.jpg' to GCS bucket 'vision-demo'
Top 5 labels from Vision API: (89.94%) Sitting, (86.09%) Interior design, (82.08%) Furniture, (81.52%) Table, (80.85%) Room
Updated 6 cells in Google Sheet

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

b53a5bc944734652.png

खास जानकारी

इस ट्यूटोरियल के पहले तीन चरणों में, आपने डेटा को ट्रांसफ़र करने और उसका विश्लेषण करने के लिए, Google Workspace और Google Cloud API से कनेक्ट किया. यह कुल काम का 80% है. हालांकि, दिन के आखिर में इन सभी बातों का कोई मतलब नहीं रह जाता, अगर आपने मैनेजमेंट को अपनी उपलब्धियों के बारे में नहीं बताया. नतीजों को बेहतर तरीके से दिखाने के लिए, जनरेट की गई रिपोर्ट में सभी नतीजों की खास जानकारी दी जाती है.

विश्लेषण को और ज़्यादा काम का बनाने के लिए, नतीजों को स्प्रेडशीट में लिखने के साथ-साथ, हर इमेज के लिए टॉप 5 लेबल को इंडेक्स किया जा सकता है. इससे एक इंटरनल डेटाबेस बनाया जा सकता है. इससे अनुमति वाले कर्मचारी, खोज टीम के ज़रिए इमेज के लिए क्वेरी कर सकते हैं. हालांकि, हम इसे पढ़ने वालों के लिए एक टास्क के तौर पर छोड़ देते हैं.

फ़िलहाल, हमारे नतीजे एक शीट में हैं और मैनेजमेंट के लिए उपलब्ध हैं. इस चरण में आपके ऐप्लिकेशन का कोड, इस repo मेंstep4-sheets/analyze_gsimg.py मौजूद कोड से मेल खाना चाहिए. आखिरी चरण में, कोड को ठीक किया जाता है और उसे इस्तेमाल की जा सकने वाली स्क्रिप्ट में बदला जाता है.

12. *आखिरी चरण: कोड को फिर से व्यवस्थित करना

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

from __future__ import print_function
import argparse
import base64
import io
import webbrowser

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

DEBUG = False

अब मुख्य हिस्से के बारे में जानें. इस सैंपल को बनाते समय, आपको "असुविधा" महसूस होनी चाहिए, क्योंकि हमारा कोड हर सेवा के साथ नेस्टिंग का एक और लेवल जोड़ता है. अगर आपको ऐसा लगता है, तो आप अकेले नहीं हैं. इसकी वजह यह है कि इससे कोड की जटिलता बढ़ जाती है. इसके बारे में Google Testing Blog की इस पोस्ट में बताया गया है.

इस सबसे सही तरीके को अपनाकर, ऐप्लिकेशन के मुख्य हिस्से को एक फ़ंक्शन में बदलते हैं. साथ ही, नेस्ट करने के बजाय (किसी भी चरण के पूरा न होने पर None और सभी चरणों के पूरा होने पर True दिखाना), हर "ब्रेक पॉइंट" पर return दिखाते हैं:

def main(fname, bucket, sheet_id, folder, top, debug):
    '"main()" drives process from image download through report generation'

    # download img file & info from Drive
    rsp = drive_get_img(fname)
    if not rsp:
        return
    fname, mtype, ftime, data = rsp
    if debug:
        print('Downloaded %r (%s, %s, size: %d)' % (fname, mtype, ftime, len(data)))

    # upload file to GCS
    gcsname = '%s/%s'% (folder, fname)
    rsp = gcs_blob_upload(gcsname, bucket, data, mtype)
    if not rsp:
        return
    if debug:
        print('Uploaded %r to GCS bucket %r' % (rsp['name'], rsp['bucket']))

    # process w/Vision
    rsp = vision_label_img(base64.b64encode(data).decode('utf-8'))
    if not rsp:
        return
    if debug:
        print('Top %d labels from Vision API: %s' % (top, rsp))

    # push results to Sheet, get cells-saved count
    fsize = k_ize(len(data))
    row = [folder,
            '=HYPERLINK("storage.cloud.google.com/%s/%s", "%s")' % (
            bucket, gcsname, fname), mtype, ftime, fsize, rsp
    ]
    rsp = sheet_append_row(sheet_id, row)
    if not rsp:
        return
    if debug:
        print('Added %d cells to Google Sheet' % rsp)
    return True

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

if __name__ == '__main__':
    # args: [-hv] [-i imgfile] [-b bucket] [-f folder] [-s Sheet ID] [-t top labels]
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--imgfile", action="store_true",
            default=FILE, help="image file filename")
    parser.add_argument("-b", "--bucket_id", action="store_true",
            default=BUCKET, help="Google Cloud Storage bucket name")
    parser.add_argument("-f", "--folder", action="store_true",
            default=PARENT, help="Google Cloud Storage image folder")
    parser.add_argument("-s", "--sheet_id", action="store_true",
            default=SHEET, help="Google Sheet Drive file ID (44-char str)")
    parser.add_argument("-t", "--viz_top", action="store_true",
            default=TOP, help="return top N (default %d) Vision API labels" % TOP)
    parser.add_argument("-v", "--verbose", action="store_true",
            default=DEBUG, help="verbose display output")
    args = parser.parse_args()

    print('Processing file %r... please wait' % args.imgfile)
    rsp = main(args.imgfile, args.bucket_id,
            args.sheet_id, args.folder, args.viz_top, args.verbose)
    if rsp:
        sheet_url = 'https://docs.google.com/spreadsheets/d/%s/edit' % args.sheet_id
        print('DONE: opening web browser to it, or see %s' % sheet_url)
        webbrowser.open(sheet_url, new=1, autoraise=True)
    else:
        print('ERROR: could not process %r' % args.imgfile)

अगर सभी चरण पूरे हो जाते हैं, तो स्क्रिप्ट उस स्प्रेडशीट के लिए वेब ब्राउज़र लॉन्च करती है जिसमें नई डेटा लाइन जोड़ी गई थी.

खास जानकारी

स्कोप में कोई बदलाव नहीं हुआ है. इसलिए, storage.json को मिटाने की ज़रूरत नहीं है. अपडेट किए गए ऐप्लिकेशन को फिर से चलाने पर, बदली गई शीट के लिए एक नई ब्राउज़र विंडो खुलती है. इसमें आउटपुट की कम लाइनें दिखती हैं. साथ ही, -h विकल्प जारी करने पर, उपयोगकर्ताओं को उनके विकल्प दिखते हैं. इनमें -v विकल्प भी शामिल है. इसकी मदद से, उपयोगकर्ता आउटपुट की उन लाइनों को वापस ला सकते हैं जिन्हें पहले छिपा दिया गया था:

$ python3 analyze_gsimg.py
Processing file 'section-work-card-img_2x.jpg'... please wait
DONE: opening web browser to it, or see https://docs.google.com/spreadsheets/d/SHEET_ID/edit

$ python3 analyze_gsimg.py -h
usage: analyze_gsimg.py [-h] [-i] [-t] [-f] [-b] [-s] [-v]

optional arguments:
  -h, --help       show this help message and exit
  -i, --imgfile    image file filename
  -t, --viz_top    return top N (default 5) Vision API labels
  -f, --folder     Google Cloud Storage image folder
  -b, --bucket_id  Google Cloud Storage bucket name
  -s, --sheet_id   Google Sheet Drive file ID (44-char str)
  -v, --verbose    verbose display output

अन्य विकल्पों की मदद से, उपयोगकर्ता Drive की फ़ाइलों के अलग-अलग नाम, Cloud Storage के "सबडायरेक्ट्री" और बकेट के नाम, Cloud Vision से मिले टॉप "N" नतीजे, और स्प्रेडशीट (Sheets) के फ़ाइल आईडी चुन सकते हैं. इन आखिरी अपडेट के बाद, आपके कोड का फ़ाइनल वर्शन, final/analyze_gsimg.pyपर मौजूद रेपो और यहां दिए गए कोड से पूरी तरह मेल खाना चाहिए:

'''
analyze_gsimg.py - analyze Google Workspace image processing workflow

Download image from Google Drive, archive to Google Cloud Storage, send
to Google Cloud Vision for processing, add results row to Google Sheet.
'''

from __future__ import print_function
import argparse
import base64
import io
import webbrowser

from googleapiclient import discovery, http
from httplib2 import Http
from oauth2client import file, client, tools

k_ize = lambda b: '%6.2fK' % (b/1000.) # bytes to kBs
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = ''     # YOUR IMG FILE PREFIX
SHEET = 'YOUR_SHEET_ID'
TOP = 5       # TOP # of VISION LABELS TO SAVE
DEBUG = False

# process credentials for OAuth2 tokens
SCOPES = (
    'https://www.googleapis.com/auth/drive.readonly',
    'https://www.googleapis.com/auth/devstorage.full_control',
    'https://www.googleapis.com/auth/cloud-vision',
    'https://www.googleapis.com/auth/spreadsheets',
)
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
    creds = tools.run_flow(flow, store)

# create API service endpoints
HTTP = creds.authorize(Http())
DRIVE  = discovery.build('drive',   'v3', http=HTTP)
GCS    = discovery.build('storage', 'v1', http=HTTP)
VISION = discovery.build('vision',  'v1', http=HTTP)
SHEETS = discovery.build('sheets',  'v4', http=HTTP)


def drive_get_img(fname):
    'download file from Drive and return file info & binary if found'

    # search for file on Google Drive
    rsp = DRIVE.files().list(q="name='%s'" % fname,
            fields='files(id,name,mimeType,modifiedTime)'
    ).execute().get('files', [])

    # download binary & return file info if found, else return None
    if rsp:
        target = rsp[0]  # use first matching file
        fileId = target['id']
        fname = target['name']
        mtype = target['mimeType']
        binary = DRIVE.files().get_media(fileId=fileId).execute()
        return fname, mtype, target['modifiedTime'], binary


def gcs_blob_upload(fname, bucket, media, mimetype):
    'upload an object to a Google Cloud Storage bucket'

    # build blob metadata and upload via GCS API
    body = {'name': fname, 'uploadType': 'multipart', 'contentType': mimetype}
    return GCS.objects().insert(bucket=bucket, body=body,
            media_body=http.MediaIoBaseUpload(io.BytesIO(media), mimetype),
            fields='bucket,name').execute()


def vision_label_img(img, top):
    'send image to Vision API for label annotation'

    # build image metadata and call Vision API to process
    body = {'requests': [{
                'image':     {'content': img},
                'features': [{'type': 'LABEL_DETECTION', 'maxResults': top}],
    }]}
    rsp = VISION.images().annotate(body=body).execute().get('responses', [{}])[0]

    # return top labels for image as CSV for Sheet (row)
    if 'labelAnnotations' in rsp:
        return ', '.join('(%.2f%%) %s' % (
                label['score']*100., label['description']) \
                for label in rsp['labelAnnotations'])


def sheet_append_row(sheet, row):
    'append row to a Google Sheet, return #cells added'

    # call Sheets API to write row to Sheet (via its ID)
    rsp = SHEETS.spreadsheets().values().append(
            spreadsheetId=sheet, range='Sheet1',
            valueInputOption='USER_ENTERED', body={'values': [row]}
    ).execute()
    if rsp:
        return rsp.get('updates').get('updatedCells')


def main(fname, bucket, sheet_id, folder, top, debug):
    '"main()" drives process from image download through report generation'

    # download img file & info from Drive
    rsp = drive_get_img(fname)
    if not rsp:
        return
    fname, mtype, ftime, data = rsp
    if debug:
        print('Downloaded %r (%s, %s, size: %d)' % (fname, mtype, ftime, len(data)))

    # upload file to GCS
    gcsname = '%s/%s'% (folder, fname)
    rsp = gcs_blob_upload(gcsname, bucket, data, mtype)
    if not rsp:
        return
    if debug:
        print('Uploaded %r to GCS bucket %r' % (rsp['name'], rsp['bucket']))

    # process w/Vision
    rsp = vision_label_img(base64.b64encode(data).decode('utf-8'), top)
    if not rsp:
        return
    if debug:
        print('Top %d labels from Vision API: %s' % (top, rsp))

    # push results to Sheet, get cells-saved count
    fsize = k_ize(len(data))
    row = [folder,
            '=HYPERLINK("storage.cloud.google.com/%s/%s", "%s")' % (
            bucket, gcsname, fname), mtype, ftime, fsize, rsp
    ]
    rsp = sheet_append_row(sheet_id, row)
    if not rsp:
        return
    if debug:
        print('Added %d cells to Google Sheet' % rsp)
    return True


if __name__ == '__main__':
    # args: [-hv] [-i imgfile] [-b bucket] [-f folder] [-s Sheet ID] [-t top labels]
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--imgfile", action="store_true",
            default=FILE, help="image file filename")
    parser.add_argument("-b", "--bucket_id", action="store_true",
            default=BUCKET, help="Google Cloud Storage bucket name")
    parser.add_argument("-f", "--folder", action="store_true",
            default=PARENT, help="Google Cloud Storage image folder")
    parser.add_argument("-s", "--sheet_id", action="store_true",
            default=SHEET, help="Google Sheet Drive file ID (44-char str)")
    parser.add_argument("-t", "--viz_top", action="store_true",
            default=TOP, help="return top N (default %d) Vision API labels" % TOP)
    parser.add_argument("-v", "--verbose", action="store_true",
            default=DEBUG, help="verbose display output")
    args = parser.parse_args()

    print('Processing file %r... please wait' % args.imgfile)
    rsp = main(args.imgfile, args.bucket_id,
            args.sheet_id, args.folder, args.viz_top, args.verbose)
    if rsp:
        sheet_url = 'https://docs.google.com/spreadsheets/d/%s/edit' % args.sheet_id
        print('DONE: opening web browser to it, or see %s' % sheet_url)
        webbrowser.open(sheet_url, new=1, autoraise=True)
    else:
        print('ERROR: could not process %r' % args.imgfile)

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

13. बधाई हो!

इस कोडलैब में काफ़ी कुछ सीखने को मिला. आपने इसे पूरा करके, सबसे लंबे कोडलैब में से एक को पूरा कर लिया है. इस वजह से, आपने एंटरप्राइज़ के लिए उपलब्ध एक संभावित समाधान को ~130 लाइनों के Python कोड की मदद से हल किया. इसके लिए, आपने Google Cloud और Google Workspace की सभी सुविधाओं का इस्तेमाल किया. साथ ही, डेटा को एक से दूसरी जगह ले जाकर, काम करने वाला समाधान तैयार किया. इस ऐप्लिकेशन के सभी वर्शन के लिए, ओपन सोर्स रेपो को एक्सप्लोर करें. इसके बारे में ज़्यादा जानकारी यहां दी गई है.

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

  1. Google Cloud API का इस्तेमाल करने के लिए शुल्क देना पड़ता है. वहीं, Google Workspace API के लिए, आपको Google Workspace की सदस्यता का मासिक शुल्क देना होता है. हालांकि, Gmail का इस्तेमाल करने वाले लोगों को इसके लिए कोई शुल्क नहीं देना पड़ता. इसलिए, Google Workspace का इस्तेमाल करने वाले लोगों को एपीआई बंद करने या हटाने की ज़रूरत नहीं है. Google Cloud के लिए, Cloud Console के डैशबोर्ड पर जाएं. इसके बाद, अनुमानित शुल्क देखने के लिए, बिलिंग "कार्ड" पर जाएं.
  2. Cloud Vision के लिए, आपको हर महीने तय संख्या में एपीआई कॉल करने की अनुमति होती है. इसके लिए, आपसे कोई शुल्क नहीं लिया जाता. इसलिए, जब तक आप इन सीमाओं के अंदर हैं, तब तक आपको कुछ भी बंद करने की ज़रूरत नहीं है. साथ ही, आपको अपना प्रोजेक्ट बंद/मिटाने की भी ज़रूरत नहीं है. Vision API की बिलिंग और मुफ़्त कोटे के बारे में ज़्यादा जानकारी, इसके कीमत वाले पेज पर देखी जा सकती है.
  3. Cloud Storage के कुछ उपयोगकर्ताओं को हर महीने बिना किसी शुल्क के स्टोरेज मिलता है. अगर इस कोडलैब का इस्तेमाल करके, इमेज को संग्रहित करने से आपका कोटा खत्म नहीं होता है, तो आपसे कोई शुल्क नहीं लिया जाएगा. GCS की बिलिंग और मुफ़्त कोटे के बारे में ज़्यादा जानकारी के लिए, इसके कीमत वाले पेज पर जाएं. Cloud Storage ब्राउज़र में जाकर, आसानी से ब्लॉब देखे और मिटाए जा सकते हैं.
  4. Google Drive के इस्तेमाल के लिए भी स्टोरेज कोटा तय किया जा सकता है. अगर आपने इस कोडलैब में बनाया गया टूल इस्तेमाल करके, उन इमेज को Cloud Storage में संग्रहित किया है, तो Drive में आपके पास ज़्यादा स्टोरेज होगा. Google Drive के स्टोरेज के बारे में ज़्यादा जानकारी, Google Workspace Basic के उपयोगकर्ताओं या Gmail/उपभोक्ता के उपयोगकर्ताओं के लिए, कीमत की जानकारी देने वाले पेज पर देखी जा सकती है.

ज़्यादातर Google Workspace Business और Enterprise प्लान में असीमित स्टोरेज मिलता है. हालांकि, इससे आपके Drive फ़ोल्डर में बहुत ज़्यादा फ़ाइलें हो सकती हैं और/या वे व्यवस्थित नहीं दिख सकती हैं. इस ट्यूटोरियल में बनाया गया ऐप्लिकेशन, काम की नहीं रही फ़ाइलों को संग्रहित करने और अपने Google Drive को व्यवस्थित करने का एक बेहतरीन तरीका है.

अन्य वर्शन

इस ट्यूटोरियल में, final/analyze_gsimg.py को "आखिरी" आधिकारिक वर्शन के तौर पर इस्तेमाल किया जा रहा है. हालांकि, यह आखिरी वर्शन नहीं है. ऐप्लिकेशन के फ़ाइनल वर्शन में एक समस्या यह है कि इसमें पुष्टि करने वाली पुरानी लाइब्रेरी का इस्तेमाल किया गया है. इन लाइब्रेरी की सेवा बंद कर दी गई है. हमने यह तरीका इसलिए चुना, क्योंकि इस दस्तावेज़ को लिखते समय, नई ऑथराइज़ेशन लाइब्रेरी में कई ज़रूरी एलिमेंट काम नहीं करते थे. जैसे, OAuth टोकन स्टोरेज मैनेजमेंट और थ्रेड सुरक्षा.

मौजूदा (नई) पुष्टि करने वाली लाइब्रेरी

हालांकि, कुछ समय बाद पुराने वर्शन की पुष्टि करने वाली लाइब्रेरी काम नहीं करेंगी. इसलिए, हम आपको उन वर्शन की समीक्षा करने का सुझाव देते हैं जो repo के alt फ़ोल्डर में, पुष्टि करने वाली नई (मौजूदा) लाइब्रेरी का इस्तेमाल करते हैं. भले ही, वे थ्रेडसेफ़ न हों. हालांकि, आपके पास थ्रेडसेफ़ लाइब्रेरी बनाने का विकल्प होता है. ऐसी फ़ाइलें ढूंढें जिनके नाम में *newauth* मौजूद हो.

Google Cloud प्रॉडक्ट की क्लाइंट लाइब्रेरी

Google Cloud का सुझाव है कि Google Cloud API का इस्तेमाल करते समय, सभी डेवलपर को प्रॉडक्ट क्लाइंट लाइब्रेरी का इस्तेमाल करना चाहिए. माफ़ करें, फ़िलहाल Google Cloud के अलावा अन्य एपीआई के लिए ऐसी लाइब्रेरी उपलब्ध नहीं हैं. लोअर-लेवल लाइब्रेरी का इस्तेमाल करने से, एपीआई का लगातार इस्तेमाल किया जा सकता है. साथ ही, इससे कोड को बेहतर तरीके से पढ़ा जा सकता है. ऊपर दी गई सलाह की तरह ही, Google Cloud प्रॉडक्ट क्लाइंट लाइब्रेरी का इस्तेमाल करने वाले वैकल्पिक वर्शन, repo के alt फ़ोल्डर में उपलब्ध हैं. इन्हें देखा जा सकता है. ऐसी फ़ाइलें ढूंढें जिनके नाम में *-gcp* मौजूद हो.

सेवा खाते की अनुमति

पूरी तरह से क्लाउड पर काम करने के दौरान, आम तौर पर न तो इंसानों का डेटा होता है और न ही (इंसानों) उपयोगकर्ताओं का डेटा होता है. इसलिए, Google Cloud के साथ मुख्य रूप से सेवा खातों और सेवा खाते की अनुमति का इस्तेमाल किया जाता है. हालांकि, Google Workspace के दस्तावेज़ों का मालिकाना हक आम तौर पर (मानव) उपयोगकर्ताओं के पास होता है. इसलिए, इस ट्यूटोरियल में उपयोगकर्ता खाते के लिए अनुमति देने की सुविधा का इस्तेमाल किया गया है. इसका मतलब यह नहीं है कि सेवा खातों के साथ Google Workspace API का इस्तेमाल नहीं किया जा सकता. अगर उन खातों के पास सही ऐक्सेस लेवल है, तो उनका इस्तेमाल ऐप्लिकेशन में किया जा सकता है. ऊपर दिए गए उदाहरण की तरह ही, सेवा खाते की पुष्टि करने की सुविधा का इस्तेमाल करने वाले वैकल्पिक वर्शन, repo के alt फ़ोल्डर में उपलब्ध हैं. इन्हें देखा जा सकता है. ऐसी फ़ाइलें ढूंढें जिनके नाम में *-svc* मौजूद हो.

अन्य वर्शन का कैटलॉग

नीचे, आपको final/analyze_gsimg.py के सभी वैकल्पिक वर्शन मिलेंगे. इनमें से हर वर्शन में, ऊपर दी गई एक या उससे ज़्यादा प्रॉपर्टी मौजूद हैं. हर वर्शन के फ़ाइल नाम में, यह जानकारी देखें:

  • final/analyze_gsimg.py के अलावा, पुराने वर्शन की पुष्टि करने वाली लाइब्रेरी का इस्तेमाल करने वाले वर्शन के लिए "oldauth"
  • मौजूदा/नई ऑथराइज़ेशन लाइब्रेरी का इस्तेमाल करने वालों के लिए "newauth"
  • "gcp" उन लोगों के लिए जो Google Cloud प्रॉडक्ट की क्लाइंट लाइब्रेरी का इस्तेमाल करते हैं. जैसे, google-cloud-storage वगैरह.
  • उपयोगकर्ता खाते के बजाय सेवा खाते ("svc acct") के ऑथराइज़ेशन का इस्तेमाल करने वाले लोगों के लिए "svc"

यहां सभी वर्शन दिए गए हैं:

फ़ाइल नाम

ब्यौरा

final/analyze_gsimg.py

प्राइमरी सैंपल; इसमें पुराने वर्शन की पुष्टि करने वाली लाइब्रेरी का इस्तेमाल किया जाता है

alt/analyze_gsimg-newauth.py

यह final/analyze_gsimg.py फ़ील्ड की तरह ही होता है, लेकिन इसमें नई ऑथराइज़ेशन लाइब्रेरी का इस्तेमाल किया जाता है

alt/analyze_gsimg-oldauth-gcp.py

यह final/analyze_gsimg.py जैसा ही है, लेकिन इसमें Google Cloud प्रॉडक्ट की क्लाइंट लाइब्रेरी का इस्तेमाल किया जाता है

alt/analyze_gsimg-newauth-gcp.py

यह alt/analyze_gsimg-newauth.py जैसा ही है, लेकिन इसमें Google Cloud प्रॉडक्ट की क्लाइंट लाइब्रेरी का इस्तेमाल किया जाता है

alt/analyze_gsimg-oldauth-svc.py

यह final/analyze_gsimg.py जैसा ही है, लेकिन इसमें उपयोगकर्ता खाते के बजाय सेवा खाते का इस्तेमाल किया जाता है

alt/analyze_gsimg-newauth-svc.py

यह alt/analyze_gsimg-newauth.py जैसा ही है, लेकिन इसमें उपयोगकर्ता खाते के बजाय सेवा खाते के ऑथराइज़ेशन का इस्तेमाल किया जाता है

alt/analyze_gsimg-oldauth-svc-gcp.py

यह alt/analyze_gsimg-oldauth-svc.py के जैसा ही है, लेकिन इसमें Google Cloud प्रॉडक्ट की क्लाइंट लाइब्रेरी का इस्तेमाल किया जाता है. यह alt/analyze_gsimg-oldauth-gcp.py के जैसा ही है, लेकिन इसमें उपयोगकर्ता खाते के बजाय सेवा खाते के ऑथराइज़ेशन का इस्तेमाल किया जाता है

alt/analyze_gsimg-newauth-svc-gcp.py

यह alt/analyze_gsimg-oldauth-svc-gcp.py फ़ील्ड की तरह ही होता है, लेकिन इसमें नई ऑथराइज़ेशन लाइब्रेरी का इस्तेमाल किया जाता है

ओरिजनल final/analyze_gsimg.py के साथ, आपके पास फ़ाइनल समाधान के सभी संभावित कॉम्बिनेशन होते हैं. इससे कोई फ़र्क़ नहीं पड़ता कि आपका Google API डेवलपमेंट एनवायरमेंट कौनसा है. साथ ही, आपके पास अपनी ज़रूरतों के हिसाब से कोई भी कॉम्बिनेशन चुनने का विकल्प होता है. इसी तरह की जानकारी के लिए, alt/README.md भी देखें.

अन्य स्टडी

इस गतिविधि को एक या दो चरणों में आगे बढ़ाने के कुछ सुझाव यहां दिए गए हैं. मौजूदा समाधान से हल की जा सकने वाली समस्याओं को बढ़ाया जा सकता है. इससे आपको ये सुधार करने में मदद मिलेगी:

  1. (फ़ोल्डर में मौजूद कई इमेज) मान लें कि आपको एक इमेज के बजाय, Google Drive के फ़ोल्डर में मौजूद इमेज प्रोसेस करनी हैं.
  2. (ZIP फ़ाइलों में कई इमेज) इमेज के फ़ोल्डर के बजाय, इमेज फ़ाइलों वाले ZIP संग्रह कैसे रहेंगे? अगर Python का इस्तेमाल किया जा रहा है, तो zipfile मॉड्यूल का इस्तेमाल करें.
  3. (Vision लेबल का विश्लेषण करें) मिलती-जुलती इमेज को एक साथ क्लस्टर करें. इसके लिए, सबसे ज़्यादा इस्तेमाल किए जाने वाले लेबल से शुरुआत करें. इसके बाद, दूसरे सबसे ज़्यादा इस्तेमाल किए जाने वाले लेबल और इसी तरह आगे बढ़ें.
  4. (चार्ट बनाएं) फ़ॉलो-अप #3, Vision API के विश्लेषण और कैटगरी के आधार पर, Sheets API की मदद से चार्ट जनरेट करें
  5. (दस्तावेज़ों को कैटगरी में बांटना) मान लें कि आपको Cloud Vision API की मदद से इमेज का विश्लेषण नहीं करना है. इसके बजाय, आपको Cloud Natural Language API की मदद से PDF फ़ाइलों को कैटगरी में बांटना है. ऊपर दिए गए समाधानों का इस्तेमाल करके, इन PDF को Drive के फ़ोल्डर या Drive पर ZIP संग्रहों में रखा जा सकता है.
  6. (प्रज़ेंटेशन बनाना) Google Sheets की रिपोर्ट के कॉन्टेंट से स्लाइड डेक जनरेट करने के लिए, Slides API का इस्तेमाल करें. स्प्रेडशीट के डेटा से स्लाइड जनरेट करने के बारे में जानने के लिए, यह ब्लॉग पोस्ट और वीडियो देखें.
  7. (PDF के तौर पर एक्सपोर्ट करें) स्प्रेडशीट और/या स्लाइड डेक को PDF के तौर पर एक्सपोर्ट करें. हालांकि, यह सुविधा Sheets और Slides, दोनों के एपीआई में उपलब्ध नहीं है. अहम जानकारी: Google Drive API. ज़्यादा क्रेडिट पाने के लिए: Ghostscript (Linux, Windows) या Combine PDF Pages.action (Mac OS X) जैसे टूल का इस्तेमाल करके, Sheets और Slides के दोनों PDF को एक मास्टर PDF में मर्ज करें.

ज़्यादा जानें

कोडलैब

सामान्य

Google Workspace

Google Cloud

लाइसेंस

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