آرشیو تصاویر، تجزیه و تحلیل و تولید گزارش Google Workspace & Google Cloud

1. بررسی اجمالی

این آزمایشگاه کد یک گردش کار سازمانی ممکن را تصور می کند: آرشیو تصویر، تجزیه و تحلیل و تولید گزارش. تصور کنید سازمان شما دارای مجموعه ای از تصاویر است که فضایی را در یک منبع محدود اشغال می کند. شما می‌خواهید آن داده‌ها را بایگانی کنید، آن تصاویر را تجزیه و تحلیل کنید، و مهمتر از همه، گزارشی حاوی خلاصه مکان‌های بایگانی‌شده به‌علاوه نتایج تجزیه و تحلیل، جمع‌آوری‌شده و آماده برای مصرف توسط مدیریت تولید کنید. Google Cloud با استفاده از APIهای دو خط تولید خود، Google Workspace (قبلاً G Suite یا Google Apps) و Google Cloud (قبلاً GCP) ابزارهایی را برای تحقق این امر فراهم می کند.

در سناریوی ما، کاربر تجاری تصاویری در Google Drive خواهد داشت. منطقی است که از آن‌ها در فضای ذخیره‌سازی «سردتر» و ارزان‌تر، مانند کلاس‌های فضای ذخیره‌سازی موجود در Google Cloud Storage، نسخه پشتیبان تهیه کنید. Google Cloud Vision به توسعه‌دهندگان اجازه می‌دهد تا به راحتی ویژگی‌های تشخیص بینایی را در برنامه‌ها ادغام کنند، از جمله تشخیص اشیا و نشانه‌ها، تشخیص نوری کاراکتر (OCR)، و غیره. در نهایت، صفحه‌گسترده Google Sheets یک ابزار تجسمی مفید برای خلاصه کردن همه این‌ها برای رئیس شما است.

پس از تکمیل این کد برای ایجاد راه‌حلی که از کل Google Cloud بهره می‌برد، امیدواریم از شما الهام گرفته شود تا چیزی حتی تاثیرگذارتر برای سازمان یا مشتریان خود بسازید.

چیزی که یاد خواهید گرفت

  • نحوه استفاده از Cloud Shell
  • نحوه احراز هویت درخواست های API
  • نحوه نصب کتابخانه سرویس گیرنده Google APIs برای پایتون
  • چگونه API های گوگل را فعال کنیم
  • نحوه دانلود فایل ها از گوگل درایو
  • نحوه آپلود اشیا / حباب ها در فضای ذخیره سازی ابری
  • نحوه تجزیه و تحلیل داده ها با Cloud Vision
  • نحوه نوشتن سطرها در Google Sheets

آنچه شما نیاز دارید

  • یک حساب Google (حساب‌های Google Workspace ممکن است به تأیید سرپرست نیاز داشته باشند)
  • پروژه Google Cloud با حساب صورتحساب Google Cloud فعال
  • آشنایی با دستورات ترمینال/شل سیستم عامل
  • مهارت های پایه در پایتون (2 یا 3)، اما می توانید از هر زبان پشتیبانی شده استفاده کنید

داشتن تجربه با چهار محصول Google Cloud ذکر شده در بالا مفید است اما لازم نیست. اگر زمان به شما اجازه می‌دهد که ابتدا به طور جداگانه با آنها آشنا شوید، می‌توانید قبل از پرداختن به تمرین در اینجا، برای هر کدام از آنها کدها را انجام دهید:

نظرسنجی

چگونه از این آموزش استفاده خواهید کرد؟

فقط از طریق آن را بخوانید آن را بخوانید و تمرینات را کامل کنید

تجربه خود را با پایتون چگونه ارزیابی می کنید؟

تازه کار متوسط مسلط

تجربه خود را در استفاده از خدمات Google Cloud چگونه ارزیابی می کنید؟

تازه کار متوسط مسلط

تجربه خود را در استفاده از خدمات توسعه دهنده Google Workspace چگونه ارزیابی می کنید؟

تازه کار متوسط مسلط

آیا دوست دارید کدهای «کسب و کار محور» بیشتری را در مقابل آنهایی که معرفی ویژگی های محصول هستند، ببینید؟

بله خیر بیشتر از هر دو

2. راه اندازی و الزامات

تنظیم محیط خود به خود

  1. به Google Cloud Console وارد شوید و یک پروژه جدید ایجاد کنید یا از یک موجود استفاده مجدد کنید. اگر قبلاً یک حساب Gmail یا Google Workspace ندارید، باید یک حساب ایجاد کنید .

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • نام پروژه نام نمایشی برای شرکت کنندگان این پروژه است. این یک رشته کاراکتری است که توسط API های Google استفاده نمی شود. شما می توانید آن را در هر زمان به روز کنید.
  • شناسه پروژه باید در تمام پروژه‌های Google Cloud منحصربه‌فرد باشد و تغییرناپذیر باشد (پس از تنظیم نمی‌توان آن را تغییر داد). Cloud Console به طور خودکار یک رشته منحصر به فرد تولید می کند. معمولاً برای شما مهم نیست که چیست. در اکثر کدها، باید به شناسه پروژه ارجاع دهید (معمولاً به عنوان PROJECT_ID شناخته می شود). اگر شناسه تولید شده را دوست ندارید، ممکن است یک شناسه تصادفی دیگر ایجاد کنید. از طرف دیگر، می‌توانید خودتان را امتحان کنید و ببینید آیا در دسترس است یا خیر. پس از این مرحله نمی توان آن را تغییر داد و در طول مدت پروژه باقی می ماند.
  • برای اطلاع شما، یک مقدار سوم وجود دارد، یک شماره پروژه که برخی از API ها از آن استفاده می کنند. در مورد هر سه این مقادیر در مستندات بیشتر بیاموزید.
  1. در مرحله بعد، برای استفاده از منابع Cloud/APIها باید صورتحساب را در کنسول Cloud فعال کنید . اجرا کردن از طریق این کد لبه نباید هزینه زیادی داشته باشد، اگر اصلاً باشد. برای اینکه منابع را خاموش کنید تا بیش از این آموزش متحمل صورتحساب نشوید، می توانید منابعی را که ایجاد کرده اید حذف کنید یا کل پروژه را حذف کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان 300 دلاری هستند.

Cloud Shell را راه اندازی کنید

خلاصه

در حالی که می‌توانید کد را به صورت محلی بر روی لپ‌تاپ خود توسعه دهید، هدف دوم این نرم‌افزار این است که به شما یاد دهد چگونه از Google Cloud Shell ، یک محیط خط فرمان که در فضای ابری از طریق مرورگر وب مدرن شما اجرا می‌شود، استفاده کنید.

Cloud Shell را فعال کنید

  1. از Cloud Console، روی Activate Cloud Shell کلیک کنید 853e55310c205094.png .

55efc1aaa7a4d3ad.png

اگر قبلاً Cloud Shell را راه‌اندازی نکرده‌اید، یک صفحه میانی (در زیر تاشو) برای شما نمایش داده می‌شود که آن را توصیف می‌کند. اگر اینطور است، روی Continue کلیک کنید (و دیگر آن را نخواهید دید). در اینجا به نظر می رسد که آن صفحه یک بار مصرف:

9c92662c6a846a5c.png

تهیه و اتصال به Cloud Shell فقط باید چند لحظه طول بکشد.

9f0e51b578fecce5.png

این ماشین مجازی با تمام ابزارهای توسعه مورد نیاز شما بارگذاری شده است. این دایرکتوری اصلی 5 گیگابایتی دائمی را ارائه می دهد و در Google Cloud اجرا می شود و عملکرد شبکه و احراز هویت را بسیار افزایش می دهد. بیشتر، اگر نه همه، کار شما در این کد لبه را می توان به سادگی با یک مرورگر یا Chromebook انجام داد.

پس از اتصال به Cloud Shell، باید ببینید که قبلاً احراز هویت شده اید و پروژه قبلاً روی ID پروژه شما تنظیم شده است.

  1. برای تایید احراز هویت، دستور زیر را در Cloud Shell اجرا کنید:
gcloud auth list

