ছবি সংরক্ষণাগার, বিশ্লেষণ এবং প্রতিবেদন তৈরি করা Google Workspace & গুগল ক্লাউড

1. ওভারভিউ

এই কোডল্যাব একটি সম্ভাব্য এন্টারপ্রাইজ ওয়ার্কফ্লো কল্পনা করে: চিত্র সংরক্ষণাগার, বিশ্লেষণ এবং প্রতিবেদন তৈরি করা। কল্পনা করুন যে আপনার সংস্থার একটি সীমাবদ্ধ সম্পদের উপর স্থান দখল করে ছবিগুলির একটি সিরিজ রয়েছে। আপনি সেই ডেটা আর্কাইভ করতে চান, সেই ছবিগুলিকে বিশ্লেষণ করতে চান, এবং সবচেয়ে গুরুত্বপূর্ণভাবে, সংরক্ষণাগারভুক্ত অবস্থানগুলির সংক্ষিপ্ত বিবরণ এবং বিশ্লেষণের ফলাফলগুলি, সমন্বিত এবং পরিচালনার দ্বারা ব্যবহারের জন্য প্রস্তুত একটি প্রতিবেদন তৈরি করতে চান৷ Google ক্লাউড তার দুটি পণ্য লাইন, Google Workspace (আগে, G Suite বা Google Apps) এবং Google ক্লাউড (আগে, GCP) থেকে API ব্যবহার করে এটি ঘটানোর জন্য সরঞ্জাম সরবরাহ করে।

আমাদের পরিস্থিতিতে, ব্যবসায়িক ব্যবহারকারীর Google ড্রাইভে ছবি থাকবে। Google ক্লাউড স্টোরেজ থেকে উপলব্ধ স্টোরেজ ক্লাসের মতো "ঠান্ডা," সস্তা সঞ্চয়স্থানে ব্যাক আপ করা বোধগম্য। Google ক্লাউড ভিশন ডেভেলপারদের সহজেই অ্যাপ্লিকেশনের মধ্যে দৃষ্টি সনাক্তকরণ বৈশিষ্ট্যগুলিকে একীভূত করতে দেয়, যার মধ্যে বস্তু এবং ল্যান্ডমার্ক সনাক্তকরণ, অপটিক্যাল ক্যারেক্টার রিকগনিশন (OCR) ইত্যাদি অন্তর্ভুক্ত রয়েছে৷ অবশেষে, একটি Google শীট স্প্রেডশীট হল আপনার বসের জন্য এই সমস্তের সংক্ষিপ্তসারের জন্য একটি দরকারী ভিজ্যুয়ালাইজেশন টুল৷

একটি সমাধান তৈরি করতে এই কোডল্যাবটি সম্পূর্ণ করার পরে যা সমস্ত Google ক্লাউডের সুবিধা দেয়, আমরা আশা করি আপনি আপনার প্রতিষ্ঠান বা আপনার গ্রাহকদের জন্য আরও বেশি প্রভাবশালী কিছু তৈরি করতে অনুপ্রাণিত হবেন।

আপনি কি শিখবেন

  • ক্লাউড শেল কিভাবে ব্যবহার করবেন
  • কীভাবে API অনুরোধগুলি প্রমাণীকরণ করবেন
  • পাইথনের জন্য গুগল এপিআই ক্লায়েন্ট লাইব্রেরি কীভাবে ইনস্টল করবেন
  • কিভাবে গুগল এপিআই সক্ষম করবেন
  • কিভাবে গুগল ড্রাইভ থেকে ফাইল ডাউনলোড করবেন
  • ক্লাউড স্টোরেজে কীভাবে অবজেক্ট/ব্লব আপলোড করবেন
  • ক্লাউড ভিশন দিয়ে কীভাবে ডেটা বিশ্লেষণ করবেন
  • কিভাবে গুগল শীটে সারি লিখতে হয়

আপনি কি প্রয়োজন হবে

  • একটি Google অ্যাকাউন্ট (Google Workspace অ্যাকাউন্টের জন্য অ্যাডমিনিস্ট্রেটরের অনুমোদনের প্রয়োজন হতে পারে)
  • একটি সক্রিয় Google ক্লাউড বিলিং অ্যাকাউন্ট সহ একটি Google ক্লাউড প্রকল্প৷
  • অপারেটিং সিস্টেম টার্মিনাল/শেল কমান্ডের সাথে পরিচিতি
  • পাইথনে মৌলিক দক্ষতা (2 বা 3), কিন্তু আপনি যে কোনো সমর্থিত ভাষা ব্যবহার করতে পারেন

উপরে তালিকাভুক্ত চারটি Google ক্লাউড পণ্যের সাথে অভিজ্ঞতা থাকা সহায়ক হবে কিন্তু প্রয়োজন নেই৷ যদি সময় আপনাকে প্রথমে তাদের সাথে আলাদাভাবে পরিচিত হওয়ার অনুমতি দেয়, তাহলে এখানে অনুশীলনটি মোকাবেলা করার আগে প্রতিটির জন্য কোডল্যাব করতে আপনাকে স্বাগত জানাই:

সমীক্ষা

আপনি কিভাবে এই টিউটোরিয়াল ব্যবহার করবেন?

শুধুমাত্র মাধ্যমে এটি পড়ুন এটি পড়ুন এবং ব্যায়াম সম্পূর্ণ করুন

পাইথনের সাথে আপনার অভিজ্ঞতাকে আপনি কীভাবে মূল্যায়ন করবেন?

নবজাতক মধ্যবর্তী দক্ষ

আপনি Google ক্লাউড পরিষেবাগুলি ব্যবহার করার সাথে আপনার অভিজ্ঞতাকে কীভাবে মূল্যায়ন করবেন?

নবজাতক মধ্যবর্তী দক্ষ

Google Workspace ডেভেলপার পরিষেবা ব্যবহার করার ক্ষেত্রে আপনার অভিজ্ঞতাকে আপনি কীভাবে মূল্যায়ন করবেন?

নবজাতক মধ্যবর্তী দক্ষ

আপনি কি আরও "ব্যবসা-ভিত্তিক" কোডল্যাব বনাম যেগুলি পণ্য বৈশিষ্ট্য পরিচিতি দেখতে চান?

হ্যাঁ না উভয়েরই বেশি

2. সেটআপ এবং প্রয়োজনীয়তা

স্ব-গতিসম্পন্ন পরিবেশ সেটআপ

  1. Google ক্লাউড কনসোলে সাইন-ইন করুন এবং একটি নতুন প্রকল্প তৈরি করুন বা বিদ্যমান একটি পুনরায় ব্যবহার করুন৷ আপনার যদি ইতিমধ্যেই একটি Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তাহলে আপনাকে অবশ্যই একটি তৈরি করতে হবে।

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • প্রকল্পের নাম এই প্রকল্পের অংশগ্রহণকারীদের জন্য প্রদর্শনের নাম। এটি একটি অক্ষর স্ট্রিং যা Google API দ্বারা ব্যবহৃত হয় না। আপনি যে কোনো সময় এটি আপডেট করতে পারেন.
  • সমস্ত Google ক্লাউড প্রজেক্ট জুড়ে প্রোজেক্ট আইডি অবশ্যই অনন্য হতে হবে এবং অপরিবর্তনীয় (সেট করার পরে পরিবর্তন করা যাবে না)। ক্লাউড কনসোল স্বয়ংক্রিয়ভাবে একটি অনন্য স্ট্রিং তৈরি করে; সাধারণত আপনি এটা কি যত্ন না. বেশিরভাগ কোডল্যাবে, আপনাকে প্রজেক্ট আইডি উল্লেখ করতে হবে (এটি সাধারণত PROJECT_ID হিসাবে চিহ্নিত করা হয়)। আপনি যদি জেনারেট করা আইডি পছন্দ না করেন, তাহলে আপনি অন্য এলোমেলো আইডি তৈরি করতে পারেন। বিকল্পভাবে, আপনি নিজের চেষ্টা করে দেখতে পারেন এবং এটি উপলব্ধ কিনা। এই ধাপের পরে এটি পরিবর্তন করা যাবে না এবং প্রকল্পের সময়কালের জন্য থাকবে।
  • আপনার তথ্যের জন্য, একটি তৃতীয় মান রয়েছে, একটি প্রকল্প নম্বর যা কিছু API ব্যবহার করে। ডকুমেন্টেশনে এই তিনটি মান সম্পর্কে আরও জানুন।
  1. এরপরে, ক্লাউড রিসোর্স/এপিআই ব্যবহার করতে আপনাকে ক্লাউড কনসোলে বিলিং সক্ষম করতে হবে। এই কোডল্যাবের মাধ্যমে চালানোর জন্য খুব বেশি খরচ করা উচিত নয়, যদি কিছু থাকে। রিসোর্স বন্ধ করতে যাতে এই টিউটোরিয়ালের বাইরে আপনার বিলিং খরচ না হয়, আপনি আপনার তৈরি করা রিসোর্স মুছে ফেলতে পারেন বা পুরো প্রোজেক্ট মুছে ফেলতে পারেন। Google ক্লাউডের নতুন ব্যবহারকারীরা $300 USD বিনামূল্যের ট্রায়াল প্রোগ্রামের জন্য যোগ্য৷

ক্লাউড শেল শুরু করুন

সারাংশ

আপনি যখন আপনার ল্যাপটপে স্থানীয়ভাবে কোড বিকাশ করতে পারেন, তখন এই কোডল্যাবের একটি মাধ্যমিক লক্ষ্য হল আপনাকে কীভাবে Google ক্লাউড শেল ব্যবহার করতে হয় তা শেখানো, আপনার আধুনিক ওয়েব ব্রাউজারের মাধ্যমে ক্লাউডে চলমান একটি কমান্ড-লাইন পরিবেশ।

