১. সংক্ষিপ্ত বিবরণ
এই কোডল্যাবটি একটি সম্ভাব্য এন্টারপ্রাইজ ওয়ার্কফ্লো কল্পনা করে: ইমেজ আর্কাইভ করা, বিশ্লেষণ এবং রিপোর্ট তৈরি করা। কল্পনা করুন, আপনার প্রতিষ্ঠানে একাধিক ইমেজ একটি সীমিত রিসোর্সে জায়গা দখল করে আছে। আপনি সেই ডেটা আর্কাইভ করতে, সেই ইমেজগুলো বিশ্লেষণ করতে এবং সবচেয়ে গুরুত্বপূর্ণভাবে, আর্কাইভ করা লোকেশন ও বিশ্লেষণের ফলাফলগুলোর সারসংক্ষেপ করে একটি রিপোর্ট তৈরি করতে চান, যা ম্যানেজমেন্টের ব্যবহারের জন্য সংকলিত ও প্রস্তুত থাকবে। গুগল ক্লাউড তার দুটি প্রোডাক্ট লাইন—গুগল ওয়ার্কস্পেস (পূর্বে জি স্যুট বা গুগল অ্যাপস) এবং গুগল ক্লাউড (পূর্বে জিসিপি)—এর এপিআই ব্যবহার করে এই কাজটি করার জন্য প্রয়োজনীয় টুলস সরবরাহ করে।
আমাদের ক্ষেত্রে, ব্যবসায়িক ব্যবহারকারীর গুগল ড্রাইভে ছবি থাকবে। সেগুলোকে গুগল ক্লাউড স্টোরেজের মতো আরও নিরাপদ ও সাশ্রয়ী স্টোরেজে ব্যাক আপ করে রাখা যুক্তিযুক্ত। গুগল ক্লাউড ভিশন ডেভেলপারদের অ্যাপ্লিকেশনগুলিতে সহজেই ভিশন ডিটেকশন ফিচার যুক্ত করার সুযোগ দেয়, যার মধ্যে রয়েছে অবজেক্ট ও ল্যান্ডমার্ক ডিটেকশন, অপটিক্যাল ক্যারেক্টার রিকগনিশন (OCR) ইত্যাদি। সবশেষে, আপনার বসের কাছে এই সবকিছু সংক্ষিপ্ত আকারে তুলে ধরার জন্য গুগল শিটস স্প্রেডশিট একটি দরকারি ভিজ্যুয়ালাইজেশন টুল।
গুগল ক্লাউডের সম্পূর্ণ সুবিধা কাজে লাগিয়ে একটি সমাধান তৈরির এই কোডল্যাবটি সম্পন্ন করার পর, আমরা আশা করি আপনি আপনার প্রতিষ্ঠান বা গ্রাহকদের জন্য আরও বেশি কার্যকর কিছু তৈরি করতে অনুপ্রাণিত হবেন।
আপনি যা শিখবেন
- ক্লাউড শেল কীভাবে ব্যবহার করবেন
- এপিআই অনুরোধগুলি কীভাবে প্রমাণীকরণ করবেন
- পাইথনের জন্য গুগল এপিআই ক্লায়েন্ট লাইব্রেরি কীভাবে ইনস্টল করবেন
- কীভাবে গুগল এপিআই সক্রিয় করবেন
- গুগল ড্রাইভ থেকে কীভাবে ফাইল ডাউনলোড করবেন
- ক্লাউড স্টোরেজে অবজেক্ট/ব্লব কীভাবে আপলোড করবেন
- ক্লাউড ভিশন দিয়ে ডেটা বিশ্লেষণ করার পদ্ধতি
- গুগল শিটসে কীভাবে সারি লিখতে হয়
আপনার যা যা লাগবে
- একটি গুগল অ্যাকাউন্ট (গুগল ওয়ার্কস্পেস অ্যাকাউন্টের জন্য প্রশাসকের অনুমোদনের প্রয়োজন হতে পারে)
- একটি সক্রিয় গুগল ক্লাউড বিলিং অ্যাকাউন্ট সহ একটি গুগল ক্লাউড প্রজেক্ট
- অপারেটিং সিস্টেম টার্মিনাল/শেল কমান্ডের সাথে পরিচিতি
- পাইথনে প্রাথমিক দক্ষতা (২ বা ৩) থাকতে হবে, তবে আপনি যেকোনো সমর্থিত ভাষা ব্যবহার করতে পারেন।
উপরে তালিকাভুক্ত চারটি গুগল ক্লাউড প্রোডাক্টের সাথে অভিজ্ঞতা থাকলে সহায়ক হবে, তবে তা আবশ্যক নয়। যদি আপনার হাতে সময় থাকে এবং আপনি প্রথমে আলাদাভাবে সেগুলোর সাথে পরিচিত হতে চান, তাহলে এখানকার অনুশীলনটি শুরু করার আগে আপনি প্রতিটির কোডল্যাব করতে পারেন।
- গুগল ড্রাইভ (গুগল ওয়ার্কস্পেস এপিআই ব্যবহার করে) পরিচিতি (পাইথন)
- পাইথনের সাথে ক্লাউড ভিশন ব্যবহার (পাইথন)
- শীটস এপিআই (জেএস/নোড) ব্যবহার করে কাস্টমাইজড রিপোর্টিং টুল তৈরি করুন
- গুগল ক্লাউড স্টোরেজে অবজেক্ট আপলোড করুন (কোনো কোডিংয়ের প্রয়োজন নেই)
জরিপ
আপনি এই টিউটোরিয়ালটি কীভাবে ব্যবহার করবেন?
পাইথন নিয়ে আপনার অভিজ্ঞতাকে আপনি কীভাবে মূল্যায়ন করবেন?
গুগল ক্লাউড পরিষেবা ব্যবহারের অভিজ্ঞতাকে আপনি কীভাবে মূল্যায়ন করবেন?
গুগল ওয়ার্কস্পেস ডেভেলপার পরিষেবা ব্যবহারের অভিজ্ঞতাকে আপনি কীভাবে মূল্যায়ন করবেন?
আপনি কি প্রোডাক্ট ফিচার পরিচিতিমূলক কোডল্যাবের চেয়ে আরও বেশি "ব্যবসা-কেন্দ্রিক" কোডল্যাব দেখতে চান?
২. সেটআপ এবং প্রয়োজনীয়তা
স্ব-গতিতে পরিবেশ সেটআপ
- Google Cloud Console- এ সাইন-ইন করুন এবং একটি নতুন প্রজেক্ট তৈরি করুন অথবা বিদ্যমান কোনো প্রজেক্ট পুনরায় ব্যবহার করুন। যদি আপনার আগে থেকে Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তবে আপনাকে অবশ্যই একটি তৈরি করতে হবে।



- প্রজেক্টের নামটি হলো এই প্রজেক্টের অংশগ্রহণকারীদের প্রদর্শিত নাম। এটি একটি ক্যারেক্টার স্ট্রিং যা গুগল এপিআই ব্যবহার করে না। আপনি যেকোনো সময় এটি আপডেট করতে পারেন।
- সমস্ত গুগল ক্লাউড প্রজেক্ট জুড়ে প্রজেক্ট আইডি অবশ্যই অনন্য হতে হবে এবং এটি অপরিবর্তনীয় (একবার সেট করার পর পরিবর্তন করা যাবে না)। ক্লাউড কনসোল স্বয়ংক্রিয়ভাবে একটি অনন্য স্ট্রিং তৈরি করে; সাধারণত এটি কী তা নিয়ে আপনার মাথা ঘামানোর দরকার নেই। বেশিরভাগ কোডল্যাবে, আপনাকে প্রজেক্ট আইডি উল্লেখ করতে হবে (এটি সাধারণত
PROJECT_IDহিসাবে চিহ্নিত করা হয়)। তৈরি করা আইডিটি আপনার পছন্দ না হলে, আপনি এলোমেলোভাবে আরেকটি তৈরি করতে পারেন। বিকল্পভাবে, আপনি নিজের আইডি দিয়ে চেষ্টা করে দেখতে পারেন যে সেটি উপলব্ধ আছে কিনা। এই ধাপের পরে এটি পরিবর্তন করা যাবে না এবং প্রজেক্টের পুরো সময়কাল জুড়ে এটি অপরিবর্তিত থাকবে। - আপনার অবগতির জন্য জানাচ্ছি যে, তৃতীয় একটি ভ্যালু রয়েছে, যা হলো প্রজেক্ট নাম্বার এবং কিছু এপিআই এটি ব্যবহার করে। ডকুমেন্টেশনে এই তিনটি ভ্যালু সম্পর্কে আরও বিস্তারিত জানুন।
- এরপর, ক্লাউড রিসোর্স/এপিআই ব্যবহার করার জন্য আপনাকে ক্লাউড কনসোলে বিলিং চালু করতে হবে। এই কোডল্যাবটি সম্পন্ন করতে খুব বেশি খরচ হওয়ার কথা নয়, এমনকি আদৌ কোনো খরচ নাও হতে পারে। এই টিউটোরিয়ালের পর যাতে কোনো বিলিং না হয়, সেজন্য রিসোর্সগুলো বন্ধ করতে আপনি আপনার তৈরি করা রিসোর্সগুলো অথবা পুরো প্রজেক্টটিই ডিলিট করে দিতে পারেন। গুগল ক্লাউডের নতুন ব্যবহারকারীরা ৩০০ মার্কিন ডলারের ফ্রি ট্রায়াল প্রোগ্রামের জন্য যোগ্য।
ক্লাউড শেল শুরু করুন
সারসংক্ষেপ
যদিও আপনি আপনার ল্যাপটপে স্থানীয়ভাবে কোড তৈরি করতে পারেন, এই কোডল্যাবের একটি দ্বিতীয় উদ্দেশ্য হলো আপনাকে গুগল ক্লাউড শেল ব্যবহার করতে শেখানো, যা আপনার আধুনিক ওয়েব ব্রাউজারের মাধ্যমে ক্লাউডে চালিত একটি কমান্ড-লাইন পরিবেশ।
ক্লাউড শেল সক্রিয় করুন
- ক্লাউড কনসোল থেকে, Activate Cloud Shell-এ ক্লিক করুন।
.