خروجی فرمان

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. دستور زیر را در Cloud Shell اجرا کنید تا تأیید کنید که دستور gcloud از پروژه شما اطلاع دارد:
gcloud config list project

خروجی فرمان

[core]
project = <PROJECT_ID>

اگر اینطور نیست، می توانید آن را با این دستور تنظیم کنید:

gcloud config set project <PROJECT_ID>

خروجی فرمان

Updated property [core/project].

3. محیط پایتون را تایید کنید

این نرم‌افزار کد از شما می‌خواهد از زبان پایتون استفاده کنید (اگرچه بسیاری از زبان‌ها توسط کتابخانه‌های سرویس گیرنده Google APIs پشتیبانی می‌شوند ، بنابراین با خیال راحت چیزی معادل آن را در ابزار توسعه مورد علاقه خود بسازید و به سادگی از Python به عنوان شبه کد استفاده کنید). به طور خاص، این کد لبه از پایتون 2 و 3 پشتیبانی می کند، اما توصیه می کنیم در اسرع وقت به 3.x بروید.

Cloud Shell ابزار مناسبی است که مستقیماً از کنسول Cloud برای کاربران در دسترس است و به محیط توسعه محلی نیاز ندارد، بنابراین این آموزش را می توان به طور کامل در فضای ابری با مرورگر وب انجام داد. به طور خاص برای این کد، Cloud Shell قبلاً هر دو نسخه پایتون را از قبل نصب کرده است.

Cloud Shell همچنین IPython را نصب کرده است: این یک مفسر تعاملی پایتون سطح بالاتری است که ما آن را توصیه می کنیم، به خصوص اگر بخشی از جامعه علم داده یا یادگیری ماشین هستید. اگر هستید، IPython مفسر پیش‌فرض برای نوت‌بوک‌های Jupyter و همچنین نوت‌بوک‌های Colab ، Jupyter است که توسط Google Research میزبانی می‌شوند.

IPython ابتدا از یک مفسر Python 3 استفاده می کند اما اگر 3.x در دسترس نباشد به Python 2 برمی گردد. IPython از Cloud Shell قابل دسترسی است اما می‌تواند در محیط توسعه محلی نیز نصب شود. با ^D (Ctrl-d) خارج شوید و پیشنهاد خروج را بپذیرید. خروجی نمونه شروع ipython به شکل زیر خواهد بود:

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

In [1]:

اگر IPython ترجیح شما نیست، استفاده از یک مفسر تعاملی پایتون استاندارد (چه Cloud Shell یا محیط توسعه محلی شما) کاملاً قابل قبول است (همچنین با ^D خارج شوید):

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

Codelab همچنین فرض می‌کند که شما ابزار نصب pip (مدیر بسته پایتون و حل‌کننده وابستگی) را دارید. همراه با نسخه های 2.7.9+ یا 3.4+ ارائه می شود. اگر نسخه پایتون قدیمی‌تری دارید، برای دستورالعمل‌های نصب به این راهنما مراجعه کنید. بسته به مجوزهای شما، ممکن است نیاز به دسترسی sudo یا superuser داشته باشید، اما معمولاً اینطور نیست. همچنین می توانید صریحاً از pip2 یا pip3 برای اجرای pip برای نسخه های خاص پایتون استفاده کنید.

بقیه کدها فرض می‌کنند که شما از پایتون 3 استفاده می‌کنید—دستورالعمل‌های خاصی برای پایتون 2 ارائه می‌شوند اگر تفاوت قابل توجهی با 3.x داشته باشند.

[اختیاری] محیط های مجازی ایجاد و استفاده کنید

این بخش اختیاری است و فقط برای کسانی که باید از یک محیط مجازی برای این کد لبه استفاده کنند (بر اساس نوار کناری هشدار بالا) واقعاً مورد نیاز است. اگر فقط پایتون 3 را روی رایانه خود دارید، می توانید به سادگی این دستور را برای ایجاد یک virtualenv به نام my_env صادر کنید (در صورت تمایل می توانید نام دیگری انتخاب کنید):

virtualenv my_env

با این حال، اگر هر دو پایتون 2 و 3 را روی رایانه خود دارید، توصیه می‌کنیم پایتون 3 virtualenv را نصب کنید که می‌توانید با -p flag به این صورت انجام دهید:

virtualenv -p python3 my_env

virtualenv تازه ایجاد شده خود را با «فعال کردن» به این صورت وارد کنید:

source my_env/bin/activate

تأیید کنید که در محیط هستید با مشاهده اینکه دستور پوسته شما اکنون با نام محیط شما قبل از آن قرار گرفته است، به عنوان مثال،

(my_env) $ 

حالا باید بتوانید هر بسته مورد نیاز pip install ، کد را در این eivonment اجرا کنید، و غیره. مزیت دیگر این است که اگر آن را کاملاً بهم بزنید، در شرایطی قرار بگیرید که نصب پایتون شما خراب شود و غیره، می توانید این را از بین ببرید. کل محیط بدون تأثیر بر بقیه سیستم شما.

4. کتابخانه سرویس گیرنده Google APIs را برای پایتون نصب کنید

این کد لبه نیاز به استفاده از کتابخانه سرویس گیرنده Google APIs برای پایتون دارد، بنابراین یا یک فرآیند نصب ساده است، یا ممکن است اصلاً مجبور نباشید کاری انجام دهید.

ما قبلاً توصیه کردیم برای راحتی از Cloud Shell استفاده کنید. می توانید کل آموزش را از یک مرورگر وب در فضای ابری کامل کنید. دلیل دیگر استفاده از Cloud Shell این است که بسیاری از ابزارهای توسعه محبوب و کتابخانه های ضروری از قبل نصب شده اند.

*کتابخانه های سرویس گیرنده را نصب کنید

( اختیاری ) اگر از Cloud Shell یا یک محیط محلی استفاده می کنید که قبلاً کتابخانه های سرویس گیرنده را در آن نصب کرده اید، می توان از این کار صرفنظر کرد. فقط در صورتی که به صورت محلی در حال توسعه هستید و آنها را نصب نکرده اید (یا مطمئن نیستید) باید این کار را انجام دهید. ساده ترین راه استفاده از pip (یا pip3 ) برای انجام نصب است (از جمله به روز رسانی خود pip در صورت لزوم):

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

نصب را تایید کنید

این دستور کتابخانه سرویس گیرنده و همچنین هر بسته ای که به آن بستگی دارد را نصب می کند. چه از Cloud Shell یا محیط شخصی خود استفاده می‌کنید، با وارد کردن بسته‌های لازم، تأیید کنید که کتابخانه مشتری نصب شده است و تأیید کنید که هیچ خطای وارد کردن (و نه خروجی) وجود ندارد:

python3 -c "import googleapiclient, httplib2, oauth2client"

اگر به جای آن از Python 2 (از Cloud Shell) استفاده کنید، اخطاری دریافت خواهید کرد که پشتیبانی از آن منسوخ شده است:

*******************************************************************************
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.
*******************************************************************************

هنگامی که بتوانید دستور import "test" را با موفقیت اجرا کنید (بدون خطا/خروجی)، آماده شروع صحبت با Google API هستید!

خلاصه

از آنجایی که این یک کد میانی است، فرض بر این است که شما قبلاً تجربه ایجاد و استفاده از پروژه‌ها در کنسول را دارید. اگر با Google APIها و به طور خاص Google Workspace APIs تازه کار هستید، ابتدا کد Lab مقدماتی Google Workspace APIs را امتحان کنید. به‌علاوه، اگر می‌دانید چگونه اعتبارنامه‌های حساب کاربری موجود ( نه حساب سرویس ) را ایجاد کنید (یا دوباره از آن استفاده کنید)، فایل client_secret.json را در فهرست کاری خود رها کنید، ماژول بعدی را رد کنید و به «فعال کردن Google APIs» بروید.

5. *مجوز درخواست های API (مجوز کاربر)

اگر قبلاً اعتبارنامه مجوز حساب کاربری را ایجاد کرده اید و با این فرآیند آشنا هستید، می توان از این بخش صرفنظر کرد. این با مجوز حساب سرویس که تکنیک آن متفاوت است متفاوت است، بنابراین لطفاً در زیر ادامه دهید.