ক্লাউড শেল সক্রিয় করুন

  1. ক্লাউড কনসোল থেকে, ক্লাউড শেল সক্রিয় করুন ক্লিক করুন 853e55310c205094.png .

55efc1aaa7a4d3ad.png

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

9c92662c6a846a5c.png

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

9f0e51b578fecce5.png

এই ভার্চুয়াল মেশিনটি আপনার প্রয়োজনীয় সমস্ত ডেভেলপমেন্ট টুল দিয়ে লোড করা হয়েছে। এটি একটি ক্রমাগত 5GB হোম ডিরেক্টরি অফার করে এবং Google ক্লাউডে চলে, যা নেটওয়ার্ক কর্মক্ষমতা এবং প্রমাণীকরণকে ব্যাপকভাবে উন্নত করে। এই কোডল্যাবে আপনার অনেক কাজ, যদি সব না হয়, শুধুমাত্র একটি ব্রাউজার বা আপনার Chromebook দিয়ে করা যেতে পারে।

একবার ক্লাউড শেলের সাথে সংযুক্ত হয়ে গেলে, আপনি দেখতে পাবেন যে আপনি ইতিমধ্যেই প্রমাণীকরণ করেছেন এবং প্রকল্পটি ইতিমধ্যে আপনার প্রকল্প আইডিতে সেট করা আছে।

  1. আপনি প্রমাণীকৃত কিনা তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:
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 কমান্ড আপনার প্রকল্প সম্পর্কে জানে তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:
gcloud config list project

কমান্ড আউটপুট

[core]
project = <PROJECT_ID>

যদি এটি না হয়, আপনি এই কমান্ড দিয়ে এটি সেট করতে পারেন:

gcloud config set project <PROJECT_ID>

কমান্ড আউটপুট

Updated property [core/project].

3. পাইথন পরিবেশ নিশ্চিত করুন

এই কোডল্যাবের জন্য আপনাকে পাইথন ভাষা ব্যবহার করতে হবে (যদিও অনেক ভাষা Google API ক্লায়েন্ট লাইব্রেরি দ্বারা সমর্থিত , তাই নির্দ্বিধায় আপনার পছন্দের ডেভেলপমেন্ট টুলে সমতুল্য কিছু তৈরি করুন এবং পাইথনকে সিউডোকোড হিসেবে ব্যবহার করুন)। বিশেষ করে, এই কোডল্যাবটি পাইথন 2 এবং 3 সমর্থন করে, তবে আমরা যত তাড়াতাড়ি সম্ভব 3.x এ সরানোর পরামর্শ দিই।

ক্লাউড শেল সরাসরি ক্লাউড কনসোল থেকে ব্যবহারকারীদের জন্য উপলব্ধ একটি সুবিধাজনক টুল এবং স্থানীয় উন্নয়ন পরিবেশের প্রয়োজন হয় না, তাই এই টিউটোরিয়ালটি একটি ওয়েব ব্রাউজার দিয়ে সম্পূর্ণরূপে ক্লাউডে করা যেতে পারে। আরও বিশেষভাবে এই কোডল্যাবের জন্য, ক্লাউড শেল ইতিমধ্যেই পাইথনের উভয় সংস্করণই প্রাক-ইনস্টল করেছে।

ক্লাউড শেলে আইপিথন ইনস্টল করা আছে: এটি একটি উচ্চ-স্তরের ইন্টারেক্টিভ পাইথন দোভাষী যা আমরা সুপারিশ করি, বিশেষ করে যদি আপনি ডেটা বিজ্ঞান বা মেশিন লার্নিং সম্প্রদায়ের অংশ হন। আপনি যদি হন, IPython হল Jupyter Notebook- এর পাশাপাশি Colab , Jupyter Notebook-এর জন্য Google Research দ্বারা হোস্ট করা ডিফল্ট ইন্টারপ্রেটার৷

IPython প্রথমে একটি Python 3 ইন্টারপ্রেটারকে সমর্থন করে কিন্তু 3.x উপলব্ধ না হলে Python 2-এ ফিরে যায়। আইপিথন ক্লাউড শেল থেকে অ্যাক্সেস করা যেতে পারে তবে স্থানীয় উন্নয়ন পরিবেশেও ইনস্টল করা যেতে পারে। ^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]:

যদি আইপিথন আপনার পছন্দ না হয়, তাহলে একটি আদর্শ পাইথন ইন্টারেক্টিভ ইন্টারপ্রেটার (ক্লাউড শেল বা আপনার স্থানীয় উন্নয়ন পরিবেশ) ব্যবহার সম্পূর্ণরূপে গ্রহণযোগ্য (এছাড়াও ^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 ইনস্টলেশন টুল (পাইথন প্যাকেজ ম্যানেজার এবং নির্ভরতা সমাধানকারী) রয়েছে। এটি 2.7.9+ বা 3.4+ সংস্করণের সাথে বান্ডিল করে আসে। আপনার যদি পুরানো পাইথন সংস্করণ থাকে তবে ইনস্টলেশন নির্দেশাবলীর জন্য এই নির্দেশিকাটি দেখুন। আপনার অনুমতির উপর নির্ভর করে, আপনার sudo বা সুপার ইউজার অ্যাক্সেসের প্রয়োজন হতে পারে, তবে সাধারণত এটি হয় না। নির্দিষ্ট পাইথন সংস্করণের জন্য pip চালানোর জন্য আপনি স্পষ্টভাবে pip2 বা pip3 ব্যবহার করতে পারেন।

কোডল্যাবের বাকি অংশ ধরে নেয় যে আপনি Python 3 ব্যবহার করছেন— Python 2-এর জন্য নির্দিষ্ট নির্দেশাবলী দেওয়া হবে যদি সেগুলি 3.x থেকে উল্লেখযোগ্যভাবে আলাদা হয়।

[ঐচ্ছিক] ভার্চুয়াল পরিবেশ তৈরি করুন এবং ব্যবহার করুন

এই বিভাগটি ঐচ্ছিক এবং শুধুমাত্র তাদের জন্য প্রয়োজন যারা এই কোডল্যাবের জন্য একটি ভার্চুয়াল পরিবেশ ব্যবহার করতে হবে (উপরের সতর্কতা সাইডবার অনুসারে)। যদি আপনার কম্পিউটারে শুধুমাত্র পাইথন 3 থাকে, তাহলে আপনি my_env নামে একটি ভার্চুয়ালেনভ তৈরি করতে এই কমান্ডটি জারি করতে পারেন (যদি ইচ্ছা হয় অন্য নাম বেছে নিতে পারেন):

virtualenv my_env

যাইহোক, যদি আপনার কম্পিউটারে Python 2 এবং 3 উভয়ই থাকে, তাহলে আমরা আপনাকে একটি Python 3 virtualenv ইনস্টল করার পরামর্শ দিই যা আপনি -p flag সাথে এইভাবে করতে পারেন:

virtualenv -p python3 my_env

আপনার সদ্য তৈরি ভার্চুয়ালেনভকে এভাবে "সক্রিয়" করে লিখুন:

source my_env/bin/activate

আপনার শেল প্রম্পটটি পর্যবেক্ষণ করে নিশ্চিত করুন যে আপনি পরিবেশে আছেন এখন আপনার পরিবেশের নামের আগে, অর্থাৎ,

(my_env) $ 

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

4. পাইথনের জন্য Google APIs ক্লায়েন্ট লাইব্রেরি ইনস্টল করুন

এই কোডল্যাবের জন্য Python এর জন্য Google APIs ক্লায়েন্ট লাইব্রেরি ব্যবহার করা প্রয়োজন, তাই হয় এটি একটি সহজ ইনস্টল প্রক্রিয়া, অথবা, আপনাকে কিছু করতে হবে না।

আমরা আগে সুপারিশ করেছি যে আপনি সুবিধার জন্য ক্লাউড শেল ব্যবহার করার কথা বিবেচনা করুন। আপনি ক্লাউডে একটি ওয়েব ব্রাউজার থেকে সম্পূর্ণ টিউটোরিয়ালটি সম্পূর্ণ করতে পারেন। ক্লাউড শেল ব্যবহার করার আরেকটি কারণ হল অনেক জনপ্রিয় ডেভেলপমেন্ট টুল এবং প্রয়োজনীয় লাইব্রেরি ইতিমধ্যেই প্রি-ইনস্টল করা আছে।

*ক্লায়েন্ট লাইব্রেরি ইনস্টল করুন

( ঐচ্ছিক ) আপনি যদি ক্লাউড শেল বা স্থানীয় পরিবেশ ব্যবহার করেন যেখানে আপনি ইতিমধ্যেই ক্লায়েন্ট লাইব্রেরিগুলি ইনস্টল করেছেন তবে এটি এড়ানো যেতে পারে। আপনি যদি স্থানীয়ভাবে বিকাশ করছেন এবং সেগুলি ইনস্টল করেছেন (বা আপনি নিশ্চিত না) তাহলেই আপনাকে এটি করতে হবে। সবচেয়ে সহজ উপায় হল ইনস্টল করার জন্য pip (বা pip3 ) ব্যবহার করা (প্রয়োজনে pip নিজেই আপডেট করা সহ):

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

ইনস্টলেশন নিশ্চিত করুন

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

python3 -c "import googleapiclient, httplib2, oauth2client"

আপনি যদি এর পরিবর্তে 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 APIs সক্ষম করুন" এ যান৷

5. *অনুমোদিত API অনুরোধ (ব্যবহারকারীর অনুমোদন)

আপনি যদি ইতিমধ্যে ব্যবহারকারীর অ্যাকাউন্ট অনুমোদনের শংসাপত্র তৈরি করে থাকেন এবং প্রক্রিয়াটির সাথে পরিচিত হন তবে এই বিভাগটি এড়ানো যেতে পারে। এটি পরিষেবা অ্যাকাউন্ট অনুমোদনের থেকে ভিন্ন যার কৌশল ভিন্ন, তাই অনুগ্রহ করে নীচে চালিয়ে যান।

অনুমোদনের ভূমিকা (প্লাস কিছু প্রমাণীকরণ)

API-কে অনুরোধ করার জন্য, আপনার আবেদনের যথাযথ অনুমোদন থাকা প্রয়োজন। প্রমাণীকরণ , একটি অনুরূপ শব্দ, লগইন শংসাপত্রগুলিকে বর্ণনা করে—আপনি একটি লগইন এবং পাসওয়ার্ড দিয়ে আপনার Google অ্যাকাউন্টে লগ ইন করার সময় নিজেকে প্রমাণীকরণ করেন৷ একবার প্রমাণীকরণ হয়ে গেলে, পরবর্তী ধাপ হল আপনি কিনা—বা বরং, আপনার কোড ,— ডেটা অ্যাক্সেস করার জন্য অনুমোদিত , যেমন ক্লাউড স্টোরেজের ব্লব ফাইল বা Google ড্রাইভে ব্যবহারকারীর ব্যক্তিগত ফাইল৷

Google APIগুলি বিভিন্ন ধরণের অনুমোদন সমর্থন করে, কিন্তু G Suite API ব্যবহারকারীদের জন্য সবচেয়ে সাধারণ একটি হল ব্যবহারকারীর অনুমোদন যেহেতু এই কোডল্যাবের উদাহরণ অ্যাপ্লিকেশনটি শেষ-ব্যবহারকারীদের সম্পর্কিত ডেটা অ্যাক্সেস করে। সেই শেষ-ব্যবহারকারীদের অবশ্যই তাদের ডেটা অ্যাক্সেস করার জন্য আপনার অ্যাপের অনুমতি দিতে হবে। এর মানে আপনার কোডটি অবশ্যই ব্যবহারকারীর অ্যাকাউন্ট OAuth2 শংসাপত্রগুলি পেতে হবে৷

ব্যবহারকারীর অনুমোদনের জন্য OAuth2 শংসাপত্রগুলি পেতে, API পরিচালকে ফিরে যান এবং বাম-নেভিতে "শংসাপত্র" ট্যাবটি নির্বাচন করুন:

635af008256d323.png

আপনি যখন সেখানে পৌঁছাবেন, আপনি তিনটি পৃথক বিভাগে আপনার সমস্ত শংসাপত্র দেখতে পাবেন:

fd2f4133b406d572.png

প্রথমটি API কীগুলির জন্য, দ্বিতীয়টি OAuth 2.0 ক্লায়েন্ট আইডি, এবং শেষটি OAuth2 পরিষেবা অ্যাকটিসের জন্য — আমরা মাঝখানে একটি ব্যবহার করছি৷

শংসাপত্র তৈরি করা হচ্ছে

শংসাপত্র পৃষ্ঠা থেকে, শীর্ষে + শংসাপত্র তৈরি করুন বোতামে ক্লিক করুন, যা আপনাকে একটি ডায়ালগ দেয় যেখানে আপনি "OAuth ক্লায়েন্ট আইডি:" চয়ন করবেন।

b17b663668e38787.png

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

4e0b967c9d70d262.png

আপনি যদি একটি সম্মতি স্ক্রীন সেট না করে থাকেন, তাহলে আপনি কনসোলে সতর্কতা দেখতে পাবেন এবং এখনই তা করতে হবে। (যদি আপনার সম্মতি স্ক্রীন ইতিমধ্যেই সেটআপ করা হয়ে থাকে তবে এই পরবর্তী পদক্ষেপগুলি এড়িয়ে যান।)

"সম্মতি স্ক্রীন কনফিগার করুন"-এ ক্লিক করুন যেখানে আপনি একটি "বহিরাগত" অ্যাপ (বা আপনি যদি একজন G Suite গ্রাহক হন তাহলে "অভ্যন্তরীণ") বেছে নিন:

f17e97b30d994b0c.png

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

b107ab81349bdad2.png

এই মুহুর্তে আপনার কেবলমাত্র একটি অ্যাপ্লিকেশনের নাম প্রয়োজন তাই এমন কাউকে বেছে নিন যা আপনি যে কোডল্যাবটি করছেন তা প্রতিফলিত করে তারপর সংরক্ষণ করুন ক্লিক করুন।

OAuth ক্লায়েন্ট আইডি তৈরি করা হচ্ছে (ব্যবহারকারীর অ্যাক্ট প্রমাণ)

এখন একটি OAuth2 ক্লায়েন্ট আইডি তৈরি করতে শংসাপত্র ট্যাবে ফিরে যান। এখানে আপনি বিভিন্ন ধরনের OAuth ক্লায়েন্ট আইডি দেখতে পাবেন যা আপনি তৈরি করতে পারেন:

5ddd365ac0af1e34.png

আমরা একটি কমান্ড-লাইন টুল ডেভেলপ করছি, যেটি হল Other , তাই সেটি বেছে নিন তারপর Create বাটনে ক্লিক করুন। আপনি যে অ্যাপটি তৈরি করছেন তা প্রতিফলিত করে এমন একটি ক্লায়েন্ট আইডি নাম চয়ন করুন বা কেবল ডিফল্ট নাম নিন, যা সাধারণত, "অন্যান্য ক্লায়েন্ট 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 সম্মতি স্ক্রীনে আবেদনের নামের জন্য, আমরা "ভিশন API ডেমো" বেছে নিয়েছি, তাই আসন্ন কিছু স্ক্রিনশটে এটি দেখতে আশা করি।

6. Google API সক্রিয় করুন৷

এই কোডল্যাবটি চারটি (4) Google ক্লাউড API, Google ক্লাউড (ক্লাউড স্টোরেজ এবং ক্লাউড ভিশন) থেকে একটি জোড়া এবং Google Workspace (Google Drive এবং Google Sheets) থেকে আরেকটি জোড়া ব্যবহার করে। নীচে Google API সক্রিয় করার জন্য সাধারণ নির্দেশাবলী রয়েছে৷ একবার আপনি কীভাবে একটি API সক্ষম করবেন তা জানলে, অন্যগুলি একই রকম।

আপনি আপনার অ্যাপ্লিকেশনে যে Google API ব্যবহার করতে চান তা নির্বিশেষে, সেগুলি অবশ্যই সক্ষম হতে হবে। এপিআই কমান্ড-লাইন বা ক্লাউড কনসোল থেকে সক্ষম করা যেতে পারে। এপিআই সক্ষম করার প্রক্রিয়াটি অভিন্ন, তাই আপনি একবার একটি এপিআই সক্ষম করলে, আপনি একইভাবে অন্যকে সক্ষম করতে পারেন।

বিকল্প 1: gcloud কমান্ড-লাইন ইন্টারফেস (ক্লাউড শেল বা স্থানীয় পরিবেশ)

ক্লাউড কনসোল থেকে এপিআই সক্ষম করা আরও সাধারণ, কিছু বিকাশকারী কমান্ড লাইন থেকে সবকিছু করতে পছন্দ করে। এটি করার জন্য, আপনাকে একটি API এর "পরিষেবার নাম" সন্ধান করতে হবে। এটি একটি URL এর মত দেখাচ্ছে: SERVICE_NAME .googleapis.com । আপনি এগুলিকে সমর্থিত পণ্যের চার্টে খুঁজে পেতে পারেন, অথবা আপনি Google Discovery API- এর মাধ্যমে প্রোগ্রাম্যাটিকভাবে তাদের জন্য অনুসন্ধান করতে পারেন৷

এই তথ্য দিয়ে সজ্জিত, ক্লাউড শেল ব্যবহার করে (অথবা gcloud কমান্ড-লাইন টুল ইনস্টল করা আপনার স্থানীয় উন্নয়ন পরিবেশ), আপনি একটি API বা পরিষেবা সক্রিয় করতে পারেন, নিম্নরূপ:

gcloud services enable SERVICE_NAME.googleapis.com

উদাহরণ 1: ক্লাউড ভিশন API সক্ষম করুন

gcloud services enable vision.googleapis.com

উদাহরণ 2: Google অ্যাপ ইঞ্জিন সার্ভারহীন গণনা প্ল্যাটফর্ম সক্ষম করুন৷

gcloud services enable appengine.googleapis.com

উদাহরণ 3: একটি অনুরোধের সাথে একাধিক API সক্রিয় করুন। উদাহরণস্বরূপ, যদি এই কোডল্যাবে দর্শকরা অ্যাপ ইঞ্জিন, ক্লাউড ফাংশন এবং ক্লাউড রানে ক্লাউড ট্রান্সলেশন API ব্যবহার করে একটি অ্যাপ স্থাপন করে, কমান্ড লাইনটি হবে:

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

এই কমান্ডটি অ্যাপ ইঞ্জিন, ক্লাউড ফাংশন, ক্লাউড রান এবং ক্লাউড অনুবাদ API সক্ষম করে। উপরন্তু, এটি ক্লাউড আর্টিফ্যাক্ট রেজিস্ট্রি সক্ষম করে কারণ ক্লাউড রানে স্থাপন করার জন্য ক্লাউড বিল্ড সিস্টেম দ্বারা কন্টেইনার চিত্রগুলিকে অবশ্যই নিবন্ধিত করতে হবে৷

এপিআই সক্ষম করার জন্য বা কোন APIগুলি ইতিমধ্যে আপনার প্রকল্পের জন্য সক্ষম করা হয়েছে তার জন্য অনুসন্ধান করার জন্য কয়েকটি কমান্ড রয়েছে।

উদাহরণ 4: আপনার প্রকল্পের জন্য সক্ষম করার জন্য উপলব্ধ Google API-এর জন্য কোয়েরি

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

উদাহরণ 5: আপনার প্রকল্পের জন্য সক্রিয় Google API-এর জন্য প্রশ্ন

gcloud services list

উপরের কমান্ডগুলি সম্পর্কে আরও তথ্যের জন্য, পরিষেবাগুলি সক্রিয় এবং নিষ্ক্রিয় করা এবং পরিষেবাগুলির তালিকাভুক্তকরণ ডকুমেন্টেশন দেখুন৷

বিকল্প 2: ক্লাউড কনসোল

আপনি API ম্যানেজারে Google API গুলিও সক্ষম করতে পারেন৷ ক্লাউড কনসোল থেকে, API ম্যানেজারে যান। এই ড্যাশবোর্ড পৃষ্ঠায়, আপনি আপনার অ্যাপের জন্য কিছু ট্র্যাফিক তথ্য, অ্যাপ্লিকেশন অনুরোধগুলি দেখানো গ্রাফ, আপনার অ্যাপের দ্বারা তৈরি ত্রুটি এবং আপনার অ্যাপের প্রতিক্রিয়ার সময় দেখতে পাবেন:

df4a0a5e00d29ffc.png

এই চার্টগুলির নীচে আপনার প্রকল্পের জন্য সক্রিয় Google APIগুলির একটি তালিকা রয়েছে:

5fcf10e5a05cfb97.png

APIs সক্ষম (বা নিষ্ক্রিয়) করতে, শীর্ষে API এবং পরিষেবাগুলি সক্ষম করুন ক্লিক করুন:

eef4e5e863f4db66.png

বিকল্পভাবে, বাম-নেভিগেশন বারে যান এবং APIs এবং পরিষেবালাইব্রেরি নির্বাচন করুন :

6eda5ba145b30b97.png

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

5d4f1c8e7cf8df28.png

সার্চ করতে এবং মিলিত ফলাফল দেখতে একটি API নাম লিখুন:

35bc4b9cf72ce9a4.png

আপনি যে APIটি সক্ষম করতে চাইছেন সেটি নির্বাচন করুন এবং সক্ষম বোতামটি ক্লিক করুন:

9574a69ef8d9e8d2.png

আপনি যে Google API ব্যবহার করতে চান তা নির্বিশেষে সমস্ত API সক্রিয় করার প্রক্রিয়া একই রকম।

খরচ

অনেক Google API ফি ছাড়াই ব্যবহার করা যেতে পারে, তবে বেশিরভাগ Google ক্লাউড পণ্য এবং API ব্যবহার করার সময় খরচ আছে। ক্লাউড API সক্রিয় করার সময়, আপনাকে একটি সক্রিয় বিলিং অ্যাকাউন্টের জন্য বলা হতে পারে৷ যাইহোক, কিছু Google ক্লাউড পণ্যে একটি "সর্বদা বিনামূল্যে" স্তর রয়েছে, যা আপনাকে বিলিং চার্জ বহন করার জন্য অতিক্রম করতে হবে।

নতুন Google ক্লাউড ব্যবহারকারীরা বিনামূল্যে ট্রায়ালের জন্য যোগ্য, বর্তমানে প্রথম 90 দিনের জন্য $300USD ভাল৷ কোডল্যাবগুলি সাধারণত খুব বেশি বা কোনও বিলিং খরচ করে না, তাই আমরা আপনাকে বিনামূল্যে ট্রায়াল বন্ধ রাখার পরামর্শ দিচ্ছি যতক্ষণ না আপনি এটিকে একটি টেস্ট ড্রাইভ দেওয়ার জন্য প্রস্তুত না হন, বিশেষ করে যেহেতু এটি একবারের অফার। আপনি বিনামূল্যে ট্রায়াল ব্যবহার করুন বা না করুন নির্বিশেষে বিনামূল্যে স্তরের কোটার মেয়াদ শেষ হয় না এবং প্রয়োগ হয়।

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

বিভিন্ন Google পণ্য আলাদাভাবে বিল করা হয়, তাই সেই তথ্যের জন্য উপযুক্ত ডকুমেন্টেশন উল্লেখ করতে ভুলবেন না।

সারাংশ

এখন যেহেতু ক্লাউড ভিশন সক্ষম করা হয়েছে, একইভাবে অন্য তিনটি API (গুগল ড্রাইভ, ক্লাউড স্টোরেজ, গুগল শীট) চালু করুন। ক্লাউড শেল থেকে, gcloud services enable বা ক্লাউড কনসোল থেকে ব্যবহার করুন:

  1. API লাইব্রেরিতে ফিরে যান
  2. এর নামের কয়েকটি অক্ষর টাইপ করে একটি অনুসন্ধান শুরু করুন
  3. পছন্দসই API নির্বাচন করুন, এবং
  4. সক্ষম করুন

ফেটানো, ধুয়ে ফেলুন এবং পুনরাবৃত্তি করুন। ক্লাউড স্টোরেজের জন্য, বেশ কিছু পছন্দ আছে: "Google ক্লাউড স্টোরেজ JSON API" বেছে নিন। ক্লাউড স্টোরেজ এপিআই একটি সক্রিয় বিলিং অ্যাকাউন্টও আশা করবে।

7. ধাপ 0: সেটআপ আমদানি এবং অনুমোদন কোড

এটি একটি মাঝারি আকারের কোডের সূচনা, তাই কিছুটা চটপটে অভ্যাসগুলি অনুসরণ করা মূল অ্যাপ্লিকেশনটি মোকাবেলা করার আগে একটি সাধারণ, স্থিতিশীল এবং কার্যকরী পরিকাঠামো নিশ্চিত করতে সহায়তা করে। Doublecheck 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)