আপনি যদি আগে কখনো ক্লাউড শেল চালু না করে থাকেন, তাহলে এটি কী তা বর্ণনা করে একটি মধ্যবর্তী স্ক্রিন (নিচে দেওয়া আছে) আপনার সামনে আসবে। যদি তাই হয়, তাহলে 'Continue'-তে ক্লিক করুন (এবং আপনি এটি আর কখনো দেখতে পাবেন না)। একবারের জন্য আসা সেই স্ক্রিনটি দেখতে এইরকম:

ক্লাউড শেল প্রস্তুত করতে এবং এর সাথে সংযোগ স্থাপন করতে মাত্র কয়েক মুহূর্ত সময় লাগা উচিত।

এই ভার্চুয়াল মেশিনটিতে আপনার প্রয়োজনীয় সমস্ত ডেভেলপমেন্ট টুলস লোড করা আছে। এটি একটি স্থায়ী ৫ জিবি হোম ডিরেক্টরি প্রদান করে এবং গুগল ক্লাউডে চলে, যা নেটওয়ার্ক পারফরম্যান্স ও অথেনটিকেশনকে ব্যাপকভাবে উন্নত করে। এই কোডল্যাবে আপনার প্রায় সমস্ত কাজই শুধুমাত্র একটি ব্রাউজার বা আপনার ক্রোমবুক দিয়ে করা সম্ভব।
ক্লাউড শেলে সংযুক্ত হওয়ার পর আপনি দেখতে পাবেন যে, আপনাকে ইতিমধ্যেই প্রমাণীকৃত করা হয়েছে এবং প্রজেক্টটি আপনার প্রজেক্ট আইডিতে সেট করা আছে।
- আপনি প্রমাণীকৃত কিনা তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:
gcloud auth list
কমান্ড আউটপুট
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- gcloud কমান্ডটি আপনার প্রজেক্ট সম্পর্কে জানে কিনা তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:
gcloud config list project
কমান্ড আউটপুট
[core] project = <PROJECT_ID>
যদি তা না থাকে, তবে আপনি এই কমান্ডটি দিয়ে এটি সেট করতে পারেন:
gcloud config set project <PROJECT_ID>
কমান্ড আউটপুট
Updated property [core/project].
৩. পাইথন পরিবেশ নিশ্চিত করুন
এই কোডল্যাবটির জন্য আপনাকে পাইথন ভাষা ব্যবহার করতে হবে (যদিও গুগল এপিআই ক্লায়েন্ট লাইব্রেরিগুলো অনেক ভাষাই সমর্থন করে , তাই আপনি আপনার পছন্দের ডেভেলপমেন্ট টুলে এর সমতুল্য কিছু তৈরি করে নিতে পারেন এবং পাইথন কোডটিকে শুধু সিউডোকোড হিসেবে ব্যবহার করতে পারেন)। বিশেষত, এই কোডল্যাবটি পাইথন ২ এবং ৩ সমর্থন করে, কিন্তু আমরা যত তাড়াতাড়ি সম্ভব ৩.x সংস্করণে আপগ্রেড করার পরামর্শ দিই।
ক্লাউড শেল হলো একটি সুবিধাজনক টুল যা ব্যবহারকারীরা সরাসরি ক্লাউড কনসোল থেকে ব্যবহার করতে পারেন এবং এর জন্য কোনো লোকাল ডেভেলপমেন্ট এনভায়রনমেন্টের প্রয়োজন হয় না, তাই এই টিউটোরিয়ালটি একটি ওয়েব ব্রাউজার ব্যবহার করে সম্পূর্ণ ক্লাউডেই করা সম্ভব। আরও নির্দিষ্টভাবে বললে, এই কোডল্যাবটির জন্য ক্লাউড শেলে পাইথনের উভয় সংস্করণই আগে থেকে ইনস্টল করা আছে।
ক্লাউড শেলে আইপাইথনও ইনস্টল করা আছে: এটি একটি উচ্চ-স্তরের ইন্টারেক্টিভ পাইথন ইন্টারপ্রেটার যা আমরা সুপারিশ করি, বিশেষ করে যদি আপনি ডেটা সায়েন্স বা মেশিন লার্নিং কমিউনিটির অংশ হন। সেক্ষেত্রে, আইপাইথন হলো জুপিটার নোটবুক এবং সেইসাথে গুগল রিসার্চ দ্বারা হোস্ট করা কোলাব জুপিটার নোটবুকগুলোর ডিফল্ট ইন্টারপ্রেটার।
IPython প্রথমে পাইথন ৩ ইন্টারপ্রেটার ব্যবহার করতে পছন্দ করে, কিন্তু ৩.x সংস্করণটি উপলব্ধ না থাকলে এটি পাইথন ২-এ ফিরে যায়। ক্লাউড শেল থেকে IPython ব্যবহার করা যায়, তবে এটি একটি স্থানীয় ডেভেলপমেন্ট এনভায়রনমেন্টেও ইনস্টল করা যেতে পারে। ^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 আপনার পছন্দ না হয়, তবে একটি স্ট্যান্ডার্ড পাইথন ইন্টারেক্টিভ ইন্টারপ্রেটার (ক্লাউড শেল অথবা আপনার লোকাল ডেভেলপমেন্ট এনভায়রনমেন্ট) ব্যবহার করা সম্পূর্ণ গ্রহণযোগ্য (এছাড়াও ^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 ইনস্টলেশন টুল (পাইথন প্যাকেজ ম্যানেজার এবং ডিপেন্ডেন্সি রিজলভার) আছে বলে ধরে নেওয়া হচ্ছে। এটি ২.৭.৯+ বা ৩.৪+ ভার্সনের সাথে বান্ডেল হিসেবে আসে। আপনার কাছে যদি এর চেয়ে পুরোনো কোনো পাইথন ভার্সন থাকে, তবে ইনস্টলেশনের নির্দেশাবলীর জন্য এই গাইডটি দেখুন। আপনার পারমিশনের ওপর নির্ভর করে, আপনার sudo বা superuser অ্যাক্সেসের প্রয়োজন হতে পারে, তবে সাধারণত এর প্রয়োজন হয় না। এছাড়াও, আপনি নির্দিষ্ট পাইথন ভার্সনের জন্য pip চালাতে pip2 বা pip3 স্পষ্টভাবে ব্যবহার করতে পারেন।
কোডল্যাবের বাকি অংশের জন্য ধরে নেওয়া হচ্ছে যে আপনি পাইথন ৩ ব্যবহার করছেন—যদি পাইথন ৩.x থেকে এর নির্দেশাবলীতে উল্লেখযোগ্য পার্থক্য থাকে, তবে পাইথন ২-এর জন্য নির্দিষ্ট নির্দেশাবলী প্রদান করা হবে।
[ঐচ্ছিক] ভার্চুয়াল পরিবেশ তৈরি করুন এবং ব্যবহার করুন
এই অংশটি ঐচ্ছিক এবং শুধুমাত্র তাদের জন্যই প্রয়োজন, যাদের এই কোডল্যাবের জন্য একটি ভার্চুয়াল এনভায়রনমেন্ট ব্যবহার করতেই হবে (উপরের সতর্কীকরণ সাইডবার অনুযায়ী)। যদি আপনার কম্পিউটারে শুধু পাইথন ৩ থাকে, তাহলে আপনি my_env নামের একটি ভার্চুয়ালএনভ তৈরি করতে কেবল এই কমান্ডটি ব্যবহার করতে পারেন (ইচ্ছা হলে অন্য কোনো নামও বেছে নিতে পারেন):
virtualenv my_env
তবে, যদি আপনার কম্পিউটারে পাইথন ২ এবং ৩ উভয়ই থাকে, তাহলে আমরা আপনাকে একটি পাইথন ৩ ভার্চুয়ালএনভ (virtualenv) ইনস্টল করার পরামর্শ দিই, যা আপনি -p flag ব্যবহার করে এইভাবে করতে পারেন:
virtualenv -p python3 my_env
এইভাবে আপনার নতুন তৈরি করা ভার্চুয়ালএনভ 'অ্যাক্টিভেট' করে প্রবেশ করুন:
source my_env/bin/activate
আপনি যে নির্দিষ্ট পরিবেশে আছেন তা নিশ্চিত করতে লক্ষ্য করুন যে আপনার শেল প্রম্পটের শুরুতে এখন আপনার পরিবেশের নামটি দেখা যাচ্ছে, যেমন,
(my_env) $
এখন আপনি pip install , এই এনভায়রনমেন্টের মধ্যে কোড চালাতে, ইত্যাদি সক্ষম হবেন। এর আরেকটি সুবিধা হলো, যদি আপনি সবকিছু পুরোপুরি এলোমেলো করে ফেলেন, বা এমন কোনো পরিস্থিতিতে পড়েন যেখানে আপনার পাইথন ইনস্টলেশনটি করাপ্টেড হয়ে গেছে, ইত্যাদি, তাহলে আপনি আপনার সিস্টেমের বাকি অংশকে প্রভাবিত না করেই এই সম্পূর্ণ এনভায়রনমেন্টটি মুছে ফেলতে পারবেন।
৪. পাইথনের জন্য গুগল এপিআই ক্লায়েন্ট লাইব্রেরি ইনস্টল করুন।
এই কোডল্যাবটি ব্যবহারের জন্য পাইথনের গুগল এপিআই ক্লায়েন্ট লাইব্রেরি প্রয়োজন, তাই এটি ইনস্টল করা খুব সহজ, অথবা আপনাকে হয়তো কিছুই করতে হবে না।
সুবিধার জন্য আমরা আগেই আপনাকে ক্লাউড শেল ব্যবহার করার পরামর্শ দিয়েছিলাম। আপনি ক্লাউডের একটি ওয়েব ব্রাউজার থেকেই সম্পূর্ণ টিউটোরিয়ালটি শেষ করতে পারবেন। ক্লাউড শেল ব্যবহার করার আরেকটি কারণ হলো, অনেক জনপ্রিয় ডেভেলপমেন্ট টুল এবং প্রয়োজনীয় লাইব্রেরি এতে আগে থেকেই ইনস্টল করা থাকে।
ক্লায়েন্ট লাইব্রেরি ইনস্টল করুন
( ঐচ্ছিক ) আপনি যদি ক্লাউড শেল বা এমন কোনো লোকাল এনভায়রনমেন্ট ব্যবহার করেন যেখানে ক্লায়েন্ট লাইব্রেরিগুলো আগে থেকেই ইনস্টল করা আছে, তাহলে এটি বাদ দেওয়া যেতে পারে। আপনাকে কেবল তখনই এটি করতে হবে, যখন আপনি লোকালি ডেভেলপ করছেন এবং সেগুলো ইনস্টল করেননি (বা করেছেন কিনা সে বিষয়ে নিশ্চিত নন)। সবচেয়ে সহজ উপায় হলো pip (বা pip3 ) ব্যবহার করে ইনস্টল করা (প্রয়োজনে pip কে আপডেট করা সহ):
pip install -U pip google-api-python-client oauth2client
ইনস্টলেশন নিশ্চিত করুন
এই কমান্ডটি ক্লায়েন্ট লাইব্রেরি এবং এর উপর নির্ভরশীল সমস্ত প্যাকেজ ইনস্টল করে। আপনি ক্লাউড শেল বা আপনার নিজস্ব পরিবেশ ব্যবহার করছেন কিনা, তা নির্বিশেষে, প্রয়োজনীয় প্যাকেজগুলি ইম্পোর্ট করে ক্লায়েন্ট লাইব্রেরিটি ইনস্টল হয়েছে কিনা তা যাচাই করুন এবং নিশ্চিত করুন যে কোনও ইম্পোর্ট ত্রুটি (বা আউটপুট) নেই:
python3 -c "import googleapiclient, httplib2, oauth2client"
এর পরিবর্তে আপনি যদি পাইথন ২ ব্যবহার করেন (ক্লাউড শেল থেকে), তাহলে আপনি একটি সতর্কবার্তা পাবেন যে এটির জন্য সমর্থন বাতিল করা হয়েছে:
******************************************************************************* 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. *******************************************************************************
একবার আপনি "test" ইম্পোর্ট কমান্ডটি সফলভাবে চালাতে পারলে (কোনো ত্রুটি বা আউটপুট ছাড়া), আপনি গুগল এপিআই-এর সাথে যোগাযোগ শুরু করার জন্য প্রস্তুত!
সারসংক্ষেপ
যেহেতু এটি একটি মধ্যবর্তী স্তরের কোডল্যাব, তাই ধরে নেওয়া হচ্ছে যে কনসোলে প্রজেক্ট তৈরি ও ব্যবহার করার অভিজ্ঞতা আপনার আগে থেকেই আছে। আপনি যদি Google APIs, এবং বিশেষ করে Google Workspace APIs-এ নতুন হন, তাহলে প্রথমে Google Workspace APIs-এর পরিচিতিমূলক কোডল্যাবটি চেষ্টা করুন। এছাড়াও, আপনি যদি ইউজার অ্যাকাউন্টের ( সার্ভিস অ্যাকাউন্ট নয় ) ক্রেডেনশিয়াল তৈরি (বা বিদ্যমান ক্রেডেনশিয়াল পুনরায় ব্যবহার) করতে জানেন, তাহলে client_secret.json ফাইলটি আপনার ওয়ার্ক ডিরেক্টরিতে রাখুন, পরবর্তী মডিউলটি এড়িয়ে যান এবং সরাসরি "Enable Google APIs"-এ চলে যান।
৫. এপিআই অনুরোধ অনুমোদন করুন (ব্যবহারকারীর অনুমোদন)
আপনি যদি ইতিমধ্যেই ব্যবহারকারী অ্যাকাউন্টের অনুমোদনের তথ্যাবলী তৈরি করে থাকেন এবং প্রক্রিয়াটির সাথে পরিচিত হন, তাহলে এই অংশটি এড়িয়ে যেতে পারেন। এটি পরিষেবা অ্যাকাউন্টের অনুমোদন থেকে ভিন্ন, যার কৌশল আলাদা, তাই অনুগ্রহ করে নিচে পড়তে থাকুন।
অনুমোদন (এবং কিছু প্রমাণীকরণ) এর ভূমিকা
এপিআই-গুলোতে অনুরোধ পাঠানোর জন্য আপনার অ্যাপ্লিকেশনের যথাযথ অনুমোদন থাকা প্রয়োজন। অথেনটিকেশন , যা একটি অনুরূপ শব্দ, লগইন ক্রেডেনশিয়ালকে বোঝায়—আপনি যখন আপনার গুগল অ্যাকাউন্টে লগইন ও পাসওয়ার্ড দিয়ে লগইন করেন, তখন নিজেকে প্রমাণীকৃত করেন। একবার প্রমাণীকৃত হয়ে গেলে, পরবর্তী ধাপ হলো আপনি—অথবা বলা ভালো, আপনার কোড —ক্লাউড স্টোরেজের ব্লব ফাইল বা গুগল ড্রাইভে থাকা কোনো ব্যবহারকারীর ব্যক্তিগত ফাইলের মতো ডেটা অ্যাক্সেস করার জন্য অনুমোদিত কিনা।
গুগল এপিআই বিভিন্ন ধরণের অনুমোদন সমর্থন করে, কিন্তু জি স্যুট এপিআই ব্যবহারকারীদের জন্য সবচেয়ে প্রচলিত হলো ব্যবহারকারী অনুমোদন , কারণ এই কোডল্যাবের উদাহরণ অ্যাপ্লিকেশনটি শেষ-ব্যবহারকারীদের ডেটা অ্যাক্সেস করে। আপনার অ্যাপকে তাদের ডেটা অ্যাক্সেস করার জন্য সেই শেষ-ব্যবহারকারীদের অবশ্যই অনুমতি দিতে হবে। এর মানে হলো, আপনার কোডকে অবশ্যই ব্যবহারকারী অ্যাকাউন্টের OAuth2 ক্রেডেনশিয়াল সংগ্রহ করতে হবে।
ব্যবহারকারীর অনুমোদনের জন্য OAuth2 ক্রেডেনশিয়াল পেতে, API ম্যানেজারে ফিরে যান এবং বাম-ন্যাভ থেকে "ক্রেডেনশিয়াল" ট্যাবটি নির্বাচন করুন:

সেখানে পৌঁছালে আপনি আপনার সমস্ত পরিচয়পত্র তিনটি আলাদা বিভাগে দেখতে পাবেন:

প্রথমটি এপিআই কী-এর জন্য, দ্বিতীয়টি OAuth 2.0 ক্লায়েন্ট আইডি-র জন্য, এবং শেষটি OAuth2 সার্ভিস অ্যাকাউন্টের জন্য — আমরা মাঝেরটি ব্যবহার করছি।
পরিচয়পত্র তৈরি করা হচ্ছে
ক্রেডেনশিয়ালস পেজ থেকে, উপরে থাকা + Create Credentials বাটনে ক্লিক করুন, যা আপনাকে একটি ডায়ালগ বক্স দেবে যেখানে আপনাকে "OAuth client ID:" বেছে নিতে হবে।

পরবর্তী স্ক্রিনে আপনার জন্য দুটি কাজ রয়েছে: আপনার অ্যাপের অনুমোদন "সম্মতি স্ক্রিন" কনফিগার করা এবং অ্যাপ্লিকেশনের ধরন নির্বাচন করা।

আপনি যদি কোনো সম্মতি স্ক্রিন সেট না করে থাকেন, তাহলে আপনি কনসোলে সতর্কবার্তাটি দেখতে পাবেন এবং আপনাকে এখনই তা করতে হবে। (আপনার সম্মতি স্ক্রিনটি যদি আগে থেকেই সেট করা থাকে, তাহলে পরবর্তী ধাপগুলো এড়িয়ে যান।)
OAuth সম্মতি স্ক্রিন
"কনসেন্ট কনফিগার করুন স্ক্রিন"-এ ক্লিক করুন যেখানে আপনি একটি "এক্সটার্নাল" অ্যাপ (অথবা আপনি যদি জি স্যুট গ্রাহক হন তবে "ইন্টারনাল") নির্বাচন করবেন:

মনে রাখবেন যে এই অনুশীলনের জন্য আপনি কোনটি বেছে নিচ্ছেন তা গুরুত্বপূর্ণ নয়, কারণ আপনি আপনার কোডল্যাব নমুনা প্রকাশ করছেন না। বেশিরভাগ মানুষ আরও জটিল একটি স্ক্রিনে যাওয়ার জন্য "External" নির্বাচন করবে, কিন্তু আপনাকে আসলে শুধু উপরের "Application name" ফিল্ডটি পূরণ করতে হবে:

এই মুহূর্তে আপনার শুধু একটি অ্যাপ্লিকেশনের নাম প্রয়োজন, তাই এমন একটি নাম বেছে নিন যা আপনার কোডল্যাবের সাথে সামঞ্জস্যপূর্ণ, তারপর সেভ-এ ক্লিক করুন।
OAuth ক্লায়েন্ট আইডি তৈরি করা (ব্যবহারকারীর অ্যাকাউন্ট প্রমাণীকরণ)
এখন একটি OAuth2 ক্লায়েন্ট আইডি তৈরি করতে ক্রেডেনশিয়ালস ট্যাবে ফিরে যান। এখানে আপনি বিভিন্ন ধরণের OAuth ক্লায়েন্ট আইডি দেখতে পাবেন যা আপনি তৈরি করতে পারেন:

আমরা একটি কমান্ড-লাইন টুল তৈরি করছি, যার নাম ‘Other’ , তাই সেটি বেছে নিয়ে ‘ Create’ বোতামে ক্লিক করুন। আপনি যে অ্যাপটি তৈরি করছেন তার সাথে সামঞ্জস্যপূর্ণ একটি ক্লায়েন্ট আইডি নাম বেছে নিন অথবা ডিফল্ট নামটিই ব্যবহার করুন, যা সাধারণত "Other client N " হয়ে থাকে।
আপনার পরিচয়পত্র সংরক্ষণ করা হচ্ছে
- নতুন ক্রেডেনশিয়ালসহ একটি ডায়ালগ বক্স আসবে; এটি বন্ধ করতে OK-তে ক্লিক করুন।

- ক্রেডেনশিয়ালস পেজে ফিরে এসে, নিচে স্ক্রল করে "OAuth2 Client IDs" সেকশনে যান এবং ডাউনলোড আইকনটি খুঁজে ক্লিক করুন।
আপনার নতুন তৈরি করা ক্লায়েন্ট আইডির একেবারে ডানদিকের নিচের অংশে। 
- এটি
client_secret-LONG-HASH-STRING.apps.googleusercontent.com.jsonএকটি ফাইল সেভ করার জন্য একটি ডায়ালগ বক্স খুলবে, যা সম্ভবত আপনার ডাউনলোডস ফোল্ডারে থাকবে। আমরা পরামর্শ দিচ্ছি যে, ফাইলটির নাম ছোট করেclient_secret.jsonমতো একটি সহজ নাম দিন (স্যাম্পল অ্যাপটিতে এই নামটিই ব্যবহার করা হয়েছে), এবং তারপর এটিকে সেই ডিরেক্টরি/ফোল্ডারে সেভ করুন যেখানে আপনি এই কোডল্যাবে স্যাম্পল অ্যাপটি তৈরি করবেন।
সারসংক্ষেপ
এখন আপনি এই কোডল্যাবে ব্যবহৃত গুগল এপিআইগুলো সক্রিয় করার জন্য প্রস্তুত। এছাড়াও, OAuth সম্মতি স্ক্রিনের অ্যাপ্লিকেশন নাম হিসেবে আমরা "ভিশন এপিআই ডেমো" বেছে নিয়েছি, তাই আসন্ন কিছু স্ক্রিনশটে এটি দেখতে পাবেন।
৬. গুগল এপিআই সক্রিয় করুন
এই কোডল্যাবে চারটি (4) গুগল ক্লাউড এপিআই ব্যবহার করা হয়েছে, গুগল ক্লাউড থেকে এক জোড়া (ক্লাউড স্টোরেজ এবং ক্লাউড ভিশন) এবং গুগল ওয়ার্কস্পেস থেকে অন্য এক জোড়া (গুগল ড্রাইভ এবং গুগল শীটস)। নিচে গুগল এপিআই সক্রিয় করার জন্য সাধারণ নির্দেশাবলী দেওয়া হল। একবার আপনি একটি এপিআই সক্রিয় করার পদ্ধতি জেনে গেলে, বাকিগুলোও একইভাবে সক্রিয় করতে পারবেন।
আপনি আপনার অ্যাপ্লিকেশনে যে গুগল এপিআই-ই ব্যবহার করতে চান না কেন, সেগুলোকে অবশ্যই সক্রিয় করতে হবে। এপিআইগুলো কমান্ড-লাইন অথবা ক্লাউড কনসোল থেকে সক্রিয় করা যায়। এপিআই সক্রিয় করার প্রক্রিয়া একই, তাই একবার একটি এপিআই সক্রিয় করলে, আপনি একইভাবে অন্যগুলোও সক্রিয় করতে পারবেন।
বিকল্প ১: gcloud কমান্ড-লাইন ইন্টারফেস (ক্লাউড শেল বা স্থানীয় পরিবেশ)
যদিও ক্লাউড কনসোল থেকে এপিআই (API) সক্রিয় করা বেশি প্রচলিত, কিছু ডেভেলপার কমান্ড লাইন থেকে সবকিছু করতে পছন্দ করেন। এটি করার জন্য, আপনাকে একটি এপিআই-এর "সার্ভিস নেম" খুঁজে বের করতে হবে। এটি একটি ইউআরএল (URL)-এর মতো দেখতে: SERVICE_NAME । আপনি এগুলো সাপোর্টেড প্রোডাক্টস চার্টে খুঁজে পেতে পারেন, অথবা গুগল ডিসকভারি এপিআই (Google Discovery API) .googleapis.com করে প্রোগ্রাম্যাটিকভাবে এগুলোর জন্য কোয়েরি করতে পারেন।
এই তথ্যের সাহায্যে, ক্লাউড শেল (অথবা আপনার স্থানীয় ডেভেলপমেন্ট এনভায়রনমেন্টে যেখানে gcloud কমান্ড-লাইন টুল ইনস্টল করা আছে ) ব্যবহার করে, আপনি নিম্নলিখিত উপায়ে একটি API বা পরিষেবা সক্রিয় করতে পারেন:
gcloud services enable SERVICE_NAME.googleapis.com
উদাহরণ ১: ক্লাউড ভিশন এপিআই সক্রিয় করুন
gcloud services enable vision.googleapis.com
উদাহরণ ২: গুগল অ্যাপ ইঞ্জিন সার্ভারলেস কম্পিউট প্ল্যাটফর্মটি সক্রিয় করুন
gcloud services enable appengine.googleapis.com
উদাহরণ ৩: একটি অনুরোধের মাধ্যমে একাধিক এপিআই সক্রিয় করুন। উদাহরণস্বরূপ, যদি এই কোডল্যাবের দর্শকরা ক্লাউড ট্রান্সলেশন এপিআই ব্যবহার করে অ্যাপ ইঞ্জিন, ক্লাউড ফাংশনস এবং ক্লাউড রান-এ একটি অ্যাপ ডেপ্লয় করেন, তাহলে কমান্ড লাইনটি হবে:
gcloud services enable appengine.googleapis.com cloudfunctions.googleapis.com artifactregistry.googleapis.com run.googleapis.com translate.googleapis.com
এই কমান্ডটি অ্যাপ ইঞ্জিন, ক্লাউড ফাংশনস, ক্লাউড রান এবং ক্লাউড ট্রান্সলেশন এপিআই সক্রিয় করে। এছাড়াও, এটি ক্লাউড আর্টিফ্যাক্ট রেজিস্ট্রি সক্রিয় করে, কারণ ক্লাউড রানে ডেপ্লয় করার জন্য ক্লাউড বিল্ড সিস্টেমকে কন্টেইনার ইমেজগুলো সেখানেই রেজিস্টার করতে হয়।
এছাড়াও, আপনার প্রোজেক্টের জন্য কোন এপিআইগুলো সক্রিয় করতে হবে অথবা কোনগুলো ইতিমধ্যে সক্রিয় করা হয়েছে, তা জানার জন্য কয়েকটি কমান্ড রয়েছে।
উদাহরণ ৪: আপনার প্রোজেক্টের জন্য সক্রিয় করা যাবে এমন গুগল এপিআইগুলো সম্পর্কে জিজ্ঞাসা করুন।
gcloud services list --available --filter="name:googleapis.com"
উদাহরণ ৫: আপনার প্রোজেক্টের জন্য সক্রিয় করা গুগল এপিআইগুলো সম্পর্কে জিজ্ঞাসা করুন।
gcloud services list
উপরোক্ত কমান্ডগুলো সম্পর্কে আরও তথ্যের জন্য, সার্ভিস চালু ও বন্ধ করা এবং সার্ভিস তালিকাভুক্ত করার ডকুমেন্টেশন দেখুন।
বিকল্প ২: ক্লাউড কনসোল
আপনি এপিআই ম্যানেজার-এও গুগল এপিআইগুলো সক্রিয় করতে পারেন। ক্লাউড কনসোল থেকে, এপিআই ম্যানেজার- এ যান। এই ড্যাশবোর্ড পৃষ্ঠায়, আপনি আপনার অ্যাপের কিছু ট্র্যাফিক তথ্য, অ্যাপ্লিকেশন অনুরোধ দেখানো গ্রাফ, আপনার অ্যাপ দ্বারা তৈরি ত্রুটি এবং আপনার অ্যাপের প্রতিক্রিয়া সময় দেখতে পাবেন:

এই চার্টগুলোর নিচে আপনার প্রোজেক্টের জন্য সক্রিয় করা গুগল এপিআইগুলোর একটি তালিকা দেওয়া হলো:

API চালু (বা বন্ধ) করতে, উপরে থাকা ‘Enable APIs and Services’- এ ক্লিক করুন:

বিকল্পভাবে, বাম দিকের নেভিগেশন বারে যান এবং APIs & Services → Library নির্বাচন করুন।

যেভাবেই হোক, আপনি এপিআই লাইব্রেরি পৃষ্ঠায় পৌঁছে যাবেন:

অনুসন্ধান করতে এবং মিলে যাওয়া ফলাফল দেখতে একটি API নাম লিখুন:

আপনি যে API-টি সক্রিয় করতে চান তা নির্বাচন করুন এবং ' সক্রিয় করুন' বোতামে ক্লিক করুন:

আপনি কোন গুগল এপিআই ব্যবহার করতে চান তা নির্বিশেষে, সমস্ত এপিআই সক্রিয় করার প্রক্রিয়া একই রকম।
খরচ
অনেক গুগল এপিআই বিনামূল্যে ব্যবহার করা যায়, তবে বেশিরভাগ গুগল ক্লাউড প্রোডাক্ট এবং এপিআই ব্যবহার করার জন্য খরচ রয়েছে। ক্লাউড এপিআই সক্রিয় করার সময়, আপনার কাছে একটি সক্রিয় বিলিং অ্যাকাউন্ট চাওয়া হতে পারে। তবে, কিছু গুগল ক্লাউড প্রোডাক্টে একটি "সর্বদা বিনামূল্যে" (Always Free) স্তর রয়েছে, যা অতিক্রম করলেই বিলিং চার্জ প্রযোজ্য হবে।
নতুন গুগল ক্লাউড ব্যবহারকারীরা ফ্রি ট্রায়ালের জন্য যোগ্য, যার বর্তমান মূল্য ৩০০ মার্কিন ডলার এবং এটি প্রথম ৯০ দিনের জন্য প্রযোজ্য। কোডল্যাবস সাধারণত খুব বেশি বা কোনো বিলই নেয় না, তাই আমরা আপনাকে পরামর্শ দিচ্ছি যে, আপনি এটি পরীক্ষা করার জন্য পুরোপুরি প্রস্তুত না হওয়া পর্যন্ত ফ্রি ট্রায়ালটি গ্রহণ করা থেকে বিরত থাকুন, বিশেষ করে যেহেতু এটি একটি এককালীন অফার। ফ্রি টিয়ারের কোটাগুলোর কোনো মেয়াদ শেষ হয় না এবং আপনি ফ্রি ট্রায়াল ব্যবহার করুন বা না করুন, তা নির্বিশেষে এটি প্রযোজ্য থাকবে।
যেকোনো API চালু করার আগে ব্যবহারকারীদের এর মূল্য সংক্রান্ত তথ্য দেখে নেওয়া উচিত (উদাহরণস্বরূপ: ক্লাউড ভিশন API প্রাইসিং পেজ), বিশেষ করে এটির কোনো ফ্রি টিয়ার আছে কিনা এবং থাকলে, সেটি কী তা লক্ষ্য করা উচিত। যতক্ষণ আপনি সামগ্রিকভাবে নির্দিষ্ট দৈনিক বা মাসিক সীমার মধ্যে থাকবেন, ততক্ষণ আপনার কোনো চার্জ লাগার কথা নয়। গুগল প্রোডাক্ট গ্রুপের API গুলোর মধ্যে মূল্য এবং ফ্রি টিয়ার ভিন্ন ভিন্ন হয়ে থাকে। উদাহরণ:
- গুগল ক্লাউড — প্রতিটি পণ্যের বিল আলাদাভাবে করা হয় এবং সাধারণত ব্যবহারের ভিত্তিতে অর্থ প্রদান করতে হয়; উপরে ফ্রি টিয়ার সম্পর্কিত তথ্য দেখুন।
- গুগল ম্যাপস — এতে রয়েছে একাধিক এপিআই এবং এটি ব্যবহারকারীদের প্রতি মাসে মোট ২০০ মার্কিন ডলারের বিনামূল্যে ক্রেডিট প্রদান করে।
- গুগল ওয়ার্কস্পেস (পূর্বের নাম জি স্যুট) এপিআই — গুগল ওয়ার্কস্পেসের মাসিক সাবস্ক্রিপশন ফি- এর আওতায় (নির্দিষ্ট সীমা পর্যন্ত) এর ব্যবহার পাওয়া যায়, তাই জিমেইল, গুগল ড্রাইভ, ক্যালেন্ডার, ডকস, শিটস বা স্লাইডসের মতো অ্যাপ্লিকেশনগুলোর এপিআই ব্যবহারের জন্য সরাসরি কোনো বিলিং করা হয় না।
গুগলের বিভিন্ন পণ্যের বিল ভিন্ন ভিন্ন হয়ে থাকে, তাই এই তথ্যের জন্য অবশ্যই সংশ্লিষ্ট ডকুমেন্টেশন দেখে নেবেন।
সারসংক্ষেপ
এখন যেহেতু ক্লাউড ভিশন চালু করা হয়েছে, একইভাবে অন্য তিনটি এপিআই (গুগল ড্রাইভ, ক্লাউড স্টোরেজ, গুগল শিটস) চালু করুন। ক্লাউড শেল থেকে, gcloud services enable ব্যবহার করুন, অথবা ক্লাউড কনসোল থেকে:
- এপিআই লাইব্রেরিতে ফিরে যান
- এর নামের কয়েকটি অক্ষর টাইপ করে অনুসন্ধান শুরু করুন।
- কাঙ্ক্ষিত এপিআই নির্বাচন করুন, এবং
- সক্ষম করুন
বারবার একই কাজ করুন। ক্লাউড স্টোরেজের জন্য কয়েকটি বিকল্প রয়েছে: ‘Google Cloud Storage JSON API’ বেছে নিন। ক্লাউড স্টোরেজ এপিআই-এর জন্য একটি সক্রিয় বিলিং অ্যাকাউন্টও প্রয়োজন হবে।
৭. ধাপ ০: ইম্পোর্ট এবং অনুমোদন কোড সেটআপ করুন
এটি একটি মাঝারি আকারের কোড অংশের সূচনা, তাই মূল অ্যাপ্লিকেশনটিতে হাত দেওয়ার আগে একটি সাধারণ, স্থিতিশীল এবং কার্যকরী পরিকাঠামো নিশ্চিত করতে অ্যাজাইল পদ্ধতি কিছুটা অনুসরণ করা সহায়ক হয়। আপনার বর্তমান ডিরেক্টরিতে 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()ফাংশনটি ইম্পোর্ট করার ফলে এই স্যাম্পলটি পাইথন ২-৩ এর সাথে সামঞ্জস্যপূর্ণ হয়, এবং গুগল লাইব্রেরি ইম্পোর্ট করার মাধ্যমে গুগল এপিআই-এর সাথে যোগাযোগের জন্য প্রয়োজনীয় সমস্ত টুলস চলে আসে। -
SCOPESভেরিয়েবলটি ব্যবহারকারীর কাছ থেকে অনুরোধ করার অনুমতিগুলো নির্দেশ করে—আপাতত এর জন্য কেবল একটিই অনুমতি রয়েছে: তাদের গুগল ড্রাইভ থেকে ডেটা পড়ার অনুমতি। - ক্রেডেনশিয়াল প্রসেসিং কোডের বাকি অংশ ক্যাশ করা OAuth2 টোকেনগুলো পড়ে নেয় এবং মূল অ্যাক্সেস টোকেনটির মেয়াদ শেষ হয়ে গেলে রিফ্রেশ টোকেন ব্যবহার করে সেটিকে একটি নতুন অ্যাক্সেস টোকেনে আপডেট করে।
- যদি কোনো টোকেন তৈরি না হয়ে থাকে অথবা অন্য কোনো কারণে একটি বৈধ অ্যাক্সেস টোকেন পুনরুদ্ধার করা ব্যর্থ হয়, তবে ব্যবহারকারীকে অবশ্যই OAuth2 3-legged flow (3LO) অনুসরণ করতে হবে: অর্থাৎ, অনুরোধ করা অনুমতিসহ ডায়ালগটি তৈরি করতে হবে এবং ব্যবহারকারীকে তা গ্রহণ করার জন্য অনুরোধ করতে হবে। ব্যবহারকারী তা করলে, অ্যাপটি চলতে থাকে, অন্যথায়
tools.run_flow()একটি এক্সেপশন থ্রো করে এবং এক্সিকিউশন থেমে যায়। - ব্যবহারকারী অনুমতি দিলে, সার্ভারের সাথে যোগাযোগের জন্য একটি HTTP ক্লায়েন্ট তৈরি করা হয় এবং নিরাপত্তার জন্য সমস্ত অনুরোধ ব্যবহারকারীর ক্রেডেনশিয়াল দিয়ে স্বাক্ষরিত হয়। এরপর সেই HTTP ক্লায়েন্ট ব্যবহার করে গুগল ড্রাইভ এপিআই (সংস্করণ ৩)-এর জন্য একটি সার্ভিস এন্ডপয়েন্ট তৈরি করা হয় এবং সেটিকে
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
আপনি যদি ক্লাউড শেল থেকে চালাচ্ছেন, তাহলে সরাসরি "ক্লাউড শেল থেকে" অংশে চলে যান এবং প্রয়োজন অনুযায়ী "স্থানীয় উন্নয়ন পরিবেশ থেকে" অংশের প্রাসঙ্গিক স্ক্রিনগুলো পর্যালোচনা করতে পিছনে স্ক্রল করুন।
স্থানীয় উন্নয়ন পরিবেশ থেকে
ব্রাউজার উইন্ডো খোলার সময় কমান্ড-লাইন স্ক্রিপ্টটি থেমে যায়। আপনি এইরকম দেখতে একটি ভীতিকর সতর্কীকরণ পৃষ্ঠা পেতে পারেন:

এটি একটি যুক্তিসঙ্গত উদ্বেগ, কারণ আপনি এমন একটি অ্যাপ চালানোর চেষ্টা করছেন যা ব্যবহারকারীর ডেটা অ্যাক্সেস করে। যেহেতু এটি কেবল একটি ডেমো অ্যাপ এবং আপনিই এর ডেভেলপার, আশা করি আপনি এগিয়ে যাওয়ার জন্য নিজের ওপর যথেষ্ট আস্থা রাখেন। বিষয়টি আরও ভালোভাবে বোঝার জন্য, নিজেকে আপনার ব্যবহারকারীর জায়গায় রেখে ভাবুন: আপনাকে অন্য কারো কোডকে আপনার ডেটা অ্যাক্সেস করার অনুমতি দিতে বলা হচ্ছে। আপনি যদি এই ধরনের কোনো অ্যাপ প্রকাশ করতে চান, তবে আপনি ভেরিফিকেশন প্রক্রিয়াটি সম্পন্ন করবেন, যাতে আপনার ব্যবহারকারীরা এই স্ক্রিনটি দেখতে না পান।
"go to 'unsafe' app" লিঙ্কে ক্লিক করার পর, আপনি একটি OAuth2 অনুমতি ডায়ালগ বক্স পাবেন যা দেখতে অনেকটা নীচের ছবির মতো—আমরা আমাদের ইউজার ইন্টারফেসের ক্রমাগত উন্নতি করছি, তাই এটি হুবহু না মিললেও চিন্তার কিছু নেই:

OAuth2 ফ্লো ডায়ালগটি ডেভেলপারের অনুরোধ করা অনুমতিগুলো ( SCOPES ভেরিয়েবলের মাধ্যমে) প্রতিফলিত করে। এক্ষেত্রে, এটি হলো ব্যবহারকারীর গুগল ড্রাইভ থেকে দেখা এবং ডাউনলোড করার ক্ষমতা। অ্যাপ্লিকেশন কোডে, এই পারমিশন স্কোপগুলো URI হিসেবে প্রদর্শিত হয়, কিন্তু এগুলো ব্যবহারকারীর লোকেল দ্বারা নির্দিষ্ট ভাষায় অনূদিত হয়। এখানে ব্যবহারকারীকে অনুরোধ করা অনুমতি(গুলো)র জন্য সুস্পষ্ট অনুমোদন দিতে হবে , অন্যথায় একটি এক্সেপশন থ্রো করা হয়, ফলে স্ক্রিপ্টটি আর অগ্রসর হয় না।
এমনকি আপনার নিশ্চিতকরণের জন্য আরও একটি ডায়ালগ বক্সও আসতে পারে:

দ্রষ্টব্য : কেউ কেউ বিভিন্ন অ্যাকাউন্টে লগ ইন করে একাধিক ওয়েব ব্রাউজার ব্যবহার করেন, তাই এই অনুমোদনের অনুরোধটি ভুল ব্রাউজার ট্যাব/উইন্ডোতে চলে যেতে পারে। সেক্ষেত্রে, আপনাকে এই অনুরোধের লিঙ্কটি সঠিক অ্যাকাউন্টে লগ ইন করা কোনো ব্রাউজারে কাট-পেস্ট করতে হতে পারে।
ক্লাউড শেল থেকে
ক্লাউড শেল থেকে কোনো ব্রাউজার উইন্ডো পপ আপ হয় না, ফলে আপনি আটকে যান। উপলব্ধি করুন যে নীচের ডায়াগনস্টিক বার্তাটি আপনার জন্যই ছিল:
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 এখনও তৈরি হয়নি) অন্য একটি ব্রাউজার ট্যাবে সেই URL-টি দিয়ে নির্দেশাবলী অনুসরণ করলে, আপনি লোকাল ডেভেলপমেন্ট এনভায়রনমেন্টের জন্য উপরে বর্ণিত অভিজ্ঞতার প্রায় হুবহু অনুরূপ একটি অভিজ্ঞতা পাবেন (উপরের স্ক্রিনশটগুলো দেখুন)। সবশেষে একটি চূড়ান্ত স্ক্রিন রয়েছে, যেখানে ক্লাউড শেলে প্রবেশ করানোর জন্য ভেরিফিকেশন কোডটি দেওয়া থাকে:

এই কোডটি কপি করে টার্মিনাল উইন্ডোতে পেস্ট করুন।
সারসংক্ষেপ
" Authentication successful " লেখাটি ছাড়া আর কোনো অতিরিক্ত আউটপুট আশা করবেন না। মনে রাখবেন, এটি কেবল প্রস্তুতি পর্ব... আপনি এখনও কিছুই করেননি। আপনি যা করেছেন তা হলো, এমন একটি কাজের দিকে আপনার যাত্রা সফলভাবে শুরু করেছেন যা প্রথমবারেই সঠিকভাবে সম্পন্ন হওয়ার সম্ভাবনা বেশি। (সবচেয়ে ভালো ব্যাপার হলো, আপনাকে অনুমোদনের জন্য কেবল একবারই অনুরোধ করা হয়েছিল; পরবর্তী সমস্ত এক্সিকিউশন এটি এড়িয়ে যাবে কারণ আপনার পারমিশনগুলো ক্যাশ করা হয়ে গেছে।) এবার চলুন কোডটিকে দিয়ে কিছু আসল কাজ করানো যাক, যার ফলে প্রকৃত আউটপুট পাওয়া যাবে।
সমস্যা সমাধান
যদি কোনো আউটপুট না আসার পরিবর্তে আপনি কোনো ত্রুটি পান, তবে এর এক বা একাধিক কারণ থাকতে পারে, সম্ভবত এটি:
৮. ধাপ ১: গুগল ড্রাইভ থেকে ছবিটি ডাউনলোড করুন।
পূর্ববর্তী ধাপে, আমরা analyze_gsimg.py নামে কোডটি তৈরি করে সেখান থেকে সম্পাদনা করার পরামর্শ দিয়েছিলাম। সরাসরি iPython বা সাধারণ পাইথন শেলে সবকিছু কাট-পেস্ট করাও সম্ভব, তবে এটি আরও কষ্টসাধ্য, কারণ আমরা অ্যাপটি ধাপে ধাপে তৈরি করতে থাকব।
ধরে নিন আপনার অ্যাপটি অনুমোদিত হয়েছে এবং এপিআই সার্ভিস এন্ডপয়েন্ট তৈরি করা হয়েছে। আপনার কোডে, এটি DRIVE ভেরিয়েবল দ্বারা চিহ্নিত করা আছে। এখন চলুন আপনার গুগল ড্রাইভে একটি ইমেজ ফাইল খুঁজে বের করি এবং
এটিকে NAME নামের একটি ভেরিয়েবলে সেট করুন। ধাপ ০-এর কোডের ঠিক নিচে সেটি এবং নিম্নলিখিত 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 প্যারামিটারটি ব্যবহৃত হয়—যদি অন্য ভ্যালুগুলো নিয়ে আপনার কোনো আগ্রহ না থাকে, তবে সবকিছু ফেরত নিয়ে গতি কমানোর ঝামেলা করার দরকার কী? আপনি যদি API রিটার্ন ভ্যালু ফিল্টার করার জন্য ফিল্ড মাস্ক ব্যবহারে নতুন হন, তবে এই ব্লগ পোস্ট ও ভিডিওটি দেখে নিতে পারেন। অন্যথায়, কোয়েরিটি চালান এবং ফেরত আসা files অ্যাট্রিবিউটটি গ্রহণ করুন; কোনো মিল না পাওয়া গেলে এটি ডিফল্টভাবে একটি খালি লিস্ট অ্যারে হিসেবে গণ্য হবে।
যদি কোনো ফলাফল না পাওয়া যায়, তাহলে ফাংশনের বাকি অংশ বাদ দেওয়া হয় এবং (অস্পষ্টভাবে) None রিটার্ন করা হয়। অন্যথায়, প্রথম মিলে যাওয়া প্রতিক্রিয়া ( rsp[0] ) গ্রহণ করুন, ফাইলের নাম, এর MIMEtype, শেষ পরিবর্তনের টাইমস্ট্যাম্প এবং সবশেষে, files() সংগ্রহে থাকা ` get_media() ফাংশন দ্বারা (এর ফাইল আইডি ব্যবহার করে) প্রাপ্ত এর বাইনারি পেলোড রিটার্ন করুন। (অন্যান্য ভাষার ক্লায়েন্ট লাইব্রেরির ক্ষেত্রে মেথডের নাম সামান্য ভিন্ন হতে পারে।)
শেষ অংশটি হলো মূল কাঠামো যা পুরো অ্যাপ্লিকেশনটিকে চালনা করে:
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)
সমস্যা সমাধান
যদি আপনি উপরের মতো সফল ফলাফল না পান, তবে এর এক বা একাধিক কারণ থাকতে পারে, সম্ভবত এটি:
সারসংক্ষেপ
এই অংশে, আপনি শিখেছেন কিভাবে (দুটি পৃথক API কলের মাধ্যমে) একটি নির্দিষ্ট ফাইলের জন্য কোয়েরি করে Drive API-এর সাথে সংযোগ স্থাপন করতে হয় এবং তারপর সেটি ডাউনলোড করতে হয়। এর ব্যবসায়িক ব্যবহার হলো: আপনার Drive ডেটা আর্কাইভ করা এবং সম্ভবত Google Cloud টুলের মতো টুল ব্যবহার করে তা বিশ্লেষণ করা। এই পর্যায়ে আপনার অ্যাপের কোডটি step1-drive/analyze_gsimg.py রিপোজিটরিতে যা আছে তার সাথে মিলতে হবে।
গুগল ড্রাইভে ফাইল ডাউনলোড করার বিষয়ে আরও জানতে এখানে পড়ুন অথবা এই ব্লগ পোস্ট ও ভিডিওটি দেখুন। কোডল্যাবের এই অংশটি গুগল ওয়ার্কস্পেস এপিআই পরিচিতি কোডল্যাবের প্রায় হুবহু অনুরূপ — শুধু ফাইল ডাউনলোড করার পরিবর্তে, এটি একজন ব্যবহারকারীর গুগল ড্রাইভের প্রথম ১০০টি ফাইল/ফোল্ডার প্রদর্শন করে এবং আরও সীমিত পরিসর ব্যবহার করে।
৯. ধাপ ২: ফাইলটি ক্লাউড স্টোরেজে আর্কাইভ করুন
পরবর্তী ধাপ হলো গুগল ক্লাউড স্টোরেজের জন্য সাপোর্ট যোগ করা। এর জন্য আমাদের আরেকটি পাইথন প্যাকেজ, io , ইম্পোর্ট করতে হবে। নিশ্চিত করুন যে আপনার ইম্পোর্টগুলোর উপরের অংশটি এখন দেখতে এইরকম:
from __future__ import print_function
import io
ড্রাইভ ফাইলের নামের পাশাপাশি, ক্লাউড স্টোরেজে এই ফাইলটি কোথায় সংরক্ষণ করা হবে সে সম্পর্কেও আমাদের কিছু তথ্য প্রয়োজন। বিশেষ করে, আপনি যে 'বাকেট'-এ এটি রাখবেন তার নাম এবং যেকোনো 'প্যারেন্ট ফোল্ডার' প্রিফিক্স। এ বিষয়ে একটু পরেই আরও আলোচনা করা হবে:
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = '' # YOUR IMG FILE PREFIX
বাকেট সম্পর্কে কিছু কথা: ক্লাউড স্টোরেজ এক ধরনের আকারহীন ব্লব স্টোরেজ প্রদান করে। সেখানে ফাইল আপলোড করার সময়, এটি গুগল ড্রাইভের মতো ফাইলের ধরন, এক্সটেনশন ইত্যাদির ধারণা বোঝে না। ক্লাউড স্টোরেজের কাছে ফাইলগুলো কেবলই "ব্লব"। এছাড়াও, ক্লাউড স্টোরেজে ফোল্ডার বা সাবডিরেক্টরির কোনো ধারণা নেই।
হ্যাঁ, একাধিক সাব-ফোল্ডারের ধারণা বোঝাতে আপনি ফাইলের নামে স্ল্যাশ ( / ) ব্যবহার করতে পারেন, কিন্তু শেষ পর্যন্ত আপনার সমস্ত ব্লব একটি বাকেটের মধ্যেই যায়, এবং " / " চিহ্নগুলো তাদের নামের কেবলই কয়েকটি অক্ষর। আরও তথ্যের জন্য বাকেট এবং অবজেক্ট নামকরণের নিয়মাবলী পৃষ্ঠাটি দেখুন।
উপরের ধাপ ১-এ ড্রাইভের রিড-অনলি স্কোপ চাওয়া হয়েছিল। সেই সময়ে, আপনার শুধু এটুকুই প্রয়োজন ছিল। এখন, ক্লাউড স্টোরেজে আপলোড (রিড-রাইট) পারমিশন প্রয়োজন। SCOPES একটিমাত্র স্ট্রিং ভেরিয়েবল থেকে পারমিশন স্কোপগুলোর একটি অ্যারেতে (পাইথন টাপল [বা লিস্ট]) পরিবর্তন করুন, যাতে এটি দেখতে এইরকম হয়:
SCOPES = (
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/devstorage.full_control',
)
এখন ড্রাইভের সার্ভিস এন্ডপয়েন্টের ঠিক নিচে ক্লাউড স্টোরেজের জন্য একটি সার্ভিস এন্ডপয়েন্ট তৈরি করুন। লক্ষ্য করুন, আমরা কলটি সামান্য পরিবর্তন করেছি যাতে একই HTTP ক্লায়েন্ট অবজেক্ট পুনরায় ব্যবহার করা যায়, কারণ এটি একটি শেয়ার্ড রিসোর্স হতে পারলে নতুন করে তৈরি করার কোনো প্রয়োজন নেই।
# 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() এর পরে) যোগ করুন, যেটি ক্লাউড স্টোরেজে আপলোড করে:
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 " ঠিকানায় আর্কাইভ করছেন। এই অংশটি প্রথম print() ফাংশনের ঠিক পরে, else ক্লজের উপরে রাখুন, যাতে পুরো "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 ড্রাইভ থেকে ডাউনলোড হয়ে ক্লাউড স্টোরেজে আপলোড হবে, তাই না? মোটেই না!
$ 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">
ভালো করে দেখুন, ড্রাইভ থেকে ডাউনলোড সফল হলেও ক্লাউড স্টোরেজে আপলোড ব্যর্থ হয়েছে। কেন?
The reason is that when we authorized this application originally for Step 1, we only authorized the read-only access to Google Drive. While we added the read-write scope for Cloud Storage, we never prompted the user to authorize that access. To make it work, we need to blow away the storage.json file which is missing this scope and re-run.
After you re-authorize (confirm this by looking inside storage.json and see both scopes there), your output will then be as expected:
$ 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'
সারসংক্ষেপ
This is a big deal, showing you, in relatively few lines of code, how to transfer files between both Cloud-based storage systems. The business use-case here is to backup a possibly constrained resource to "colder," cheaper storage as mentioned earlier. Cloud Storage offers different storage classes depending on whether you access your data regularly, monthly, quarterly, or annually.
Of course, developers do ask us from time-to-time why both Google Drive and Cloud Storage exist. After all, aren't they both file storage in the cloud? That's why we made this video . Your code at this stage should match what's in the repo at step2-gcs/analyze_gsimg.py .
10. Step 3: Analyze with Cloud Vision
While we now know you can move data between Google Cloud and Google Workspace, we haven't done any analysis yet, so time to send the image to Cloud Vision for label annotation aka object detection. To do so, we need to Base64-encode the data, meaning another Python module, base64 . Ensure your top import section now looks like this:
from __future__ import print_function
import base64
import io
By default, the Vision API returns all the labels it finds. To keep things consistent, let's request just the top 5 (adjustable by the user of course). We'll use a constant variable TOP for this; add it under all the other constants:
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = '' # YOUR IMG FILE PREFIX
TOP = 5 # TOP # of VISION LABELS TO SAVE
As with earlier steps, we need another permission scope, this time for the Vision API. Update SCOPES with its string:
SCOPES = (
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/devstorage.full_control',
'https://www.googleapis.com/auth/cloud-vision',
)
Now create a service endpoint to Cloud Vision so it lines up with the others like this:
# 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)
Now add this function that sends the image payload to 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'])
The images().annotate() call requires the data plus desired API features. The top 5 label cap is part of the payload too (but completely optional). If the call is successful, the payload returns the top 5 labels of objects plus a confidence score an object is in the image. (If no response comes back, assign an empty Python dictionary so the following if statement doesn't fail.) This function simply collates that data into a CSV string for eventual use in our report.
These 5 lines that call vision_label_img() should be placed right after the successful upload to 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)
With that addition, the entire main driver should look like this:
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)
Deleting storage.json to refresh the scopes and re-running the updated application should result in output similar to the following, noting the addition of Cloud Vision analysis:
$ 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
সারসংক্ষেপ
Not everyone has the machine learning expertise to create and train their own ML models to analyze their data. The Google Cloud team has made available some of Google's pre-trained models for general use and put them behind APIs, helping democratize AI & ML for everyone.
If you're a developer and can call an API, you can use machine learning. Cloud Vision is just one of the API services you can use to analyze your data with. Learn about the others here . Your code should now match what's in the repo at step3-vision/analyze_gsimg.py .
11. Step 4: Generate a report with Google Sheets
At this point, you've been able to archive corporate data and analyze it, but what's lacking is a summary of this work. Let's organize all results into a single report you can hand to your boss. What's more presentable to management than a spreadsheet?
No additional imports are needed for the Google Sheets API, and the only new piece of information needed is the file ID of an existing spreadsheet already formatted and awaiting a new row of data, hence the SHEET constant. We recommend you create a new spreadsheet that looks similar to the following:

The URL for that spreadsheet will look like the following: https://docs.google.com/spreadsheets/d/ FILE_ID /edit . Grab that FILE_ID and assign it as a sting to SHEET .
We also snuck in a tiny function named k_ize() which converts bytes to kilobytes, defining it as a Python lambda since it's a simple 1-liner. Both of these integrated with the other constants looks like this:
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
As with earlier steps, we need another permission scope, this time read-write for the Sheets API. SCOPES now has all 4 needed:
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',
)
Now create a service endpoint to Google Sheets near the others, so it looks like this:
# 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)
The functionality of sheet_append_row() is straightforward: take a row of data and a Sheet's ID, then add that row to that Sheet:
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')
The spreadsheets().values().append() call requires Sheet's file ID, a range of cells, how the data should be entered, and the data itself. The file ID is straightforward, the range of cells is given in A1 notation . A range of " Sheet1 " means the entire Sheet—this signals to the API to append the row after all the data in the Sheet. There are a pair of choices on how the data should be added to the Sheet , " RAW " (enter the string data verbatim) or " USER_ENTERED " (write the data as if a user entered it on their keyboard with the Google Sheets application, preserving any cell formatting features).
If the call is successful, the return value doesn't really have anything super useful, so we opted for getting the number of cells updated by the API request. Below is the code that calls that function:
# 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')
The Google Sheet has columns representing data such as any parent "subdirectory," the location of the archived file on Cloud Storage (bucket + filename), the file's MIMEtype, the file size (originally in bytes, but converted to kilobytes with k_ize() ), and the Cloud Vision labels string. Also note the archived location is a hyperlink so your manager can click to confirm it's been backed up safely.
Adding the block of code above right after displaying the results from Cloud Vision, the main portion driving the app is now complete, although structurally a bit complex:
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)
Deleting storage.json one last time and re-running the updated application should result in output similar to the following, noting the addition of Cloud Vision analysis:
$ 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
The extra line of output, while useful, is better visualized by taking a peek at the updated Google Sheet, with the last line (row 7 in the example below) added to the existing data set added prior:

সারসংক্ষেপ
In the first 3 steps of this tutorial, you connected with Google Workspace and Google Cloud APIs to move data and to analyze it, representing 80% of all the work. However at the end of day, none of this means anything if you can't present to management all you've accomplished. To better visualize the results, summarizing all the results in a generated report speaks volumes.
To further enhance the usefulness of the analysis, in addition to writing the results into a spreadsheet, one possible enhancement would be to index these top 5 labels for each image so that an internal database can be built allowing authorized employees to query for images by search team, but we leave that as an exercise for readers.
For now, our results are in a Sheet and accessible to management. The code for your app at this stage should match what's in the repo at step4-sheets/analyze_gsimg.py . The final step is to clean-up the code and turn it into a usable script.
12. *Final step: refactor
(optional) It's good to have a working app, however can we improve it? Yes, especially the main application which seems like a jumbled mess. Let's put that into its own function and drive it allowing for user input rather than fixed constants. We'll do that with the argparse module. Furthermore, let's launch a web browser tab to display the Sheet once we've written our row of data to it. This is doable with the webbrowser module. Weave these imports with the others so the top imports look like this:
from __future__ import print_function
import argparse
import base64
import io
import webbrowser
To be able to use this code in other applications, we need the ability to suppress the output, so let's add a DEBUG flag to make that happen, adding this line to end of the constants section near the top:
DEBUG = False
Now, about the main body. As we were building this sample, you should've begun to feel "uncomfortable" as our code adds another level of nesting with each service added. If you felt that way, you're not alone, as this adds to code complexity as described in this Google Testing Blog post .
Following this best practice, let's reorganize the main part of the app into a function and return at each "break point" instead of nesting (returning None if any step fails and True if all succeed):
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
It's neater and cleaner, leaving behind that recursive if-else chain feeling along with reducing code complexity as described above. The last piece of the puzzle is to create a "real" main driver, allowing for user customization, and minimizing output (unless desired):
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)
If all steps are successful, the script launches a web browser to the spreadsheet specified where the new data row was added.
সারসংক্ষেপ
No need to delete storage.json since no scope changes occurred. Re-run the updated application reveals a new browser window opened to the modified Sheet, fewer lines of output, and issuing a -h option shows users their options, including -v to restore the now-suppressed lines of output seen earlier:
$ 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
The other options let users choose different Drive file names, Cloud Storage "subdirectory" and bucket names, top "N" results from Cloud Vision, and spreadsheet (Sheets) file IDs. With these last updates, the final version of your code should now match what's in the repo at final/analyze_gsimg.py as well as here, in its entirety:
'''
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)
We will make every attempt to keep this tutorial's contents up-to-date, but there will be occasions where the repo will have the most recent version of the code.
১৩. অভিনন্দন!
There was certainly a lot of learning in this codelab, and you achieved that, surviving one of the longer codelabs. As a result, you tackled a possible enterprise scenario with about ~130 lines of Python, leveraging all of Google Cloud and Google Workspace, and moving data between them to build a working solution. Feel free to explore the open source repo for all versions of this app (more info below).
পরিষ্কার করা
- Use of Google Cloud APIs are not free while Google Workspace APIs are covered by your monthly Google Workspace subscription fee (consumer Gmail users have a monthly fee of zero), so there's no API clean-up/turndown required for Google Workspace users. For Google Cloud, you can go to your Cloud console dashboard and check the Billing "card" for estimated charges.
- For Cloud Vision , you're allowed a fixed number of API calls per month for free. So as long as you stay under those limits, there's no need to shut anything down nor must you disable/delete your project. More information on the Vision API's billing and free quota can be found on its pricing page .
- Some Cloud Storage users receive a free amount of storage per month. If the images you archive using this codelab do not cause you to exceed that quota, you will not incur any charges. More information on GCS billing and free quota can be found on its pricing page . You can view and easily delete blobs from the Cloud Storage browser .
- Your use of Google Drive may also have a storage quota, and if you exceed it (or are close to it), you may actually consider using the tool you built in this codelab to archive those images to Cloud Storage to give yourself more space on Drive. More information on Google Drive storage can be found on the appropriate pricing page for Google Workspace Basic users or Gmail/consumer users.
While most Google Workspace Business and Enterprise plans have unlimited storage, this could cause your Drive folders to be cluttered and/or overwhelming, and the app you built in this tutorial is a great way to archive extraneous files and clean-up your Google Drive.
Alternate versions
While final/analyze_gsimg.py is the "last" official version you're working on in this tutorial, it's not the end of the story. One issue with the final version of the app is that it uses the older auth libraries which have been deprecated. We chose this path because, at the time of this writing, the newer auth libraries did not support several key elements: OAuth token storage management and thread safety.
Current (newer) auth libraries
However, at some point, the older auth libraries will no longer be supported, so we encourage you to review versions that use the newer (current) auth libraries in the repo's alt folder even if they aren't threadsafe (but you can build your own solution that is). Look for files with *newauth* in their names.
Google Cloud product client libraries
Google Cloud recommends all developers use the product client libraries when using Google Cloud APIs. Unfortunately non-Google Cloud APIs don't have such libraries at this time. Use of the lower-level libraries allow for consistent API usage and features better readability. Similar to the recommendation above, alternative versions using Google Cloud product client libraries are available in the repo's alt folder for you to review. Look for files with *-gcp* in their names.
Service account authorization
When working purely in the cloud, there generally aren't humans nor (human) user-owned data, so that's why service accounts and service account authorization are primarily used with Google Cloud. However, Google Workspace documents are generally owned by (human) users, so that's why this tutorial uses user account authorization. That doesn't mean it's not possible to use Google Workspace APIs with service accounts. As long as those accounts have the appropriate access level, they can certainly be used in applications. Similar to the above, alternative versions using service account authorization are available in the repo's alt folder for you to review. Look for files with *-svc* in their names.
Alternative version catalog
Below, you'll find all alternative versions of final/analyze_gsimg.py , each having one or more of the properties above. In each version's filename, look for:
- "
oldauth" for versions using the older auth libraries (in addition tofinal/analyze_gsimg.py) - "
newauth" for those using the current/newer auth libraries - "
gcp" for those using Google Cloud product client libraries, ie, google-cloud-storage, etc. - "
svc" for those using a service account ("svc acct") auth instead of a user account
Here are all the versions:
ফাইলের নাম | বর্ণনা |
| The primary sample; uses the older auth libraries |
| Same as |
| Same as |
| Same as |
| Same as |
| Same as |
| Same as |
| Same as |
Coupled with the original final/analyze_gsimg.py , you have all possible combinations of the final solution, regardless of your Google API development environment, and can choose the one which best suits your needs. Also see alt/README.md for a similar explanation.
Additional Study
Below are a few ideas of how you can take this exercise a step or two further. The problem set the current solution can handle can be expanded allowing you to make these enhancements:
- ( multiple images in folders ) Instead of processing one image, let's say you had images in Google Drive folders .
- ( multiple images in ZIP files ) Instead of a folder of images, how about ZIP archives containing image files? If using Python, consider the
zipfilemodule . - ( analyze Vision labels ) Cluster similar images together, perhaps start by looking for the most common labels, then the 2nd most common, and so on.
- ( create charts ) Follow-up #3, generate charts with the Sheets API based on the Vision API analysis and categorization
- ( categorize documents ) Instead of analyzing images with the Cloud Vision API, let's say you have PDF files to categorize with the Cloud Natural Language API . Using your solutions above, these PDFs can be in Drive folders or ZIP archives on Drive.
- ( create presentations ) Use the Slides API to generate a slide deck from the contents of the Google Sheet report. For inspiration, check out this blog post & video on generating slides from spreadsheet data.
- ( export as PDF ) Export the spreadsheet and/or slide deck as PDF, however this isn't a feature of either the Sheets nor Slides APIs. Hint : Google Drive API. Extra credit : merge both the Sheets and Slides PDFs into one master PDF with tools like Ghostscript (Linux, Windows) or
Combine PDF Pages.action(Mac OS X).
আরও জানুন
কোডল্যাবস
- Intro to Google Workspace APIs (Google Drive API) (Python)
- Using Cloud Vision with Python (Python)
- Build customized reporting tools (Google Sheets API) (JS/Node)
- Upload objects to Google Cloud Storage (no coding required)
সাধারণ
গুগল ওয়ার্কস্পেস
- Google Drive API home page
- Google Sheets API home page
- Google Workspace developer overview & documentation
গুগল ক্লাউড
- Google Cloud Storage home page
- Google Cloud Vision home page & live demo
- Cloud Vision API documentation
- Vision API image labeling docs
- Python on Google Cloud
- Google Cloud product client libraries
- Google Cloud documentation
লাইসেন্স
এই কাজটি ক্রিয়েটিভ কমন্স অ্যাট্রিবিউশন ২.০ জেনেরিক লাইসেন্সের অধীনে রয়েছে।