مقدمه ای برای مجوز (به علاوه برخی از احراز هویت)

برای ارسال درخواست به APIها، برنامه شما باید مجوز مناسب را داشته باشد. احراز هویت ، کلمه ای مشابه، اعتبار ورود به سیستم را توصیف می کند—شما خود را هنگام ورود به حساب Google خود با ورود و رمز عبور احراز هویت می کنید. پس از احراز هویت، مرحله بعدی این است که آیا شما مجاز هستید یا بهتر بگوییم کد شما مجاز به دسترسی به داده‌هایی مانند فایل‌های حباب در فضای ذخیره‌سازی ابری یا فایل‌های شخصی کاربر در Google Drive هستید.

APIهای Google از چندین نوع مجوز پشتیبانی می‌کنند، اما رایج‌ترین مورد برای کاربران G Suite API مجوز کاربر است، زیرا برنامه نمونه در این آزمایشگاه کد به داده‌های متعلق به کاربران نهایی دسترسی دارد. این کاربران نهایی باید به برنامه شما اجازه دسترسی به داده‌هایشان را بدهند. این بدان معنی است که کد شما باید اعتبار حساب کاربری OAuth2 را دریافت کند.

برای دریافت اعتبار OAuth2 برای مجوز کاربر، به مدیر API برگردید و برگه "Credentials" را در نوار سمت چپ انتخاب کنید:

635af008256d323.png

وقتی به آنجا رسیدید، تمام اطلاعات کاربری خود را در سه بخش مجزا خواهید دید:

fd2f4133b406d572.png

اولین مورد برای کلیدهای API ، شناسه های مشتری OAuth 2.0 و آخرین سرویس OAuth2 است — ما از یکی در وسط استفاده می کنیم.

ایجاد اعتبار

از صفحه اعتبار، روی دکمه + ایجاد اعتبارنامه در بالا کلیک کنید، که سپس یک گفتگو به شما می دهد که در آن "OAuth Client ID" را انتخاب کنید:

b17b663668e38787.png

در صفحه بعدی، 2 عمل دارید: پیکربندی مجوز برنامه خود "صفحه رضایت" و انتخاب نوع برنامه:

4e0b967c9d70d262.png

اگر صفحه رضایت تنظیم نکرده باشید، اخطار را در کنسول خواهید دید و اکنون باید این کار را انجام دهید. (اگر صفحه رضایت شما قبلاً تنظیم شده است، از این مراحل بعدی رد شوید.)

روی «پیکربندی صفحه رضایت» کلیک کنید، جایی که یک برنامه «خارجی» (یا «داخلی» را اگر مشتری G Suite هستید انتخاب کنید):

f17e97b30d994b0c.png

توجه داشته باشید که برای اهداف این تمرین، مهم نیست که کدام را انتخاب می‌کنید، زیرا نمونه کد لبه خود را منتشر نمی‌کنید. اکثر افراد برای نمایش به صفحه پیچیده تر، "External" را انتخاب می کنند، اما شما در واقع فقط باید قسمت "Application name" را در بالا تکمیل کنید:

b107ab81349bdad2.png

تنها چیزی که در حال حاضر به آن نیاز دارید فقط یک نام برنامه است، بنابراین فردی را انتخاب کنید که نشان دهنده کدهای شما باشد و سپس روی ذخیره کلیک کنید.

ایجاد شناسه مشتری OAuth (user acct auth)

اکنون برای ایجاد شناسه مشتری OAuth2 به برگه Credentials برگردید. در اینجا انواع شناسه های مشتری OAuth را می بینید که می توانید ایجاد کنید:

5ddd365ac0af1e34.png

ما در حال توسعه یک ابزار خط فرمان هستیم که عبارت Other است، بنابراین آن را انتخاب کنید و سپس روی دکمه ایجاد کلیک کنید. یک نام شناسه مشتری که منعکس کننده برنامه ای است که ایجاد می کنید انتخاب کنید یا به سادگی نام پیش فرض را انتخاب کنید، که معمولاً «کلینت دیگر N » است.

در حال ذخیره اعتبار شما

  1. یک گفتگو با اعتبارنامه جدید ظاهر می شود. روی OK کلیک کنید تا بسته شود

8bec84d82cb104d7.png

  1. در صفحه اعتبارنامه ها، به بخش «شناسه های مشتری OAuth2» بروید و روی نماد دانلود کلیک کنید. f54b28417901b3aa.png در انتهای سمت راست شناسه مشتری تازه ایجاد شده شما. 1b4e8d248274a338.png
  2. این یک گفتگو برای ذخیره فایلی با نام client_secret- LONG-HASH-STRING .apps.googleusercontent.com.json باز می کند که احتمالاً در پوشه دانلودهای شما. ما توصیه می‌کنیم به نام ساده‌تری مانند client_secret.json (که همان چیزی است که برنامه نمونه استفاده می‌کند) کوتاه کنید، سپس آن را در فهرست/پوشه‌ای ذخیره کنید که در آن برنامه نمونه را در این Codelab ایجاد می‌کنید.

خلاصه

اکنون شما آماده فعال کردن APIهای Google به کار رفته در این کد لبه هستید. همچنین، برای نام برنامه در صفحه رضایت OAuth، "Vision API demo" را انتخاب کردیم، بنابراین انتظار دارید این مورد را در برخی از اسکرین شات های آینده مشاهده کنید.

6. Google API ها را فعال کنید

این آزمایشگاه کد از چهار (4) API Google Cloud، یک جفت از Google Cloud (Cloud Storage و Cloud Vision) و یک جفت دیگر از Google Workspace (Google Drive و Google Sheets) استفاده می‌کند. در زیر دستورالعمل های کلی برای فعال کردن API های Google آورده شده است. هنگامی که بدانید چگونه یک API را فعال کنید، بقیه مشابه هستند.

صرف نظر از اینکه از کدام API Google می خواهید در برنامه خود استفاده کنید، آنها باید فعال باشند. API ها را می توان از طریق خط فرمان یا از کنسول Cloud فعال کرد. فرآیند فعال کردن APIها یکسان است، بنابراین هنگامی که یک API را فعال می کنید، می توانید سایر API ها را به روشی مشابه فعال کنید.

گزینه 1: رابط خط فرمان gcloud (Cloud Shell یا محیط محلی)

در حالی که فعال کردن API ها از کنسول Cloud رایج تر است، برخی از توسعه دهندگان ترجیح می دهند همه چیز را از طریق خط فرمان انجام دهند. برای انجام این کار، باید «نام سرویس» یک API را جستجو کنید. به نظر می رسد یک URL: SERVICE_NAME .googleapis.com . می‌توانید اینها را در نمودار محصولات پشتیبانی شده بیابید یا می‌توانید با برنامه Google Discovery API آنها را جستجو کنید.

با استفاده از این اطلاعات، با استفاده از Cloud Shell (یا محیط توسعه محلی خود با ابزار خط فرمان gcloud نصب شده )، می توانید یک API یا سرویس را به شرح زیر فعال کنید:

gcloud services enable SERVICE_NAME.googleapis.com

مثال 1: Cloud Vision API را فعال کنید

gcloud services enable vision.googleapis.com

مثال 2: پلت فرم محاسباتی بدون سرور Google App Engine را فعال کنید

gcloud services enable appengine.googleapis.com

مثال 3: چند API را با یک درخواست فعال کنید. به عنوان مثال، اگر این کد لبه بینندگانی داشته باشد که برنامه ای را با استفاده از Cloud Translation API به App Engine، Cloud Functions و Cloud Run اجرا می کنند، خط فرمان به صورت زیر خواهد بود:

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

این دستور App Engine، Cloud Functions، Cloud Run و Cloud Translation API را فعال می کند. علاوه بر این، Cloud Artifact Registry را فعال می‌کند، زیرا در آنجاست که تصاویر کانتینر باید توسط سیستم Cloud Build ثبت شوند تا در Cloud Run مستقر شوند.