এই মূল উপাদানটিতে মডিউল/প্যাকেজ আমদানির জন্য কোড ব্লক, ব্যবহারকারীর প্রমাণপত্রের প্রসেসিং এবং API পরিষেবার শেষ পয়েন্ট তৈরি করা অন্তর্ভুক্ত। কোডের মূল অংশগুলি আপনার পর্যালোচনা করা উচিত:

  • print() ফাংশন আমদানি করা এই নমুনা Python 2-3 সামঞ্জস্যপূর্ণ করে তোলে এবং Google লাইব্রেরি আমদানি Google API-এর সাথে যোগাযোগের জন্য প্রয়োজনীয় সমস্ত সরঞ্জাম নিয়ে আসে।
  • SCOPES ভেরিয়েবল ব্যবহারকারীর কাছ থেকে অনুরোধ করার অনুমতিগুলির প্রতিনিধিত্ব করে—এখন শুধুমাত্র একটিই রয়েছে: তাদের Google ড্রাইভ থেকে ডেটা পড়ার অনুমতি
  • ক্রেডেনশিয়াল প্রসেসিং কোডের অবশিষ্টাংশ ক্যাশে করা OAuth2 টোকেনে পড়ে, সম্ভবত রিফ্রেশ টোকেন সহ একটি নতুন অ্যাক্সেস টোকেনে আপডেট করা হয় যদি আসল অ্যাক্সেস টোকেনের মেয়াদ শেষ হয়ে যায়।
  • যদি কোনো টোকেন তৈরি করা না হয় বা অন্য কোনো কারণে বৈধ অ্যাক্সেস টোকেন পুনরুদ্ধার করা ব্যর্থ হয়, ব্যবহারকারীকে অবশ্যই OAuth2 3-লেগড ফ্লো (3LO) এর মধ্য দিয়ে যেতে হবে: অনুরোধ করা অনুমতিগুলির সাথে ডায়ালগ তৈরি করুন এবং ব্যবহারকারীকে গ্রহণ করার জন্য অনুরোধ করুন। একবার তারা হয়ে গেলে, অ্যাপটি চলতে থাকে, অন্যথায় tools.run_flow() একটি ব্যতিক্রম ছুঁড়ে দেয় এবং এক্সিকিউশন বন্ধ করে দেয়।
  • একবার ব্যবহারকারী অনুমতি দিলে, সার্ভারের সাথে যোগাযোগ করার জন্য একটি HTTP ক্লায়েন্ট তৈরি করা হয় এবং সমস্ত অনুরোধ নিরাপত্তার জন্য ব্যবহারকারীর শংসাপত্রের সাথে স্বাক্ষরিত হয়। তারপরে সেই HTTP ক্লায়েন্টের সাথে Google ড্রাইভ এপিআই (সংস্করণ 3) এর একটি পরিষেবা শেষ পয়েন্ট তৈরি করা হয় তারপর 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

আপনি যদি ক্লাউড শেল থেকে দৌড়াচ্ছেন, "ক্লাউড শেল থেকে" বিভাগে এগিয়ে যান তারপর উপযুক্ত হলে "স্থানীয় উন্নয়ন পরিবেশ থেকে" প্রাসঙ্গিক স্ক্রীনগুলি পর্যালোচনা করতে পিছনে স্ক্রোল করুন৷

স্থানীয় উন্নয়ন পরিবেশ থেকে

একটি ব্রাউজার উইন্ডো খোলার সাথে সাথে কমান্ড-লাইন স্ক্রিপ্টটি বিরতি দেওয়া হয়। আপনি একটি ভীতিকর-সুদর্শন সতর্কতা পৃষ্ঠা পেতে পারেন যা দেখতে এইরকম:

149241d33871a141.png

এটি একটি বৈধ উদ্বেগ, কারণ আপনি এমন একটি অ্যাপ চালানোর চেষ্টা করছেন যা ব্যবহারকারীর ডেটা অ্যাক্সেস করে। যেহেতু এটি শুধুমাত্র একটি ডেমো অ্যাপ, এবং আপনি ডেভেলপার, আশা করি আপনি এগিয়ে যাওয়ার জন্য নিজেকে যথেষ্ট বিশ্বাস করেন। এটি আরও ভালভাবে বোঝার জন্য, নিজেকে আপনার ব্যবহারকারীর জুতোয় রাখুন: আপনাকে অন্য কারো কোড আপনার ডেটা অ্যাক্সেস করার অনুমতি দিতে বলা হচ্ছে৷ আপনি যদি এইরকম একটি অ্যাপ প্রকাশ করতে চান, তাহলে আপনি যাচাইকরণ প্রক্রিয়ার মধ্য দিয়ে যাবেন যাতে আপনার ব্যবহারকারীরা এই স্ক্রীনটি দেখতে না পায়৷