همچنین چند دستور وجود دارد که یا از APIها پرس و جو کنید تا فعال شوند یا کدام APIها قبلاً برای پروژه شما فعال شده اند.

مثال 4: پرس و جو برای Google API های موجود برای فعال کردن برای پروژه شما

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

مثال 5: پرس و جو برای Google API های فعال برای پروژه شما

gcloud services list

برای کسب اطلاعات بیشتر در مورد دستورات فوق، به مستندات خدمات فعال و غیرفعال و فهرست خدمات مراجعه کنید.

گزینه 2: Cloud Console

همچنین می‌توانید APIهای Google را در API Manager فعال کنید. از کنسول Cloud، به مدیر API بروید. در این صفحه داشبورد، برخی از اطلاعات ترافیک برنامه خود، نمودارهایی که درخواست های برنامه را نشان می دهد، خطاهای ایجاد شده توسط برنامه و زمان پاسخ برنامه خود را می بینید:

df4a0a5e00d29ffc.png

در زیر این نمودارها لیستی از Google APIهای فعال برای پروژه شما وجود دارد:

5fcf10e5a05cfb97.png

برای فعال کردن (یا غیرفعال کردن) API ها، روی Enable APIs and Services در بالا کلیک کنید:

eef4e5e863f4db66.png

از طرف دیگر، به نوار ناوبری سمت چپ بروید و APIs & ServicesLibrary را انتخاب کنید:

6eda5ba145b30b97.png

در هر صورت، به صفحه کتابخانه API خواهید رسید:

5d4f1c8e7cf8df28.png

یک نام API برای جستجو و دیدن نتایج منطبق وارد کنید:

35bc4b9cf72ce9a4.png

API مورد نظر برای فعال کردن را انتخاب کنید و روی دکمه Enable کلیک کنید:

9574a69ef8d9e8d2.png

فرآیند فعال کردن همه APIها مشابه است، صرف نظر از اینکه می خواهید از کدام API Google استفاده کنید.

هزینه

بسیاری از API های Google را می توان بدون هزینه استفاده کرد، با این حال، هنگام استفاده از اکثر محصولات و API های Google Cloud هزینه هایی وجود دارد. هنگام فعال کردن Cloud API، ممکن است از شما یک حساب صورتحساب فعال خواسته شود. با این حال، برخی از محصولات Google Cloud دارای یک ردیف «همیشه رایگان» هستند که برای متحمل شدن هزینه‌های صورت‌حساب باید از آن فراتر بروید.

کاربران جدید Google Cloud واجد شرایط استفاده از آزمایش رایگان هستند که در حال حاضر 300 دلار برای 90 روز اول خوب است. Codelabs معمولاً متحمل صورت‌حساب زیادی نمی‌شود، بنابراین ما به شما پیشنهاد می‌کنیم که آزمایش رایگان را تا زمانی که واقعاً آماده انجام تست درایو باشید، متوقف کنید، به خصوص که این یک پیشنهاد یک‌باره است. سهمیه های سطح رایگان منقضی نمی شوند و صرف نظر از اینکه از آزمایش رایگان استفاده می کنید یا خیر اعمال می شوند.

کاربران باید قبل از فعال کردن، به اطلاعات قیمت گذاری هر API مراجعه کنند (مثال: صفحه قیمت گذاری Cloud Vision API )، به خصوص توجه داشته باشند که آیا سطح رایگان دارد یا خیر، و اگر چنین است، چیست. تا زمانی که در مجموع در محدوده مشخص شده روزانه یا ماهانه بمانید، نباید هزینه ای متحمل شوید. قیمت‌گذاری و ردیف‌های رایگان بین APIهای گروه محصول Google متفاوت است. مثال ها:

صورت‌حساب محصولات مختلف Google متفاوت است، بنابراین حتماً به اسناد مناسب برای آن اطلاعات مراجعه کنید.

خلاصه

اکنون که Cloud Vision فعال شده است، سه API دیگر (Google Drive، Cloud Storage، Google Sheets) را به همین ترتیب روشن کنید. از Cloud Shell، از gcloud services enable یا از کنسول Cloud استفاده کنید:

  1. به کتابخانه API برگردید
  2. با تایپ چند حرف از نام آن جستجو را شروع کنید
  3. API مورد نظر را انتخاب کنید و
  4. فعال کردن

کف کنید، آبکشی کنید و تکرار کنید. برای Cloud Storage، چندین گزینه وجود دارد: "Google Cloud Storage JSON API" را انتخاب کنید. Cloud Storage 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() این نمونه پایتون 2-3 را سازگار می‌کند و واردات کتابخانه Google همه ابزارهای لازم برای برقراری ارتباط با APIهای Google را به همراه دارد.
  • متغیر SCOPES مجوزهای درخواست از کاربر را نشان می دهد — در حال حاضر تنها یک مورد وجود دارد: اجازه خواندن داده ها از Google Drive او.
  • باقی‌مانده کد پردازش اعتبار در توکن‌های OAuth2 ذخیره‌شده خوانده می‌شود، در صورتی که نشانه دسترسی اصلی منقضی شده باشد، احتمالاً به یک نشانه دسترسی جدید با نشانه تازه‌سازی به‌روزرسانی می‌شود.
  • اگر هیچ نشانه ای ایجاد نشده باشد یا بازیابی یک نشانه دسترسی معتبر به دلیل دیگری ناموفق باشد، کاربر باید از جریان سه پایه OAuth2 (3LO) عبور کند: گفتگو را با مجوزهای درخواست شده ایجاد کنید و از کاربر بخواهد بپذیرد. پس از انجام این کار، برنامه ادامه می‌یابد، در غیر این صورت tools.run_flow() یک استثنا ایجاد می‌کند و اجرا متوقف می‌شود.
  • هنگامی که کاربر اجازه می دهد، یک کلاینت HTTP برای ارتباط با سرور ایجاد می شود و همه درخواست ها برای امنیت با اعتبار کاربر امضا می شوند. سپس یک نقطه پایانی سرویس به Google Drive API (نسخه 3) با آن سرویس گیرنده HTTP ایجاد می شود و سپس به DRIVE اختصاص داده می شود.

در حال اجرای برنامه

اولین باری که اسکریپت را اجرا می‌کنید، مجوز دسترسی به فایل‌های کاربر در Drive (مال شما) را نخواهد داشت. خروجی با توقف اجرا به این شکل است:

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

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

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

  --noauth_local_webserver

اگر از Cloud Shell اجرا می‌کنید، به بخش «From Cloud Shell» بروید و در صورت لزوم، صفحه‌های مربوطه را در «از محیط توسعه محلی» مرور کنید.

از محیط توسعه محلی

با باز شدن پنجره مرورگر، اسکریپت خط فرمان متوقف می شود. ممکن است صفحه هشدار ترسناکی دریافت کنید که شبیه این است:

149241d33871a141.png

این یک نگرانی قانونی است، زیرا شما در حال تلاش برای اجرای برنامه ای هستید که به داده های کاربر دسترسی دارد. از آنجایی که این فقط یک برنامه آزمایشی است و شما توسعه دهنده آن هستید ، امیدواریم برای ادامه کار به اندازه کافی به خودتان اعتماد داشته باشید. برای درک بهتر این موضوع، خود را به جای کاربر خود قرار دهید: از شما خواسته می شود که به کد شخص دیگری اجازه دسترسی به داده های شما را بدهید. اگر قصد انتشار برنامه ای مانند این را دارید، مراحل تأیید را طی می کنید تا کاربران شما این صفحه را نبینند.

پس از کلیک بر روی پیوند "برو به برنامه "ناامن"، یک گفتگوی مجوزهای OAuth2 را دریافت خواهید کرد که چیزی شبیه به شکل زیر است—ما همیشه در حال بهبود رابط کاربری خود هستیم، بنابراین اگر دقیقاً مطابقت ندارد نگران نباشید:

a122eb7468d0d34e.png