"'অনিরাপদ' অ্যাপে যান" লিঙ্কে ক্লিক করার পরে, আপনি একটি OAuth2 অনুমতি ডায়ালগ পাবেন যা দেখতে নিচের মত কিছু হবে—আমরা সর্বদা আমাদের ইউজার ইন্টারফেস উন্নত করছি তাই এটি সঠিক মিল না হলে চিন্তা করবেন না:

a122eb7468d0d34e.png

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

এমনকি আপনি আপনার নিশ্চিতকরণের জন্য জিজ্ঞাসা করে আরও একটি ডায়ালগ পেতে পারেন:

bf171080dcd6ec5.png

দ্রষ্টব্য : কেউ কেউ বিভিন্ন অ্যাকাউন্টে লগ ইন করা একাধিক ওয়েব ব্রাউজার ব্যবহার করে, তাই এই অনুমোদনের অনুরোধটি ভুল ব্রাউজার ট্যাব/উইন্ডোতে যেতে পারে এবং আপনাকে এই অনুরোধের জন্য লিঙ্কটি কাট-এন-পেস্ট করতে হতে পারে এমন একটি ব্রাউজারে যা সঠিক দিয়ে লগ ইন করা আছে। অ্যাকাউন্ট

ক্লাউড শেল থেকে

ক্লাউড শেল থেকে, কোনও ব্রাউজার উইন্ডো পপ আপ হয় না, আপনাকে আটকে রেখে৷ নীচের ডায়াগনস্টিক বার্তাটি আপনার জন্য বোঝানো হয়েছে তা বুঝতে পারেন:

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

40a567cda0f31cc9.png

এই কোডটি কপি করে টার্মিনাল উইন্ডোতে পেস্ট করুন।

সারাংশ

ব্যতীত, " Authentication successful ", কোনো অতিরিক্ত আউটপুট আশা করবেন না৷ মনে রাখবেন এটি শুধুমাত্র সেটআপ... আপনি এখনও কিছু করেননি। আপনি যা করেছেন তা সফলভাবে এমন কিছুতে আপনার যাত্রা শুরু করেছে যা প্রথমবার সঠিকভাবে কার্যকর করার সম্ভাবনা বেশি। (সর্বোত্তম অংশটি হল আপনাকে শুধুমাত্র একবার অনুমোদনের জন্য অনুরোধ করা হয়েছিল; সমস্ত ক্রমাগত মৃত্যুদন্ড এটিকে এড়িয়ে যায় কারণ আপনার অনুমতিগুলি ক্যাশে করা হয়েছে।) এখন আসুন কোডটিকে কিছু বাস্তব কাজ করা যাক যার ফলে প্রকৃত আউটপুট হবে।

সমস্যা সমাধান

আপনি যদি কোনও আউটপুটের পরিবর্তে একটি ত্রুটি পান তবে এটি এক বা একাধিক কারণের কারণে হতে পারে, সম্ভবত এটি:

8. ধাপ 1: গুগল ড্রাইভ থেকে ছবি ডাউনলোড করুন

পূর্ববর্তী ধাপে, আমরা analyze_gsimg.py হিসাবে কোডটি তৈরি করার এবং সেখান থেকে সম্পাদনা করার পরামর্শ দিয়েছি। আইপিথন বা স্ট্যান্ডার্ড পাইথন শেলে সরাসরি সবকিছু কাট-এন-পেস্ট করাও সম্ভব, তবে এটি আরও কষ্টকর কারণ আমরা টুকরো টুকরো অ্যাপ তৈরি করতে যাচ্ছি।

ধরে নিন আপনার অ্যাপ অনুমোদিত হয়েছে এবং API পরিষেবা শেষ পয়েন্ট তৈরি করা হয়েছে। আপনার কোডে, এটি 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

ড্রাইভ files() সংগ্রহে একটি list() পদ্ধতি রয়েছে যা নির্দিষ্ট ফাইলের জন্য একটি কোয়েরি ( q প্যারামিটার) সম্পাদন করে। আপনি কোন রিটার্ন মানগুলিতে আগ্রহী তা নির্দিষ্ট করতে fields প্যারামিটারটি ব্যবহার করা হয়—কেন আপনি যদি অন্য মানগুলির বিষয়ে চিন্তা না করেন তবে সবকিছু ফিরে পেতে এবং জিনিসগুলিকে ধীর করে দেওয়ার জন্য বিরক্ত করবেন? আপনি যদি API রিটার্ন মান ফিল্টার করার জন্য ফিল্ড মাস্কে নতুন হন, তাহলে এই ব্লগ পোস্ট এবং ভিডিওটি দেখুন। অন্যথায় ক্যোয়ারীটি চালান এবং ফিরে আসা files অ্যাট্রিবিউটটি ধরুন, যদি কোনও মিল না থাকে তবে একটি খালি তালিকা অ্যারেতে ডিফল্ট করে৷

যদি কোন ফলাফল না থাকে, বাকি ফাংশন বাদ দেওয়া হয় এবং None ফেরত দেওয়া হয় না (উপলব্ধভাবে)। অন্যথায় প্রথম ম্যাচিং রেসপন্স ( rsp[0] ) ধরুন, ফাইলের নাম, এর MIME টাইপ, সর্বশেষ পরিবর্তনের টাইমস্ট্যাম্প, এবং অবশেষে, এর বাইনারি পেলোড, get_media() ফাংশন (এর ফাইল আইডির মাধ্যমে) দ্বারা পুনরুদ্ধার করুন, files() সংগ্রহ। (অন্যান্য ভাষার ক্লায়েন্ট লাইব্রেরির সাথে পদ্ধতির নাম সামান্য ভিন্ন হতে পারে।)

চূড়ান্ত অংশ হল "প্রধান" বডি পুরো অ্যাপ্লিকেশনটি চালায়:

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)

ড্রাইভে section-work-card-img_2x.jpg নামক একটি চিত্র ধরে নিয়ে এবং FILE এ সেট করা হয়েছে, সফল স্ক্রিপ্ট সম্পাদনের পরে, আপনি আউটপুট দেখতে পাবেন যে এটি ড্রাইভ থেকে ফাইলটি পড়তে সক্ষম হয়েছে (কিন্তু আপনার কম্পিউটারে সংরক্ষিত নয়):

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

সমস্যা সমাধান

আপনি যদি উপরের মত সফল আউটপুট না পান তবে এটি এক বা একাধিক কারণের কারণে হতে পারে, সম্ভবত এটি:

সারাংশ

এই বিভাগে, আপনি শিখেছেন কীভাবে (2টি পৃথক API কলে) একটি নির্দিষ্ট ফাইলের জন্য ড্রাইভ এপিআই ক্যোয়ারী করার পরে এটি ডাউনলোড করে সংযোগ করতে হয়৷ ব্যবসায়িক ব্যবহারের ক্ষেত্রে: আপনার ড্রাইভ ডেটা সংরক্ষণ করুন এবং সম্ভবত এটি বিশ্লেষণ করুন, যেমন Google ক্লাউড সরঞ্জামগুলির সাথে৷ এই পর্যায়ে আপনার অ্যাপের কোডটি step1-drive/analyze_gsimg.py এ রেপোতে যা আছে তার সাথে মেলে।

এখানে Google ড্রাইভে ফাইল ডাউনলোড করার বিষয়ে আরও পড়ুন বা এই ব্লগ পোস্ট এবং ভিডিওটি দেখুন। কোডল্যাবের এই অংশটি Google Workspace APIs কোডল্যাবের সম্পূর্ণ ভূমিকার সাথে প্রায় একই রকম — একটি ফাইল ডাউনলোড করার পরিবর্তে, এটি ব্যবহারকারীর Google ড্রাইভে প্রথম 100টি ফাইল/ফোল্ডার প্রদর্শন করে এবং আরও সীমাবদ্ধ সুযোগ ব্যবহার করে।

9. ধাপ 2: ক্লাউড স্টোরেজে ফাইল সংরক্ষণ করুন

পরবর্তী ধাপ হল Google ক্লাউড স্টোরেজের জন্য সমর্থন যোগ করা। এর জন্য আমাদের আরেকটি পাইথন প্যাকেজ আমদানি করতে হবে, io । আপনার আমদানির শীর্ষ বিভাগটি এখন এইরকম দেখাচ্ছে তা নিশ্চিত করুন:

from __future__ import print_function                   
import io

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

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

বালতিতে একটি শব্দ: ক্লাউড স্টোরেজ নিরাকার ব্লব স্টোরেজ প্রদান করে। সেখানে ফাইল আপলোড করার সময়, এটি Google ড্রাইভের মতো ফাইলের ধরন, এক্সটেনশন ইত্যাদির ধারণা বুঝতে পারে না। তারা ক্লাউড স্টোরেজের জন্য শুধু "ব্লবস"। উপরন্তু, ক্লাউড স্টোরেজে ফোল্ডার বা সাবডিরেক্টরির কোন ধারণা নেই।

হ্যাঁ, আপনি একাধিক সাব-ফোল্ডারের বিমূর্ততা উপস্থাপন করতে ফাইলের নামগুলিতে স্ল্যাশ ( / ) রাখতে পারেন, কিন্তু দিনের শেষে, আপনার সমস্ত ব্লবগুলি একটি বালতিতে চলে যায় এবং " / "গুলি তাদের ফাইলের নামের অক্ষর মাত্র৷ আরও তথ্যের জন্য বালতি এবং বস্তুর নামকরণের পৃষ্ঠাটি দেখুন।