گفتگوی جریان OAuth2 مجوزهایی را که توسعه دهنده درخواست می کند (از طریق متغیر SCOPES ) منعکس می کند. در این مورد، امکان مشاهده و دانلود از گوگل درایو کاربر است. در کد برنامه، این محدوده‌های مجوز به‌عنوان URI ظاهر می‌شوند، اما به زبان مشخص‌شده توسط منطقه کاربر ترجمه می‌شوند. در اینجا کاربر باید مجوز صریح مجوز(های) درخواستی را بدهد، در غیر این صورت یک استثنا ایجاد می شود تا اسکریپت ادامه پیدا نکند.

حتی ممکن است یک گفتگوی دیگر دریافت کنید که تأیید شما را می خواهد:

bf171080dcd6ec5.png

توجه : برخی از مرورگرهای وب متعددی استفاده می‌کنند که به حساب‌های مختلف وارد شده‌اند، بنابراین این درخواست مجوز ممکن است به برگه/پنجره مرورگر اشتباهی برود، و ممکن است مجبور شوید پیوند این درخواست را در مرورگری که با درستی وارد شده است، برش دهید. حساب کاربری

از Cloud Shell

از Cloud Shell، هیچ پنجره مرورگری ظاهر نمی شود و شما را گیر می کند. متوجه شوید که پیام تشخیصی در پایین برای شما در نظر گرفته شده است:

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

  --noauth_local_webserver

شما باید ^C (Ctrl-C یا سایر کلیدها را فشار دهید تا اجرای اسکریپت متوقف شود)، و آن را از پوسته خود با پرچم اضافی اجرا کنید. هنگامی که آن را به این شکل اجرا می کنید، در عوض خروجی زیر را دریافت خواهید کرد:

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

Go to the following link in your browser:

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

Enter verification code:

(با نادیده گرفتن هشدار، زیرا می دانیم storage.json هنوز ایجاد نشده است و) با پیروی از دستورالعمل ها در برگه مرورگر دیگری با آن URL، تجربه ای تقریباً مشابه با آنچه در بالا برای محیط های توسعه محلی توضیح داده شد، دریافت خواهید کرد (به تصاویر صفحه بالا مراجعه کنید. ). در پایان یک صفحه نهایی با کد تأیید برای وارد کردن در Cloud Shell وجود دارد:

40a567cda0f31cc9.png

این کد را کپی کرده و در پنجره ترمینال قرار دهید.

خلاصه

به غیر از " Authentication successful "، انتظار خروجی اضافی نداشته باشید. به یاد بیاورید که این فقط راه اندازی است... شما هنوز کاری انجام نداده اید. کاری که شما انجام داده اید ، سفر خود را با موفقیت به سمت چیزی آغاز کرده است که احتمال دارد بار اول به درستی اجرا شود. (بهترین بخش این است که فقط یک بار از شما درخواست مجوز شده است؛ همه اجراهای متوالی آن را نادیده می گیرند، زیرا مجوزهای شما در حافظه پنهان ذخیره شده است.) حالا اجازه دهید کد را مجبور کنیم کار واقعی انجام دهد که منجر به خروجی واقعی می شود.

عیب یابی

اگر به جای عدم خروجی خطا دریافت کردید، ممکن است به دلیل یک یا چند دلیل باشد، شاید این یکی:

8. مرحله 1: دانلود تصویر از Google Drive

در مرحله قبل توصیه می کنیم کد را به صورت analyze_gsimg.py ایجاد کرده و از آنجا ویرایش کنید. همچنین این امکان وجود دارد که همه چیز را مستقیماً در iPython یا پوسته استاندارد Python برش دهید، اما این کار دشوارتر است زیرا ما به ساخت برنامه تکه تکه ادامه می دهیم.

فرض کنید برنامه شما مجاز شده است و نقطه پایانی سرویس API ایجاد شده است. در کد شما، با متغیر DRIVE نشان داده شده است. اکنون بیایید یک فایل تصویری را در Google Drive خود پیدا کنیم و

آن را روی متغیری به نام NAME تنظیم کنید. آن را به اضافه تابع drive_get_img() زیر دقیقاً زیر کد مرحله 0 وارد کنید:

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] ) را بگیرید، نام فایل، نوع MIME آن، آخرین مهر زمانی اصلاح، و در نهایت، بار باینری آن را که توسط تابع get_media() بازیابی شده است (از طریق شناسه فایل آن) نیز در files() برگردانید. 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 در Drive و روی FILE تنظیم شده باشد، پس از اجرای موفقیت‌آمیز اسکریپت، باید خروجی را ببینید که تأیید می‌کند قادر به خواندن فایل از Drive است (اما در رایانه شما ذخیره نشده است):

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

عیب یابی

اگر خروجی موفقیت آمیزی مانند موارد بالا دریافت نکردید، ممکن است به دلیل یک یا چند دلیل باشد، شاید این یکی:

خلاصه

در این بخش، یاد گرفتید که چگونه (در 2 تماس جداگانه API) به Drive API متصل شوید و یک فایل خاص را پرس و جو کنید و سپس آن را دانلود کنید. مورد استفاده تجاری: داده‌های Drive خود را بایگانی کنید و شاید آن‌ها را تجزیه و تحلیل کنید، مانند ابزار Google Cloud. کد برنامه شما در این مرحله باید با آنچه در مخزن موجود در step1-drive/analyze_gsimg.py مطابقت داشته باشد.

درباره بارگیری فایل‌ها در Google Drive اینجا بیشتر بخوانید یا این پست و ویدیوی وبلاگ را بررسی کنید. این بخش از کد لبه تقریباً مشابه کل مقدمه‌ای است که به جای دانلود یک فایل، 100 فایل/پوشه اول را در Google Drive کاربر نمایش می‌دهد و از محدوده محدودتری استفاده می‌کند.

9. مرحله 2: فایل را در Cloud Storage بایگانی کنید

مرحله بعدی اضافه کردن پشتیبانی برای Google Cloud Storage است. برای این کار باید یک بسته پایتون دیگر، io وارد کنیم. مطمئن شوید که بخش بالای واردات شما اکنون به این شکل است:

from __future__ import print_function                   
import io

علاوه بر نام فایل Drive، به اطلاعاتی در مورد مکان ذخیره این فایل در فضای ذخیره‌سازی ابری نیاز داریم، به‌ویژه نام «سطل» که قرار است آن را در آن قرار دهید و هر پیشوند «پوشه والد». بیشتر در این مورد در یک لحظه:

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

یک کلمه در مورد سطل ها: Cloud Storage ذخیره سازی لکه های بی شکل را فراهم می کند. وقتی فایل‌ها را در آنجا آپلود می‌کند، مانند Google Drive مفهوم انواع فایل، پسوندها و غیره را نمی‌فهمد. آنها فقط "حباب" برای فضای ذخیره سازی ابری هستند. علاوه بر این، در Cloud Storage مفهومی از پوشه ها یا زیر شاخه ها وجود ندارد.

بله، می‌توانید برای نمایش انتزاع چندین زیرپوشه، اسلش ( / ) در نام فایل‌ها داشته باشید، اما در پایان روز، همه حباب‌های شما در یک سطل قرار می‌گیرند و " / "ها فقط کاراکترهایی در نام فایل‌ها هستند. برای اطلاعات بیشتر ، صفحه قراردادهای نامگذاری سطل و اشیاء را بررسی کنید.

مرحله 1 در بالا دامنه فقط خواندنی Drive را درخواست کرد. در آن زمان، این تنها چیزی است که نیاز داشتید. اکنون، مجوز آپلود (خواندن-نوشتن) در Cloud Storage مورد نیاز است. SCOPES از یک متغیر رشته ای به یک آرایه (تاپل پایتون [یا لیست]) از دامنه های مجوز تغییر دهید تا به این صورت به نظر برسد:

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

اکنون یک نقطه پایانی سرویس در فضای ذخیره‌سازی ابری درست زیر نقطه پایانی Drive ایجاد کنید. توجه داشته باشید که ما تماس را کمی تغییر دادیم تا از همان شیء مشتری 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 فقط سطل و نام های شیء را که از API بازگردانده می شود ، درخواست می کند. برای کسب اطلاعات بیشتر در مورد این ماسک های میدانی در درخواست های خوانده شده API ، این پست و فیلم را بررسی کنید.