উপরের ধাপ 1 শুধুমাত্র ড্রাইভ পড়ার সুযোগের অনুরোধ করেছে। এই সময়ে, যে সব আপনার প্রয়োজন. এখন, ক্লাউড স্টোরেজে আপলোড (পড়া-লেখা) অনুমতি প্রয়োজন৷ অনুমতি স্কোপের একটি অ্যারে (পাইথন টিপল [বা তালিকা]) থেকে একটি একক স্ট্রিং ভেরিয়েবল থেকে 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 filename" এ ফাইলটি সংরক্ষণাগারভুক্ত করছেন এমন ধারণাটি বন্ধ করে দেয়। প্রথম print() ফাংশনের ঠিক পরে এই অংশটি else ধারাটির ঠিক উপরে স্লিপ করুন যাতে পুরো "মূল" এর মতো দেখাচ্ছে:

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">

সাবধানে দেখুন, ড্রাইভ ডাউনলোড সফল হওয়ার সাথে সাথে ক্লাউড স্টোরেজে আপলোড ব্যর্থ হয়েছে। কেন?

কারণটি হ'ল আমরা যখন এই অ্যাপ্লিকেশনটিকে মূলত 1 ধাপের জন্য অনুমোদিত করেছি তখন আমরা কেবল গুগল ড্রাইভে কেবল পঠনযোগ্য অ্যাক্সেসকে অনুমোদিত করেছি। আমরা ক্লাউড স্টোরেজের জন্য পঠন-লেখার সুযোগটি যুক্ত করার সময়, আমরা কখনই ব্যবহারকারীকে সেই অ্যাক্সেসের অনুমোদন দেওয়ার জন্য অনুরোধ করি নি। এটি কাজ করার জন্য, আমাদের 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'

সারাংশ

এটি একটি বড় ব্যাপার, আপনাকে দেখানো হচ্ছে, কোডের তুলনামূলকভাবে কয়েকটি লাইনে, উভয় ক্লাউড-ভিত্তিক স্টোরেজ সিস্টেমের মধ্যে ফাইলগুলি কীভাবে স্থানান্তর করতে হয়। এখানে ব্যবসায়িক ব্যবহারের ক্ষেত্রে হ'ল "শীতল," সস্তা স্টোরেজ হিসাবে সম্ভবত একটি সীমাবদ্ধ সংস্থান ব্যাকআপ করা। আপনি নিয়মিত, মাসিক, ত্রৈমাসিক বা বার্ষিক আপনার ডেটা অ্যাক্সেস করেন কিনা তার উপর নির্ভর করে ক্লাউড স্টোরেজ বিভিন্ন স্টোরেজ ক্লাস সরবরাহ করে।

অবশ্যই, বিকাশকারীরা গুগল ড্রাইভ এবং ক্লাউড স্টোরেজ উভয়ই কেন বিদ্যমান তা সময়ে সময়ে আমাদের জিজ্ঞাসা করে। সর্বোপরি, তারা উভয়ই মেঘে স্টোরেজ ফাইল করে না? এজন্য আমরা এই ভিডিওটি তৈরি করেছি। এই পর্যায়ে আপনার কোডটি step2-gcs/analyze_gsimg.py -তে রেপোতে যা আছে তা মেলে।

10. পদক্ষেপ 3: মেঘের দৃষ্টি দিয়ে বিশ্লেষণ করুন

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

from __future__ import print_function
import base64
import io

ডিফল্টরূপে, ভিশন এপিআই এটি পাওয়া সমস্ত লেবেল দেয়। বিষয়গুলিকে সামঞ্জস্য রাখতে, আসুন কেবলমাত্র শীর্ষ 5 (অবশ্যই ব্যবহারকারীর দ্বারা সামঞ্জস্যযোগ্য) অনুরোধ করুন। আমরা এর জন্য একটি ধ্রুবক পরিবর্তনশীল TOP ব্যবহার করব; এটি অন্য সমস্ত ধ্রুবকের অধীনে যুক্ত করুন:

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

পূর্ববর্তী পদক্ষেপগুলির মতো, আমাদের আরও একটি অনুমতি সুযোগ প্রয়োজন, এবার ভিশন এপিআইয়ের জন্য। এর স্ট্রিং সহ SCOPES আপডেট করুন:

SCOPES = (
    'https://www.googleapis.com/auth/drive.readonly',
    'https://www.googleapis.com/auth/devstorage.full_control',
    'https://www.googleapis.com/auth/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)

এখন এই ফাংশনটি যুক্ত করুন যা ক্লাউড ভিশনে চিত্রের পে -লোড প্রেরণ করে:

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

এই 5 টি লাইন যা vision_label_img() কে কল করে ক্লাউড স্টোরেজে সফল আপলোডের পরে ঠিক স্থাপন করা উচিত:

            # 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 মুছে ফেলা এবং আপডেট হওয়া অ্যাপ্লিকেশনটি পুনরায় চালানোর ফলে ক্লাউড ভিশন বিশ্লেষণের সংযোজনকে লক্ষ্য করে নিম্নলিখিতগুলির মতো আউটপুট হতে হবে:

$ 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

সারাংশ

প্রত্যেকেরই তাদের ডেটা বিশ্লেষণ করতে তাদের নিজস্ব এমএল মডেল তৈরি এবং প্রশিক্ষণের জন্য মেশিন লার্নিং দক্ষতা নেই। গুগল ক্লাউড টিম সাধারণ ব্যবহারের জন্য গুগলের কিছু প্রাক-প্রশিক্ষিত মডেল সরবরাহ করেছে এবং এপিআইয়ের পিছনে ফেলেছে, যা প্রত্যেকের জন্য এআই ও এমএলকে গণতান্ত্রিক করতে সহায়তা করে।

আপনি যদি একজন বিকাশকারী হন এবং কোনও এপিআই কল করতে পারেন তবে আপনি মেশিন লার্নিং ব্যবহার করতে পারেন। ক্লাউড ভিশন হ'ল আপনার ডেটা বিশ্লেষণ করতে আপনি ব্যবহার করতে পারেন এমন একটি এপিআই পরিষেবাগুলির মধ্যে একটি। এখানে অন্যদের সম্পর্কে শিখুন। আপনার কোডটি এখন step3-vision/analyze_gsimg.py -তে রেপোতে যা আছে তা মেলে।

১১. পদক্ষেপ 4: গুগল শীটগুলির সাথে একটি প্রতিবেদন তৈরি করুন

এই মুহুর্তে, আপনি কর্পোরেট ডেটা সংরক্ষণাগারভুক্ত করতে এবং এটি বিশ্লেষণ করতে সক্ষম হয়েছেন, তবে যা অভাব রয়েছে তা এই কাজের সংক্ষিপ্তসার। আসুন আমরা সমস্ত ফলাফলকে একক প্রতিবেদনে সংগঠিত করি যা আপনি আপনার বসকে হস্তান্তর করতে পারেন। স্প্রেডশিটের চেয়ে পরিচালনার পক্ষে আরও কী উপস্থাপিত?

গুগল শীট এপিআইয়ের জন্য কোনও অতিরিক্ত আমদানির প্রয়োজন নেই এবং কেবলমাত্র নতুন তথ্যের নতুন অংশটি হ'ল ইতিমধ্যে ফর্ম্যাট করা একটি বিদ্যমান স্প্রেডশিটের ফাইল আইডি এবং একটি নতুন সারি ডেটার জন্য অপেক্ষা করছে, তাই SHEET ধ্রুবক। আমরা আপনাকে একটি নতুন স্প্রেডশিট তৈরি করার পরামর্শ দিচ্ছি যা নিম্নলিখিতগুলির মতো দেখাচ্ছে:

4DEF78583D05300.png

সেই স্প্রেডশিটের জন্য ইউআরএলটি নিম্নলিখিতগুলির মতো দেখাবে: https://docs.google.com/spreadsheets/d/ FILE_ID /edit । সেই FILE_ID ধরুন এবং এটি SHEET থেকে স্টিং হিসাবে বরাদ্দ করুন।

আমরা k_ize() নামে একটি ছোট্ট ফাংশনেও ছড়িয়ে পড়েছি যা বাইটকে কিলোবাইটে রূপান্তর করে, এটি একটি সাধারণ 1-লাইনার হওয়ায় এটি একটি পাইথন 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                 

পূর্ববর্তী পদক্ষেপগুলির মতো, আমাদের আরও একটি অনুমতি সুযোগ প্রয়োজন, এবার শিটস এপিআইয়ের জন্য পড়ুন। SCOPES এখন সমস্ত 4 টি প্রয়োজন:

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',
)                  

এখন অন্যের কাছে গুগল শিটগুলিতে একটি পরিষেবা শেষ পয়েন্ট তৈরি করুন, সুতরাং এটি দেখতে এটির মতো:

# 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() কলটির জন্য শীটের ফাইল আইডি, কোষগুলির একটি পরিসীমা, কীভাবে ডেটা প্রবেশ করা উচিত এবং ডেটা নিজেই প্রয়োজন। ফাইল আইডি সোজা, কোষের পরিসীমা এ 1 স্বরলীতে দেওয়া হয়। " Sheet1 " এর একটি পরিসীমা মানে পুরো শীট - এটি শিটের সমস্ত ডেটা পরে সারিটি সংযোজন করার জন্য এপিআইয়ের সংকেত দেয়। " RAW " (স্ট্রিং ডেটা ভারব্যাটিম প্রবেশ করুন) বা " USER_ENTERED " (ডেটা লিখুন যেন কোনও ব্যবহারকারী গুগল শিট অ্যাপ্লিকেশন সহ তাদের কীবোর্ডে প্রবেশ করেছেন, সে সম্পর্কে কীভাবে ডেটা যুক্ত করা উচিত সে সম্পর্কে একজোড়া পছন্দ রয়েছে যে কোনও সেল ফর্ম্যাটিং বৈশিষ্ট্য সংরক্ষণ করা)।

যদি কলটি সফল হয় তবে রিটার্নের মানটিতে সত্যই খুব কার্যকর কিছু নেই, তাই আমরা এপিআই অনুরোধের দ্বারা আপডেট হওয়া কোষের সংখ্যা পাওয়ার জন্য বেছে নিয়েছি। নীচে সেই কোডটি রয়েছে যা সেই ফাংশনটিকে কল করে:

                # 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')

গুগল শিটটিতে কলাম রয়েছে যেমন কোনও পিতামাতার "সাবডাইরেক্টরি," ক্লাউড স্টোরেজে সংরক্ষণাগারভুক্ত ফাইলের অবস্থান (বালতি + ফাইলের নাম), ফাইলের মাইমেটাইপ, ফাইলের আকার (মূলত বাইটে, তবে k_ize() এর সাথে কিলোবাইটে রূপান্তরিত হয়েছে। ), এবং ক্লাউড ভিশন লেবেল স্ট্রিং। এছাড়াও নোট করুন সংরক্ষণাগারভুক্ত অবস্থানটি একটি হাইপারলিঙ্ক যাতে আপনার পরিচালক এটি নিরাপদে ব্যাক আপ করা হয়েছে তা নিশ্চিত করতে ক্লিক করতে পারেন।

ক্লাউড ভিশন থেকে ফলাফলগুলি প্রদর্শনের পরে ডানদিকে উপরে কোডের ব্লক যুক্ত করা, অ্যাপ্লিকেশনটি চালানোর মূল অংশটি এখন সম্পূর্ণ, যদিও কাঠামোগতভাবে কিছুটা জটিল:

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 মোছা।

$ 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

আউটপুট অতিরিক্ত লাইন, দরকারী হলেও আপডেট হওয়া গুগল শীটে উঁকি দিয়ে আরও ভাল ভিজ্যুয়ালাইজ করা হয়, শেষ লাইনটি (নীচের উদাহরণে সারি 7) সহ বিদ্যমান ডেটা সেটটিতে যুক্ত হওয়া পূর্বে যুক্ত হয়েছে:

b53a5bc944734652.png

সারাংশ

এই টিউটোরিয়ালটির প্রথম 3 টি ধাপে, আপনি সমস্ত কাজের 80% উপস্থাপন করে ডেটা সরাতে এবং এটি বিশ্লেষণ করতে গুগল ওয়ার্কস্পেস এবং গুগল ক্লাউড এপিআইয়ের সাথে সংযুক্ত হন। তবে দিনের শেষে, আপনি যদি আপনি সম্পাদন করেছেন এমন সমস্ত পরিচালনায় উপস্থাপন করতে না পারলে এর কোনওটির অর্থ কিছুই নয়। ফলাফলগুলি আরও ভালভাবে কল্পনা করার জন্য, উত্পন্ন প্রতিবেদনে সমস্ত ফলাফলের সংক্ষিপ্তসারগুলি ভলিউম বলে।

বিশ্লেষণের কার্যকারিতা আরও বাড়ানোর জন্য, ফলাফলগুলি একটি স্প্রেডশিটে লেখার পাশাপাশি, একটি সম্ভাব্য বর্ধন হ'ল প্রতিটি চিত্রের জন্য এই শীর্ষ 5 লেবেলগুলিকে সূচক করা যাতে কোনও অভ্যন্তরীণ ডাটাবেস তৈরি করা যায় যাতে অনুমোদিত কর্মীদের অনুসন্ধানের মাধ্যমে চিত্রগুলির জন্য জিজ্ঞাসা করতে দেয় দল, তবে আমরা এটি পাঠকদের জন্য অনুশীলন হিসাবে ছেড়ে দিয়েছি।

আপাতত, আমাদের ফলাফলগুলি একটি শীটে এবং পরিচালনার জন্য অ্যাক্সেসযোগ্য। এই পর্যায়ে আপনার অ্যাপ্লিকেশনটির কোডটি step4-sheets/analyze_gsimg.py -তে রেপোতে যা আছে তা মেলে। চূড়ান্ত পদক্ষেপটি কোডটি পরিষ্কার করা এবং এটিকে ব্যবহারযোগ্য স্ক্রিপ্টে পরিণত করা।

12. *চূড়ান্ত পদক্ষেপ: রিফ্যাক্টর

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

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

অন্যান্য অ্যাপ্লিকেশনগুলিতে এই কোডটি ব্যবহার করতে সক্ষম হতে, আমাদের আউটপুটটি দমন করার ক্ষমতা প্রয়োজন, সুতরাং এটি ঘটানোর জন্য একটি DEBUG পতাকা যুক্ত করুন, শীর্ষের কাছাকাছি ধ্রুবক বিভাগের শেষে এই লাইনটি যুক্ত করুন:

DEBUG = False

এখন, মূল দেহ সম্পর্কে। যেহেতু আমরা এই নমুনাটি তৈরি করছিলাম, আপনার কোডটি প্রতিটি পরিষেবা যুক্ত করার সাথে আরও একটি স্তর বাসা বাঁধার সাথে সাথে আপনার "অস্বস্তিকর" বোধ করা শুরু করা উচিত ছিল। আপনি যদি সেভাবে অনুভব করেন তবে আপনি একা নন, কারণ এটি এই গুগল টেস্টিং ব্লগ পোস্টে বর্ণিত কোড জটিলতায় যুক্ত করে।

এই সর্বোত্তম অনুশীলন অনুসরণ করে, আসুন অ্যাপের মূল অংশটিকে একটি ফাংশনে পুনর্গঠিত করুন এবং বাসা বাঁধার পরিবর্তে প্রতিটি "ব্রেক পয়েন্ট" এ return (কোনও পদক্ষেপ ব্যর্থ না হলে এবং True যদি সমস্ত সফল হয় তবে সত্য None ):

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 সহ -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

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

পরিষ্কার করুন

  1. গুগল ক্লাউড এপিআইগুলির ব্যবহার নিখরচায় নয় যখন গুগল ওয়ার্কস্পেস এপিআইগুলি আপনার মাসিক গুগল ওয়ার্কস্পেস সাবস্ক্রিপশন ফি দ্বারা আচ্ছাদিত (গ্রাহক জিমেইল ব্যবহারকারীদের শূন্যের মাসিক ফি রয়েছে), সুতরাং গুগল ওয়ার্কস্পেস ব্যবহারকারীদের জন্য কোনও এপিআই ক্লিন-আপ/টার্নডাউন প্রয়োজন নেই। গুগল ক্লাউডের জন্য, আপনি আপনার ক্লাউড কনসোল ড্যাশবোর্ডে যেতে পারেন এবং আনুমানিক চার্জের জন্য বিলিং "কার্ড" পরীক্ষা করতে পারেন।
  2. ক্লাউড ভিশনের জন্য, আপনাকে প্রতি মাসে বিনামূল্যে একটি নির্দিষ্ট সংখ্যক এপিআই কলের অনুমতি দেওয়া হয়েছে। সুতরাং যতক্ষণ আপনি এই সীমাতে থাকেন ততক্ষণ কিছুই বন্ধ করার দরকার নেই বা আপনার প্রকল্পটি অক্ষম/মুছতে হবে না। ভিশন এপিআইয়ের বিলিং এবং ফ্রি কোটা সম্পর্কিত আরও তথ্য এর মূল্য পৃষ্ঠায় পাওয়া যাবে।
  3. কিছু ক্লাউড স্টোরেজ ব্যবহারকারী প্রতি মাসে একটি নিখরচায় স্টোরেজ পান। আপনি যদি এই কোডল্যাবটি ব্যবহার করে সংরক্ষণাগারভুক্ত চিত্রগুলি আপনাকে সেই কোটা ছাড়িয়ে না দেয় তবে আপনি কোনও চার্জ গ্রহণ করবেন না। জিসিএস বিলিং এবং ফ্রি কোটা সম্পর্কিত আরও তথ্য এর মূল্য পৃষ্ঠায় পাওয়া যাবে। আপনি ক্লাউড স্টোরেজ ব্রাউজার থেকে ব্লবগুলি দেখতে এবং সহজেই মুছতে পারেন।
  4. আপনার গুগল ড্রাইভের ব্যবহারে স্টোরেজ কোটাও থাকতে পারে এবং আপনি যদি এটির চেয়ে বেশি (বা এটির কাছাকাছি থাকেন) তবে আপনি নিজেকে আরও স্থান দেওয়ার জন্য ক্লাউড স্টোরেজে এই চিত্রগুলি সংরক্ষণাগারভুক্ত করার জন্য এই কোডল্যাবটিতে নির্মিত সরঞ্জামটি ব্যবহার করার বিষয়টি বিবেচনা করতে পারেন ড্রাইভ গুগল ড্রাইভ স্টোরেজ সম্পর্কিত আরও তথ্য গুগল ওয়ার্কস্পেস বেসিক ব্যবহারকারী বা জিমেইল/ভোক্তা ব্যবহারকারীদের জন্য উপযুক্ত মূল্য পৃষ্ঠায় পাওয়া যাবে।

যদিও বেশিরভাগ গুগল ওয়ার্কস্পেস বিজনেস এবং এন্টারপ্রাইজ পরিকল্পনার সীমাহীন স্টোরেজ রয়েছে, এটি আপনার ড্রাইভ ফোল্ডারগুলি বিশৃঙ্খলা এবং/অথবা অপ্রতিরোধ্য হতে পারে এবং এই টিউটোরিয়ালে আপনি যে অ্যাপ্লিকেশনটি তৈরি করেছেন তা বহিরাগত ফাইলগুলি সংরক্ষণাগার এবং আপনার গুগল ড্রাইভ পরিষ্কার করার এক দুর্দান্ত উপায়।

বিকল্প সংস্করণ