اکنون استفاده از 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 بکشید تا کل "اصلی" به این شکل باشد:

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

با دقت نگاه کنید ، در حالی که بارگیری درایو موفق شد ، بارگذاری در Cloud Storage انجام نشد. چرا؟

دلیل این امر این است که وقتی ما این برنامه را در ابتدا برای مرحله 1 مجاز کردیم ، ما فقط دسترسی خواندنی به Google Drive را مجاز کردیم. در حالی که ما دامنه خواندن نوشتن را برای ذخیره سازی ابری اضافه کردیم ، هرگز کاربر را وادار نکردیم که این دسترسی را مجاز کند. برای کار کردن ، ما باید پرونده storage.json را که از دست رفته و دوباره اجرا شده است ، منفجر کنیم.

بعد از اینکه مجدداً مجاز هستید (این موضوع را با نگاه کردن به داخل storage.json تأیید کنید و هر دو دامنه را در آنجا ببینید) ، خروجی شما همانطور که انتظار می رود خواهد بود:

$ python3 analyze_gsimg.py

    . . .

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

خلاصه

این یک چیز بزرگ است ، که به شما نشان می دهد ، در خط نسبت کمی کد ، نحوه انتقال پرونده ها بین هر دو سیستم ذخیره سازی مبتنی بر ابر. مورد استفاده در اینجا برای تهیه نسخه پشتیبان از یک منبع احتمالاً محدود به "سردتر" ، ارزان تر ذخیره سازی همانطور که در ابتدا گفته شد. Cloud Storage بسته به اینکه به داده های خود به طور مرتب ، ماهانه ، سه ماهه یا سالانه دسترسی داشته باشید ، کلاس های مختلف ذخیره سازی را ارائه می دهد.

البته ، توسعه دهندگان از هر زمان به ما می پرسند که چرا Google Drive و Cloud Storage وجود دارد. از این گذشته ، آیا آنها هر دو فایل ذخیره در ابر نیستند؟ به همین دلیل ما این فیلم را ساختیم. کد شما در این مرحله باید با آنچه در repo در step2-gcs/analyze_gsimg.py مطابقت داشته باشد.

10. مرحله 3: با Cloud Vision تجزیه و تحلیل کنید

در حالی که ما اکنون می دانیم که شما می توانید داده ها را بین Google Cloud و فضای کاری Google جابجا کنید ، ما هنوز هیچ تحلیلی انجام نداده ایم ، بنابراین زمان آن است که تصویر را به Cloud Vision برای حاشیه نویسی برچسب AKA Detection ارسال کنید. برای انجام این کار ، ما باید داده ها را پایه گذاری کنیم ، به معنی ماژول پایتون دیگر ، base64 . اطمینان حاصل کنید که بخش واردات برتر شما اکنون به این شکل است:

from __future__ import print_function
import base64
import io

به طور پیش فرض ، Vision API تمام برچسب هایی را که پیدا می کند برمی گرداند. برای سازگاری با امور ، بیایید فقط 5 مورد برتر را درخواست کنیم (البته توسط کاربر قابل تنظیم است). برای این کار از یک متغیر متغیر TOP استفاده خواهیم کرد. آن را زیر تمام ثابت های دیگر اضافه کنید:

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

مانند مراحل قبلی ، ما به دامنه مجوز دیگری نیاز داریم ، این بار برای API Vision. SCOPES با رشته خود به روز کنید:

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

اکنون یک نقطه پایانی سرویس به Cloud Vision ایجاد کنید تا با دیگران مانند این هماهنگ باشد:

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

اکنون این عملکرد را اضافه کنید که بار تصویر را به Cloud Vision ارسال می کند:

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

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

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

تماس با images().annotate() به داده ها به علاوه ویژگی های API مورد نظر نیاز دارد. درپوش 5 برچسب برتر بخشی از بار است (اما کاملاً اختیاری). اگر تماس موفقیت آمیز باشد ، بار بار 5 برچسب برتر اشیاء را به همراه نمره اطمینان یک شیء در تصویر باز می گرداند. (اگر هیچ پاسخی برنگردد ، یک فرهنگ لغت پایتون خالی اختصاص دهید تا if عدم موفقیت در زیر ، موارد زیر باشد.) این عملکرد به سادگی آن داده ها را در یک رشته CSV برای استفاده نهایی در گزارش ما جمع می کند.

این 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

خلاصه

همه افراد تخصص یادگیری ماشین را برای ایجاد و آموزش مدل های ML خود برای تجزیه و تحلیل داده های خود ندارند. تیم Google Cloud برخی از مدل های از پیش آموزش Google را برای استفاده عمومی در دسترس قرار داده و آنها را در پشت API ها قرار داده و به دموکراتیک AI & ML برای همه کمک می کند.

اگر یک توسعه دهنده هستید و می توانید با API تماس بگیرید ، می توانید از یادگیری ماشین استفاده کنید. Cloud Vision فقط یکی از خدمات API است که می توانید برای تجزیه و تحلیل داده های خود با آن استفاده کنید. در مورد دیگران اینجا بیاموزید. کد شما اکنون باید با آنچه در repo در step3-vision/analyze_gsimg.py مطابقت داشته باشد.

11. مرحله 4: گزارشی را با Google Sheets تهیه کنید

در این مرحله ، شما توانسته اید داده های شرکت ها را بایگانی کرده و آن را تجزیه و تحلیل کنید ، اما آنچه فاقد آن است خلاصه ای از این کار است. بیایید تمام نتایج را در یک گزارش واحد سازماندهی کنیم که می توانید به رئیس خود تحویل دهید. چه چیزی بیشتر از یک صفحه گسترده در مدیریت حضور دارد؟

برای API Google Sheets واردات اضافی لازم نیست و تنها اطلاعات جدید مورد نیاز شناسه پرونده یک صفحه گسترده موجود است که قبلاً فرمت شده و در انتظار ردیف جدیدی از داده ها است ، از این رو SHEET ثابت است. توصیه می کنیم یک صفحه گسترده جدید ایجاد کنید که شبیه به موارد زیر باشد:

4DEF78583D05300.PNG

URL برای آن صفحه گسترده مانند موارد زیر خواهد بود: https://docs.google.com/spreadsheets/d/ FILE_ID /edit . آن FILE_ID را بگیرید و آن را به عنوان نیش به SHEET اختصاص دهید.

ما همچنین در یک عملکرد کوچک به نام k_ize() که بایت ها را به کیلوبیت تبدیل می کند ، چرت زدیم و آن را به عنوان یک lambda پایتون تعریف می کنیم زیرا این یک 1 لینر ساده است. هر دوی این یکپارچه با سایر ثابت ها به این شکل است:

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

اکنون یک نقطه پایانی سرویس به برگه های Google در نزدیکی دیگران ایجاد کنید ، بنابراین به نظر می رسد:

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

عملکرد sheet_append_row() ساده است: یک ردیف از داده ها و شناسه ورق بگیرید ، سپس آن ردیف را به آن برگه اضافه کنید:

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

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

spreadsheets().values().append() به شناسه پرونده برگه ، طیف وسیعی از سلول ها ، نحوه ورود داده ها و خود داده ها نیاز دارد. شناسه پرونده ساده است ، دامنه سلول ها در نماد A1 آورده شده است. طیف وسیعی از " Sheet1 " به معنای کل برگه است - این سیگنال ها به API برای اضافه کردن ردیف پس از تمام داده های موجود در برگه. یک جفت انتخاب در مورد چگونگی اضافه کردن داده ها به برگه ، " RAW " (وارد کردن داده های رشته رشته) یا " USER_ENTERED " وجود دارد (داده ها را بنویسید که گویی کاربر آن را با برنامه Google Sheets وارد صفحه کلید خود کرده است ، حفظ هرگونه ویژگی قالب بندی سلول).

اگر تماس موفقیت آمیز باشد ، مقدار بازگشت واقعاً چیز فوق العاده ای ندارد ، بنابراین ما تصمیم گرفتیم تعداد سلول ها را با درخواست API به روز کنیم. در زیر کدی است که به آن عملکرد می خواند:

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

برگه Google دارای ستون هایی است که داده هایی مانند هر "زیر مجموعه والدین" ، محل پرونده بایگانی شده در ذخیره سازی ابر (سطل + نام پرونده) ، Mimetype پرونده ، اندازه پرونده (در اصل در بایت ها ، اما با k_ize() تبدیل شده است. ) ، و رشته Cloud Vision String. همچنین توجه داشته باشید که مکان بایگانی شده یک لینک لینک است بنابراین مدیر شما می تواند برای تأیید با اطمینان از آن کلیک کند.

با افزودن بلوک کد بالا درست پس از نمایش نتایج از Cloud Vision ، بخش اصلی که برنامه را هدایت می کند اکنون کامل است ، اگرچه از نظر ساختاری کمی پیچیده است:

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

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

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

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

حذف storage.json آخرین بار و اجرای مجدد برنامه به روز شده باید منجر به خروجی مشابه موارد زیر شود ، با توجه به افزودن آنالیز چشم انداز ابر:

$ python3 analyze_gsimg.py

    . . .

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

خط اضافی خروجی ، در حالی که مفید است ، بهتر است با گرفتن یک نگاه در برگه Google به روز شده ، با آخرین خط (ردیف 7 در مثال زیر) به مجموعه داده های موجود اضافه شده قبلی اضافه شود:

B53A5BC944734652.png

خلاصه

در 3 مرحله اول این آموزش ، شما با Google Workspace و Google Cloud API برای جابجایی داده ها و تجزیه و تحلیل آن ، که 80 ٪ از کل کارها را نشان می دهد ، متصل شده اید. با این حال ، در پایان روز ، هیچ یک از این موارد به معنای چیزی نیست اگر نتوانید همه آنچه را که انجام داده اید به مدیریت ارائه دهید. برای تجسم بهتر نتایج ، خلاصه کردن تمام نتایج در یک گزارش تولید شده ، حجم صحبت می کند.

برای تقویت بیشتر سودمندی تجزیه و تحلیل ، علاوه بر نوشتن نتایج در صفحه گسترده ، یکی از پیشرفت های احتمالی این است که این 5 برچسب برتر برای هر تصویر نمایه شود تا یک پایگاه داده داخلی ساخته شود و به کارمندان مجاز اجازه می دهد تا با جستجو از تصاویر پرس و جو کنند تیم ، اما ما آن را به عنوان یک تمرین برای خوانندگان ترک می کنیم.

در حال حاضر ، نتایج ما در یک ورق است و برای مدیریت قابل دسترسی است. کد برنامه شما در این مرحله باید مطابق با آنچه در repo در step4-sheets/analyze_gsimg.py مطابقت داشته باشد. مرحله آخر تمیز کردن کد و تبدیل آن به یک اسکریپت قابل استفاده است.

12. *مرحله نهایی: Refactor

(اختیاری) داشتن یک برنامه کار خوب است ، اما آیا می توانیم آن را بهبود بخشیم؟ بله ، به خصوص برنامه اصلی که به نظر می رسد مانند یک آشفتگی شدید است. بیایید این کار را در عملکرد خود قرار دهیم و به جای ثابت ثابت ، امکان ورود کاربر را فراهم کنیم. ما این کار را با ماژول argparse انجام خواهیم داد. علاوه بر این ، بیایید یک برگه مرورگر وب را راه اندازی کنیم تا هنگامی که ردیف داده های خود را روی آن نوشتیم ، برگه را نمایش دهیم. این کار با ماژول webbrowser قابل انجام است. این واردات را با دیگران بافته کنید تا واردات برتر مانند این به نظر برسد:

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

برای اینکه بتوانیم از این کد در برنامه های دیگر استفاده کنیم ، ما به توانایی سرکوب خروجی نیاز داریم ، بنابراین بیایید یک پرچم DEBUG اضافه کنیم تا این اتفاق بیفتد ، اضافه کردن این خط برای پایان بخش ثابت در نزدیکی بالا:

DEBUG = False

اکنون ، در مورد بدن اصلی. همانطور که ما در حال ساخت این نمونه بودیم ، باید احساس "ناراحت کننده" کنید زیرا کد ما با هر سرویس اضافه شده ، سطح دیگری از لانه سازی را اضافه می کند. اگر چنین احساسی دارید ، تنها نیستید ، زیرا این امر به پیچیدگی کد می افزاید که در این پست وبلاگ تست Google توضیح داده شده است.

پس از این بهترین روش ، بیایید قسمت اصلی برنامه را به یک عملکرد سازماندهی کنیم و به جای لانه سازی در هر "نقطه شکست" 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 برای بازگرداندن خطوط سرکوب شده در حال حاضر که قبلاً دیده می شود ، نشان می دهد:

$ 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

گزینه های دیگر به کاربران اجازه می دهد تا نام پرونده های مختلف درایو ، ذخیره سازی ابری "Subdirectory" و نام سطل را انتخاب کنند ، نتایج "N" از Cloud Vision و صفحه گسترده (Sheets) File File را انتخاب کنند. با استفاده از این آخرین به روزرسانی ها ، نسخه نهایی کد شما اکنون باید با آنچه در repo در 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)

ما تمام تلاش خود را برای حفظ مطالب این آموزش به روز خواهیم کرد ، اما مواردی وجود خواهد داشت که repo جدیدترین نسخه کد را داشته باشد.

13. تبریک می گویم!

مطمئناً در این Codelab یادگیری زیادی وجود داشت ، و شما به این نتیجه رسیدید که از یکی از کدگذاری های طولانی تر زنده مانده است. در نتیجه ، شما با یک سناریوی شرکت احتمالی با حدود 130 پوند خط پایتون ، با استفاده از همه Google Cloud و Google Workspace ، و جابجایی داده ها بین آنها برای ایجاد یک راه حل کار ، مقابله کردید. در صورت تمایل می توانید برای همه نسخه های این برنامه (اطلاعات بیشتر در زیر) repo منبع باز را کشف کنید.

پاک کن

  1. استفاده از API های Google Cloud رایگان نیست در حالی که API های فضای کاری Google توسط هزینه اشتراک ماهانه Google Workpace شما پوشش داده می شود (کاربران مصرف کننده Gmail هزینه ماهانه صفر دارند) ، بنابراین هیچ نوع پاکسازی/Turndown API برای کاربران فضای کاری Google مورد نیاز نیست. برای Google Cloud ، می توانید به داشبورد کنسول ابری خود بروید و "کارت" صورتحساب را برای هزینه های تخمین زده شده بررسی کنید.
  2. برای Cloud Vision ، به شما اجازه می دهد تعداد مشخصی از تماس های API در هر ماه به صورت رایگان. بنابراین تا زمانی که در زیر آن محدودیت بمانید ، نیازی به خاموش کردن هر چیزی نیست و باید پروژه خود را غیرفعال و حذف کنید. اطلاعات بیشتر در مورد صورتحساب Vision API و سهمیه رایگان را می توان در صفحه قیمت گذاری آن یافت.
  3. برخی از کاربران ذخیره سازی ابری در هر ماه مبلغ رایگان ذخیره سازی را دریافت می کنند. اگر تصاویری که با استفاده از این CodeLab بایگانی می کنید باعث نمی شود که از آن سهمیه فراتر بروید ، هیچ هزینه ای متحمل نخواهید شد. اطلاعات بیشتر در مورد صورتحساب GCS و سهمیه رایگان را می توان در صفحه قیمت گذاری آن یافت. می توانید حباب ها را از مرورگر ذخیره سازی ابری مشاهده و به راحتی حذف کنید.
  4. استفاده شما از Google Drive همچنین ممکن است سهمیه ذخیره سازی داشته باشد ، و اگر از آن فراتر بروید (یا به آن نزدیک هستید) ، در واقع ممکن است از ابزاری که در این CodeLab ساخته اید برای بایگانی آن تصاویر به فضای ذخیره سازی ابری استفاده کنید تا فضای بیشتری را به خود اختصاص دهید رانندگی کنید. اطلاعات بیشتر در مورد ذخیره سازی Google Drive را می توان در صفحه قیمت گذاری مناسب برای کاربران اصلی Google Workspace یا کاربران Gmail/مصرف کننده یافت.