final/analyze_gsimg.py থাকলেও আপনি এই টিউটোরিয়ালে কাজ করছেন এমন "শেষ" অফিসিয়াল সংস্করণ, এটি গল্পের শেষ নয়। অ্যাপ্লিকেশনটির চূড়ান্ত সংস্করণ সহ একটি সমস্যা হ'ল এটি পুরানো এথ লাইব্রেরিগুলি ব্যবহার করে যা অবমূল্যায়িত হয়েছে। আমরা এই পথটি বেছে নিয়েছি কারণ, এই লেখার সময়, নতুন এথ লাইব্রেরিগুলি বেশ কয়েকটি মূল উপাদানকে সমর্থন করে না: ওউথ টোকেন স্টোরেজ ম্যানেজমেন্ট এবং থ্রেড সুরক্ষা।

বর্তমান (নতুন) লেখক গ্রন্থাগারগুলি

যাইহোক, এক পর্যায়ে, পুরানো এথ লাইব্রেরিগুলি আর সমর্থন করা হবে না, তাই আমরা আপনাকে রেপোর alt ফোল্ডারে নতুন (বর্তমান) অ্যাথ লাইব্রেরিগুলি ব্যবহার করে এমন সংস্করণগুলি পর্যালোচনা করতে উত্সাহিত করি যা তারা থ্রেডস্যাফে না করেও (তবে আপনি আপনার তৈরি করতে পারেন নিজস্ব সমাধান যে হয়)। তাদের নামে *newauth* সহ ফাইলগুলি সন্ধান করুন।

গুগল ক্লাউড পণ্য ক্লায়েন্ট গ্রন্থাগার

গুগল ক্লাউড সমস্ত বিকাশকারীদের গুগল ক্লাউড এপিআই ব্যবহার করার সময় পণ্য ক্লায়েন্ট লাইব্রেরিগুলি ব্যবহার করার পরামর্শ দেয়। দুর্ভাগ্যক্রমে নন-গুগল ক্লাউড এপিআইগুলিতে এই মুহুর্তে এ জাতীয় গ্রন্থাগার নেই। নিম্ন-স্তরের গ্রন্থাগারগুলির ব্যবহার ধারাবাহিক এপিআই ব্যবহারের জন্য অনুমতি দেয় এবং আরও ভাল পঠনযোগ্যতার বৈশিষ্ট্যযুক্ত। উপরের সুপারিশের অনুরূপ, গুগল ক্লাউড প্রোডাক্ট ক্লায়েন্ট লাইব্রেরি ব্যবহার করে বিকল্প সংস্করণগুলি আপনার পর্যালোচনা করার জন্য রেপোর alt ফোল্ডারে উপলব্ধ। তাদের নামে *-gcp* সহ ফাইলগুলি সন্ধান করুন।

পরিষেবা অ্যাকাউন্ট অনুমোদন

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

বিকল্প সংস্করণ ক্যাটালগ

নীচে, আপনি final/analyze_gsimg.py সমস্ত বিকল্প সংস্করণগুলি পাবেন_গসিমগ.পি.পি, প্রত্যেকের উপরের বৈশিষ্ট্যগুলির এক বা একাধিক রয়েছে। প্রতিটি সংস্করণের ফাইলের নামটিতে, সন্ধান করুন:

  • পুরানো এথ লাইব্রেরিগুলি ব্যবহার করে সংস্করণগুলির জন্য " oldauth " ( final/analyze_gsimg.py ছাড়া_গসিমগ.পি)
  • যারা বর্তমান/নতুন এথ লাইব্রেরি ব্যবহার করছেন তাদের জন্য " newauth "
  • গুগল ক্লাউড প্রোডাক্ট ক্লায়েন্ট লাইব্রেরি, আইই, গুগল-ক্লাউড-স্টোরেজ ইত্যাদি ব্যবহারকারীদের জন্য " gcp "
  • ব্যবহারকারী অ্যাকাউন্টের পরিবর্তে কোনও পরিষেবা অ্যাকাউন্ট ("এসভিসি অ্যাক্ট") আথ ব্যবহারকারীদের জন্য " svc "

এখানে সমস্ত সংস্করণ রয়েছে:

ফাইলের নাম

বর্ণনা

final/analyze_gsimg.py

প্রাথমিক নমুনা; পুরানো এথ লাইব্রেরি ব্যবহার করে

alt/analyze_gsimg-newauth.py

final/analyze_gsimg.py হিসাবে একই তবে নতুন এথ লাইব্রেরি ব্যবহার করে

alt/analyze_gsimg-oldauth-gcp.py

final/analyze_gsimg.py হিসাবে একই তবে গুগল ক্লাউড পণ্য ক্লায়েন্ট লাইব্রেরি ব্যবহার করে

alt/analyze_gsimg-newauth-gcp.py

alt/analyze_gsimg-newauth.py হিসাবে একই তবে গুগল ক্লাউড পণ্য ক্লায়েন্ট লাইব্রেরি ব্যবহার করে

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 হিসাবে একই তবে গুগল ক্লাউড প্রোডাক্ট ক্লায়েন্ট লাইব্রেরিগুলি ব্যবহার করে এবং alt/analyze_gsimg-oldauth-gcp.py হিসাবে একই ব্যবহারকারী এসভিসি অ্যাক্ট অ্যাথ ব্যবহার করে

alt/analyze_gsimg-newauth-svc-gcp.py

alt/analyze_gsimg-oldauth-svc-gcp.py হিসাবে একই তবে নতুন এথ লাইব্রেরি ব্যবহার করে

মূল final/analyze_gsimg.py সাথে মিলিত হয়ে আপনার গুগল এপিআই বিকাশের পরিবেশ নির্বিশেষে আপনার চূড়ান্ত সমাধানের সমস্ত সম্ভাব্য সংমিশ্রণ রয়েছে এবং এটি আপনার প্রয়োজনের পক্ষে সবচেয়ে উপযুক্ত যেটি বেছে নিতে পারে। অনুরূপ ব্যাখ্যার জন্য alt/README.md দেখুন।

অতিরিক্ত অধ্যয়ন

আপনি কীভাবে এই অনুশীলনটি আরও এক বা দুটি পদক্ষেপ নিতে পারেন তার কয়েকটি ধারণা নীচে দেওয়া হল। বর্তমান সমাধানটি হ্যান্ডেল করতে পারে এমন সমস্যাটি আপনাকে এই বর্ধিতকরণগুলি তৈরি করার অনুমতি দিয়ে প্রসারিত করা যেতে পারে:

  1. ( ফোল্ডারগুলিতে একাধিক চিত্র ) একটি চিত্র প্রক্রিয়াকরণের পরিবর্তে, আসুন আমরা বলি যে গুগল ড্রাইভ ফোল্ডারগুলিতে আপনার চিত্র রয়েছে।
  2. ( জিপ ফাইলগুলিতে একাধিক চিত্র ) চিত্রগুলির ফোল্ডারের পরিবর্তে, চিত্র ফাইলযুক্ত জিপ সংরক্ষণাগারগুলি সম্পর্কে কীভাবে? যদি পাইথন ব্যবহার করে তবে zipfile মডিউলটি বিবেচনা করুন।
  3. ( ভিশন লেবেলগুলি বিশ্লেষণ করুন ) ক্লাস্টার অনুরূপ চিত্রগুলি একসাথে, সম্ভবত সর্বাধিক সাধারণ লেবেলগুলি সন্ধান করে শুরু করুন, তারপরে ২ য় সর্বাধিক সাধারণ ইত্যাদি।
  4. ( চার্ট তৈরি করুন ) ফলোআপ #3, ভিশন এপিআই বিশ্লেষণ এবং শ্রেণিবদ্ধকরণের উপর ভিত্তি করে শীট এপিআই দিয়ে চার্ট তৈরি করুন
  5. ( নথিগুলিকে শ্রেণিবদ্ধ করুন ) ক্লাউড ভিশন এপিআইয়ের সাথে চিত্রগুলি বিশ্লেষণের পরিবর্তে, আসুন আমরা বলি যে ক্লাউড প্রাকৃতিক ভাষা এপিআইয়ের সাথে শ্রেণিবদ্ধ করার জন্য আপনার পিডিএফ ফাইল রয়েছে। উপরের আপনার সমাধানগুলি ব্যবহার করে, এই পিডিএফগুলি ড্রাইভে ড্রাইভ ফোল্ডার বা জিপ সংরক্ষণাগারগুলিতে থাকতে পারে।
  6. ( উপস্থাপনা তৈরি করুন ) গুগল শীট প্রতিবেদনের বিষয়বস্তু থেকে স্লাইড ডেক তৈরি করতে স্লাইডগুলি এপিআই ব্যবহার করুন। অনুপ্রেরণার জন্য, স্প্রেডশিট ডেটা থেকে স্লাইড তৈরি করার জন্য এই ব্লগ পোস্ট এবং ভিডিওটি দেখুন।
  7. ( পিডিএফ হিসাবে রফতানি ) স্প্রেডশিট এবং/অথবা স্লাইড ডেক পিডিএফ হিসাবে রফতানি করে, তবে এটি শীট বা স্লাইড এপিআইগুলির কোনও বৈশিষ্ট্য নয়। ইঙ্গিত : গুগল ড্রাইভ এপিআই। অতিরিক্ত ক্রেডিট : শিট এবং স্লাইড পিডিএফ উভয়কেই ঘোস্টস্ক্রিপ্ট (লিনাক্স, উইন্ডোজ) এর মতো সরঞ্জামগুলির সাথে একটি মাস্টার পিডিএফ -এ একীভূত করুন বা Combine PDF Pages.action (ম্যাক ওএস এক্স)।

আরও জানুন

কোডল্যাব

সাধারণ

Google Workspace

গুগল ক্লাউড

লাইসেন্স

এই কাজটি ক্রিয়েটিভ কমন্স অ্যাট্রিবিউশন 2.0 জেনেরিক লাইসেন্সের অধীনে লাইসেন্সপ্রাপ্ত।