در حالی که اکثر برنامه های تجارت و شرکت های Google Workspace دارای ذخیره نامحدودی هستند ، این می تواند باعث شود پوشه های درایو شما به هم ریخته و/یا بیش از حد به هم ریخته و برنامه ای را که در این آموزش ساخته اید ، راهی عالی برای بایگانی پرونده های بیرونی و پاکسازی Google Drive شما باشد.

نسخه های جایگزین

در حالی که final/analyze_gsimg.py نسخه رسمی "آخرین" است که در این آموزش روی آن کار می کنید ، پایان داستان نیست. یک مسئله در مورد نسخه نهایی برنامه این است که از کتابخانه های AUTH قدیمی تر که مستهلک شده اند استفاده می کند. ما این مسیر را انتخاب کردیم زیرا ، در زمان این نوشتار ، کتابخانه های جدید AUTH از چندین عنصر اصلی پشتیبانی نمی کردند: مدیریت ذخیره سازی توکن OAuth و ایمنی موضوع.

کتابخانه های فعلی (جدیدتر)

با این حال ، در بعضی از مواقع ، کتابخانه های AUTT قدیمی دیگر پشتیبانی نمی شوند ، بنابراین ما شما را تشویق می کنیم نسخه هایی را که از کتابخانه های جدیدتر (فعلی) AUTH در پوشه alt repo استفاده می کنند ، مرور کنید حتی اگر این موضوع نباشد (اما می توانید خود را بسازید راه حل شخصی که هست). به دنبال پرونده هایی با *newauth* در نام آنها باشید.

کتابخانه های مشتری Google Cloud Product

Google Cloud توصیه می کند که همه توسعه دهندگان هنگام استفاده از API های Google Cloud از کتابخانه های مشتری محصول استفاده کنند. متأسفانه API های Cloud غیر Google در حال حاضر چنین کتابخانه ای ندارند. استفاده از کتابخانه های سطح پایین امکان استفاده مداوم از API را فراهم می کند و از ویژگی های خوانایی بهتر برخوردار است. مشابه توصیه فوق ، نسخه های جایگزین با استفاده از کتابخانه های مشتری Google Cloud Product در پوشه alt repo برای بررسی شما در دسترس هستند. به دنبال پرونده هایی با *-gcp* در نام آنها باشید.

مجوز حساب خدمات

هنگام کار صرفاً در ابر ، عموماً انسان ها و داده های کاربر (انسانی) وجود ندارند ، به همین دلیل حساب های خدمات و مجوز حساب خدمات در درجه اول با Google Cloud استفاده می شوند. با این حال ، اسناد فضای کاری Google به طور کلی متعلق به کاربران (انسانی) است ، به همین دلیل این آموزش از مجوز حساب کاربری استفاده می کند. این بدان معنا نیست که استفاده از API های Google Workspace با حساب های خدمات امکان پذیر نیست. تا زمانی که این حساب ها سطح دسترسی مناسب را داشته باشند ، مطمئناً می توان در برنامه ها استفاده کرد. مشابه موارد فوق ، نسخه های جایگزین با استفاده از مجوز حساب خدمات در پوشه alt repo برای بررسی شما در دسترس هستند. به دنبال پرونده هایی با *-svc* در نام آنها باشید.

کاتالوگ نسخه جایگزین

در زیر ، تمام نسخه های جایگزین final/analyze_gsimg.py را پیدا خواهید کرد که هر یک دارای یک یا چند مورد از ویژگی های فوق هستند. در نام پرونده هر نسخه ، به دنبال:

  • " oldauth " برای نسخه هایی با استفاده از کتابخانه های AUTH قدیمی (علاوه بر final/analyze_gsimg.py )
  • " newauth " برای کسانی که از کتابخانه های AUTH فعلی/جدیدتر استفاده می کنند
  • " gcp " برای کسانی که از کتابخانه های مشتری Google Cloud Product ، IE ، Google-Cloud-Storage و غیره استفاده می کنند.
  • " svc " برای کسانی که از یک حساب سرویس استفاده می کنند ("SVC Acct") به جای یک حساب کاربری

در اینجا همه نسخه ها وجود دارد:

نام فایل

توضیحات

final/analyze_gsimg.py

نمونه اولیه ؛ از کتابخانه های AUTH قدیمی تر استفاده می کند

alt/analyze_gsimg-newauth.py

همانند final/analyze_gsimg.py اما از کتابخانه های جدید AUTH استفاده می کند

alt/analyze_gsimg-oldauth-gcp.py

همانند final/analyze_gsimg.py اما از کتابخانه های مشتری Google Cloud Product استفاده می کند

alt/analyze_gsimg-newauth-gcp.py

همان alt/analyze_gsimg-newauth.py اما از کتابخانه های مشتری Google Cloud Product استفاده می کند

alt/analyze_gsimg-oldauth-svc.py

همانند final/analyze_gsimg.py اما از SVC acct به جای کاربر استفاده می کند

alt/analyze_gsimg-newauth-svc.py

همان alt/analyze_gsimg-newauth.py اما از svc acct auth به جای کاربر استفاده می کند

alt/analyze_gsimg-oldauth-svc-gcp.py

همانند alt/analyze_gsimg-oldauth-svc.py اما از کتابخانه های مشتری Google Cloud Product و همان alt/analyze_gsimg-oldauth-gcp.py استفاده می کند اما از SVC Acct Auth به جای کاربر استفاده می کند

alt/analyze_gsimg-newauth-svc-gcp.py

همان alt/analyze_gsimg-oldauth-svc-gcp.py اما از کتابخانه های جدید AUTH استفاده می کند

همراه با اصلی final/analyze_gsimg.py ، شما بدون در نظر گرفتن محیط توسعه Google API ، همه ترکیبات ممکن از راه حل نهایی را دارید و می توانید یکی را انتخاب کنید که مناسب نیازهای شما باشد. همچنین برای توضیح مشابه به alt/README.md مراجعه کنید.

مطالعه تکمیلی

در زیر چند ایده در مورد اینکه چگونه می توانید این تمرین را یک یا دو قدم دیگر انجام دهید. مشکل تنظیم شده راه حل فعلی می تواند گسترش یابد و به شما امکان می دهد این پیشرفت ها را انجام دهید:

  1. ( چندین تصویر در پوشه ها ) به جای پردازش یک تصویر ، بیایید بگوییم که در پوشه های Google Drive تصاویر داشتید.
  2. ( چندین تصویر در پرونده های زیپ ) به جای پوشه ای از تصاویر ، در مورد بایگانی ZIP حاوی پرونده های تصویری چطور؟ در صورت استفاده از پایتون ، ماژول zipfile را در نظر بگیرید.
  3. .
  4. .
  5. ( طبقه بندی اسناد ) به جای تجزیه و تحلیل تصاویر با Cloud Vision API ، بیایید بگوییم که شما فایلهای PDF دارید تا با API زبان طبیعی Cloud طبقه بندی کنید. با استفاده از راه حل های خود در بالا ، این PDF ها می توانند در پوشه های درایو یا بایگانی زیپ در درایو باشند.
  6. ( ایجاد ارائه ) از API اسلایدها برای تولید یک عرشه اسلاید از محتوای گزارش Google Sheet استفاده کنید. برای الهام بخش ، این پست و فیلم وبلاگ را در مورد تولید اسلایدها از داده های صفحه گسترده بررسی کنید.
  7. ( صادرات به عنوان PDF ) صفحه گسترده و/یا عرشه اسلاید را به عنوان PDF صادر کنید ، اما این ویژگی API های ورق ها و اسلایدها نیست. نکته : Google Drive API. اعتبار اضافی : هر دو صفحه و اسلایدها PDF را در یک PDF Master با ابزارهایی مانند GhostScript (Linux ، Windows) یا Combine PDF Pages.action (Mac OS X) ادغام کنید.

بیشتر بدانید

Codelabs

ژنرال

Google Workspace

Google Cloud

مجوز

این اثر تحت مجوز Creative Commons Attribution 2.0 Generic مجوز دارد.