Pengarsipan gambar, analisis, dan pembuatan laporan dengan G Suite & GCP

Codelab ini menggambarkan kemungkinan alur kerja perusahaan: pengarsipan gambar, analisis, dan pembuatan laporan. Bayangkan organisasi Anda memiliki serangkaian gambar yang menghabiskan ruang penyimpanan di resource yang terbatas. Anda ingin mengarsipkan data itu, menganalisis gambar tersebut, dan yang paling penting, membuat laporan yang merangkum lokasi pengarsipan serta hasil analisis, yang telah tersusun rapi dan siap untuk digunakan manajemen. Google Cloud menyediakan alat untuk mewujudkan hal ini, dengan menggunakan API dari dua lini produknya, G Suite dan Google Cloud Platform (GCP).

Dalam skenario kami, pengguna bisnis akan memiliki gambar di Google Drive. Cukup masuk akal untuk mencadangkan gambar tersebut ke penyimpanan yang lebih murah dan "lebih dingin", seperti kelas penyimpanan yang tersedia di Google Cloud Storage. Google Cloud Vision memungkinkan developer dapat mengintegrasikan fitur deteksi visi dalam aplikasi dengan mudah, termasuk deteksi objek dan bangunan terkenal, pengenalan karakter optik (OCR), dll. Terakhir, spreadsheet (Google Spreadsheet) merupakan alat visualisasi yang berguna untuk merangkum semua ini untuk atasan Anda.

Setelah menyelesaikan codelab ini untuk membuat solusi yang memanfaatkan seluruh Google Cloud, kami berharap Anda akan terinspirasi untuk membuat sesuatu yang lebih berdampak bagi organisasi atau pelanggan Anda.

Yang akan Anda pelajari

  • Cara menggunakan Cloud Shell
  • Cara Mengautentikasi permintaan API
  • Cara menginstal library klien Google API untuk Python
  • Cara mengaktifkan Google API
  • Cara mendownload file dari Google Drive
  • Cara mengupload objek/blob ke Cloud Storage
  • Cara menganalisis data dengan Cloud Vision
  • Cara menulis baris ke Google Spreadsheet

Yang akan Anda perlukan

  • Akun Google (akun G Suite mungkin memerlukan persetujuan administrator)
  • Project Google Cloud Platform dengan akun penagihan GCP yang aktif
  • Pemahaman tentang perintah terminal/shell sistem operasi
  • Keahlian dasar dalam Python (2 atau 3), tetapi Anda dapat menggunakan bahasa apa pun yang didukung

Memiliki pengalaman dengan keempat produk Google Cloud yang tercantum di atas akan sangat membantu, tetapi tidak diwajibkan. Jika Anda memiliki waktu untuk mengenalnya secara terpisah terlebih dahulu, Anda dapat mengerjakan codelab untuk masing-masing produk sebelum membahas latihan di sini:

Survei

Bagaimana Anda akan menggunakan tutorial ini?

Hanya membacanya Membacanya dan menyelesaikan latihan

Bagaimana penilaian Anda terhadap pengalaman dengan Python?

Pemula Menengah Mahir

Bagaimana penilaian Anda terhadap pengalaman menggunakan layanan Google Cloud Platform?

Pemula Menengah Mahir

Bagaimana penilaian Anda terhadap pengalaman menggunakan layanan developer G Suite?

Pemula Menengah Mahir

Apakah Anda ingin melihat lebih banyak codelab "berorientasi bisnis" atau codelab yang merupakan pengantar fitur produk?

Ya Tidak Dua-duanya

Penyiapan lingkungan mandiri

  1. Login ke Cloud Console dan buat project baru atau gunakan kembali project yang sudah ada. (Jika belum memiliki akun Gmail atau G Suite, Anda harus membuatnya.)

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

Ingat project ID, nama unik di semua project Google Cloud (maaf, nama di atas telah digunakan dan tidak akan berfungsi untuk Anda!) Project ID tersebut selanjutnya akan dirujuk di codelab ini sebagai PROJECT_ID.

  1. Selanjutnya, Anda harus mengaktifkan penagihan di Cloud Console untuk menggunakan resource Google Cloud.

Menjalankan operasi dalam codelab ini seharusnya tidak memerlukan banyak biaya, bahkan mungkin tidak sama sekali. Pastikan untuk mengikuti petunjuk yang ada di bagian "Membersihkan" yang memberi tahu Anda cara menonaktifkan resource sehingga tidak menimbulkan penagihan di luar tutorial ini. Pengguna baru Google Cloud memenuhi syarat untuk mengikuti program Uji Coba Gratis senilai $300 USD.

Mulai Cloud Shell

Ringkasan

Meskipun Anda dapat mengembangkan kode secara lokal di laptop, tujuan sekunder codelab ini adalah untuk mengajarkan cara menggunakan Google Cloud Shell, lingkungan command line yang berjalan di cloud melalui browser web modern.

Aktifkan Cloud Shell

  1. Dari Cloud Console, klik Aktifkan Cloud Shell H7JlbhKGHITmsxhQIcLwoe5HXZMhDlYue4K-SPszMxUxDjIeWfOHBfxDHYpmLQTzUmQ7Xx8o6OJUlANnQF0iBuUyfp1RzVad_4nCa0Zz5LtwBlUZFXFCWFrmrWZLqg1MkZz2LdgUDQ.

zlNW0HehB_AFW1qZ4AyebSQUdWm95n7TbnOr7UVm3j9dFcg6oWApJRlC0jnU1Mvb-IQp-trP1Px8xKNwt6o3pP6fyih947sEhOFI4IRF0W7WZk6hFqZDUGXQQXrw21GuMm2ecHrbzQ

Jika belum pernah memulai Cloud Shell, Anda akan melihat layar perantara (di paruh bawah) yang menjelaskan apa itu Cloud Shell. Jika demikian, klik Lanjutkan (dan Anda tidak akan pernah melihatnya lagi). Berikut tampilan layar sekali-tampil tersebut:

kEPbNAo_w5C_pi9QvhFwWwky1cX8hr_xEMGWySNIoMCdi-Djx9AQRqWn-__DmEpC7vKgUtl-feTcv-wBxJ8NwzzAp7mY65-fi2LJo4twUoewT1SUjd6Y3h81RG3rKIkqhoVlFR-G7w

Perlu waktu beberapa saat untuk penyediaan dan terhubung ke Cloud Shell.

pTv5mEKzWMWp5VBrg2eGcuRPv9dLInPToS-mohlrqDASyYGWnZ_SwE-MzOWHe76ZdCSmw0kgWogSJv27lrQE8pvA5OD6P1I47nz8vrAdK7yR1NseZKJvcxAZrPb8wRxoqyTpD-gbhA

Mesin virtual ini berisi semua alat pengembangan yang Anda perlukan. Layanan ini menawarkan direktori beranda tetap sebesar 5 GB dan beroperasi di Google Cloud, sehingga sangat meningkatkan performa dan autentikasi jaringan. Sebagian besar pekerjaan Anda dalam codelab ini dapat dilakukan hanya dengan browser atau Chromebook.

Setelah terhubung ke Cloud Shell, Anda akan melihat bahwa Anda sudah diautentikasi dan project sudah ditetapkan ke project ID Anda.

  1. Jalankan perintah berikut di Cloud Shell untuk mengonfirmasi bahwa Anda telah diautentikasi:
gcloud auth list

Output perintah

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

Output perintah

[core]
project = <PROJECT_ID>

Jika tidak, Anda dapat menyetelnya dengan perintah ini:

gcloud config set project <PROJECT_ID>

Output perintah

Updated property [core/project].

Codelab ini mengharuskan Anda untuk menggunakan bahasa Python (meskipun banyak bahasa yang didukung oleh library klien Google API, jadi silakan buat sesuatu yang setara di alat pengembangan favorit Anda dan cukup gunakan Python sebagai kode semu). Secara khusus, codelab ini mendukung Python 2 dan 3, namun sebaiknya Anda beralih ke 3.x sesegera mungkin.

Cloud Shell adalah kemudahan yang tersedia bagi pengguna secara langsung dari Cloud Console dan tidak memerlukan lingkungan pengembangan lokal, jadi tutorial ini dapat dilakukan sepenuhnya di cloud dengan browser web. Cloud Shell sangat berguna jika Anda sedang mengembangkan atau berencana untuk terus mengembangkan dengan produk & API GCP. Lebih khusus untuk codelab ini, Cloud Shell telah menginstal kedua versi Python.

Cloud Shell juga telah menginstal IPython... ini adalah penafsir Python interaktif tingkat tinggi yang kami rekomendasikan, terutama jika Anda menjadi bagian dari komunitas data science atau machine learning. Jika ya, IPython adalah penafsir default untuk Jupyter Notebooks serta Colab, Jupyter Notebooks dihosting oleh Google Research.

IPython lebih dulu mendukung penafsir Python 3, tetapi bisa mendukung Python 2 jika 3.x tidak tersedia. IPython dapat diakses dari Cloud Shell, tetapi juga dapat diinstal di lingkungan pengembangan lokal. Keluar dengan ^D (Ctrl-d) dan terima tawaran untuk keluar. Contoh output ipython awal akan terlihat seperti ini:

$ 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]:

Jika IPython bukan preferensi Anda, penggunaan penafsir interaktif Python standar (baik di Cloud Shell atau lingkungan pengembangan lokal Anda) sangat dapat diterima (juga keluar dengan ^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 ini juga mengasumsikan bahwa Anda memiliki alat penginstalan pip (pengelola paket Python dan resolver dependensi). Alat ini hadir dalam bentuk paket dengan versi 2.7.9+ atau 3.4+. Jika Anda memiliki versi Python yang lebih lama, lihat panduan ini untuk petunjuk penginstalan. Bergantung pada izin Anda, Anda mungkin perlu memiliki sudo atau akses superuser, tetapi biasanya tidak demikian. Anda juga dapat menggunakan pip2 atau pip3 secara eksplisit untuk menjalankan pip untuk versi Python tertentu.

Bagian selebihnya dari codelab ini mengasumsikan bahwa Anda menggunakan Python 3—petunjuk spesifik akan disediakan untuk Python 2 jika petunjuk tersebut jauh berbeda dari 3.x.

*Membuat dan menggunakan lingkungan virtual

Bagian ini bersifat opsional dan hanya benar-benar diperlukan bagi mereka yang harus menggunakan lingkungan virtual untuk codelab ini (sesuai sidebar peringatan di atas). Jika hanya memiliki Python 3 di komputer, Anda cukup mengeluarkan perintah ini untuk membuat virtualenv yang disebut my_env (Anda dapat memilih nama lain jika diinginkan):

virtualenv my_env

Namun, jika Anda memiliki Python 2 & 3 di komputer, sebaiknya instal virtualenv Python 3 yang dapat Anda lakukan dengan -p flag seperti ini:

virtualenv -p python3 my_env

Masukkan virtualenv yang baru Anda buat dengan "mengaktifkannya" seperti ini:

source my_env/bin/activate

Konfirmasikan bahwa Anda berada di lingkungan tersebut dengan mengamati perintah shell yang sekarang diawali dengan nama lingkungan Anda, yaitu,

(my_env) $

Sekarang Anda semestinya dapat pip install paket apa pun yang diperlukan, mengeksekusi kode dalam lingkungan ini, dll. Manfaat lainnya adalah jika Anda benar-benar mengacaukannya, masuk ke situasi ketika penginstalan Python Anda rusak, dll., Anda dapat menyingkirkan seluruh lingkungan ini tanpa memengaruhi sistem lainnya.

Codelab ini memerlukan penggunaan library klien Google API untuk Python, sehingga proses penginstalan menjadi sederhana, atau, Anda mungkin tidak perlu melakukan apa pun.

Sebelumnya, kami menyarankan Anda untuk mempertimbangkan menggunakan Cloud Shell demi kenyamanan. Anda dapat menyelesaikan seluruh tutorial dari browser web di cloud. Alasan lain untuk menggunakan Cloud Shell adalah karena banyak alat pengembangan populer dan library yang diperlukan sudah terinstal.

*Menginstal library klien

(opsional) Langkah ini dapat dilewati jika Anda menggunakan Cloud Shell atau lingkungan lokal yang sudah menginstal library klien. Anda hanya perlu melakukan ini jika Anda mengembangkan secara lokal dan belum (atau tidak yakin telah) menginstalnya klien. Cara termudah adalah menggunakan pip (atau pip3) untuk melakukan penginstalan (termasuk memperbarui pip jika diperlukan):

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

Mengonfirmasi penginstalan

Perintah ini menginstal library klien serta paket apa pun yang diperlukan library klien. Entah Anda menggunakan Cloud Shell atau lingkungan Anda sendiri, pastikan library klien diinstal dengan mengimpor paket yang diperlukan, dan pastikan tidak ada error impor (atau output):

python3 -c "import googleapiclient, httplib2, oauth2client"

Jika menggunakan Python 2 (dari Cloud Shell), Anda akan mendapatkan peringatan bahwa dukungan untuk Python 2 sudah tidak digunakan lagi:

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

Setelah berhasil menjalankan perintah "test" impor tersebut (tanpa error/output), Anda siap untuk mulai bekerja dengan Google API.

Ringkasan

Karena ini adalah codelab perantara, diasumsikan bahwa Anda sudah memiliki pengalaman dalam membuat & menggunakan project di konsol. Jika Anda baru menggunakan Google API, dan khususnya G Suite API, coba codelab pengantar G Suite API terlebih dahulu. Selain itu, jika Anda mengetahui cara membuat (atau menggunakan kembali) kredensial akun pengguna (bukan akun layanan), letakkan file client_secret.json ke dalam direktori kerja Anda, lewati modul berikutnya, dan langsung ke bagian "Mengaktifkan Google API".

Bagian ini dapat dilewati jika Anda telah membuat kredensial otorisasi akun pengguna dan mengetahui prosesnya. Ini berbeda dengan otorisasi akun layanan yang tekniknya berbeda, jadi lanjutkan di bawah.

Pengantar tentang otorisasi (plus beberapa autentikasi)

Untuk membuat permintaan ke API, aplikasi Anda harus memiliki otorisasi yang tepat. Autentikasi, sebuah kata yang mirip, menjelaskan kredensial login—Anda mengautentikasi diri sendiri saat login ke akun Google dengan login & sandi. Setelah diautentikasi, langkah berikutnya adalah apakah Anda—atau lebih tepatnya, kode Anda,—diotorisasi untuk mengakses data, seperti file blob di Cloud Storage atau file pribadi pengguna di Google Drive.

Google API mendukung beberapa jenis otorisasi, namun yang paling umum untuk pengguna G Suite API adalah otorisasi pengguna karena aplikasi contoh dalam codelab ini mengakses data milik pengguna akhir. Pengguna akhir tersebut harus memberikan izin kepada aplikasi Anda untuk mengakses datanya. Ini berarti kode Anda harus mendapatkan kredensial OAuth2 akun pengguna.

Untuk mendapatkan kredensial OAuth2 untuk otorisasi pengguna, kembali ke pengelola API dan pilih tab "Kredensial" di navigasi sebelah kiri:

Y33PZ_rJC1y7NH7Rrvq1kN_WxZ9CppDGJK8tTSaha298Jlm5pMqgnyweIO4oX34fcLy0_VI4gihYu5wpEM_LeJg1iDAFoidhUVyfqJX3QTzODQ_OGjHLXYBxPpUvihCJi9JGwvMREw

Setelah itu, Anda akan melihat semua kredensial dalam tiga bagian terpisah:

ComE4qh76dwZbIehkDUm1QawHGia_qVe7w7rkmgbeo_wjWS--kqXCt4_zvm55iy_RXA8dKYKvBxIKazkcYQ8871SA_kNslbvum_n1Ju4k9qJJSMtDhPAnofcvIlqlKm1nu7PBQhmEg

Bagian pertama adalah untuk kunci API, bagian kedua untuk client ID OAuth 2.0, dan bagian ketiga untuk akun layanan OAuth2—kita menggunakan bagian yang di tengah.

Membuat kredensial

Dari halaman Kredensial, klik tombol + Buat Kredensial di bagian atas, yang akan menampilkan dialog tempat Anda memilih "Client ID OAuth:"

C7jTddfrczo3GewPGCxbxX13GawtFc6FGvAPFusPc_IW-tr5M6xgXd1OzOHOUTo86WDa9fXiCITogv9b3wAgOcYM7xS3AmVNaPdTxbAynIe_sia2_x3LEPsBrdbX8NjeI2WaHRioOA

Pada layar berikutnya, Anda memiliki 2 tindakan: mengonfigurasi "layar izin" otorisasi aplikasi dan memilih jenis aplikasi:

El9_aqPQ6Q9hOsOp3JUC5qnCm_A_BVI-oCEfPk_MsvybnWBmC5lT6CtXSoZ7EQoFzrcBEzo4zF9s8CbhXyo0e-eSY3pZ1zg0BRvT0YssMMhbzEG-gP_jiO8v9q9HYTjg-QW5jJ0RDA

Jika belum menyetel layar izin, Anda akan melihat peringatan di konsol dan harus menyetelnya sekarang. (Lewati langkah berikutnya ini jika layar izin Anda sudah disetel.)

Klik "Konfigurasikan layar izin", pilih aplikasi "Eksternal" (atau "Internal" jika Anda adalah pelanggan G Suite):

5w-9R6gPvUHFzODZxXy-0GEhL8ZGDGNea3QtMp1FFYDv5DJ_MIDD21NEh3CzI-GKNzy6bkhH7bohxOG8icQTegiWlavOQhQqhSy7K31Ma3YTI9aAP3P-LmTBanPslX1cnjKLVZBi8A

Perlu diperhatikan, untuk keperluan latihan ini, tidak masalah apa yang Anda pilih karena Anda tidak memublikasikan sampel codelab Anda. Sebagian besar orang akan memilih "Eksternal" untuk diarahkan ke layar yang lebih kompleks, namun Anda hanya perlu mengisi kolom "Nama aplikasi" di bagian atas:

8e9z_RQz8lumYbDIcBvm57_Gpptn9uhrVQHoRzJ01AJNOFmXloDO7Eg3hhzJZZIU2F5rR0MxTCw-oXVFCq683xUwD4O33pXeuFsOMtM8EZhyjDoYc8Kv4hEoaG0Ztq9ePx6De7YmfA

Satu-satunya yang Anda butuhkan saat ini adalah nama aplikasi, jadi pilih seseorang yang mencerminkan codelab yang Anda kerjakan, lalu klik Simpan.

Membuat client ID OAuth (autentikasi akun pengguna)

Sekarang kembali ke tab Kredensial untuk membuat client ID OAuth2. Di sini Anda akan melihat berbagai client ID OAuth yang dapat Anda buat:

f8reuhsxOUNLcVrEIyRVsmP_fX_ceIlLvEKql1YHwSPW9jk9Mm9fJ0UlfUoi8eRN3QQXar4xtpo071zj6LSczNN7TYY8zB96Dn6ICZuvCAtjIgJSKdMSlX-ZhMuSWFpxxv661aUemw

Kita sedang mengembangkan alat command line, yaitu Lainnya, jadi pilih itu, lalu klik tombol Buat. Pilih nama client ID yang mencerminkan aplikasi yang sedang Anda buat atau cukup gunakan nama default, yaitu "Klien lain N".

Menyimpan kredensial Anda

  1. Dialog dengan kredensial baru akan muncul; klik Oke untuk menutup

rAwekj_GNEuVwGbZOYYlGDQjlu4flE61OPEZIUmwMI5vGi3W365UwVCxi0mVNhg4WZSSczZywrZZ6NDM_U0FJ4b-TOIMEC189uybOJjgn8F_axesVMopel9RlehRBXdEFhN4d41WGQ

  1. Kembali ke halaman Kredensial, scroll ke bawah ke bagian "Client ID OAuth2" lalu cari dan klik ikon download aAmje6kT_xSUM4BKIlPREpjosx7C_xxwpWqBgiGVfVWxQ8nnQOfxTPhuU0QwSnmbjykZffGrqyP1nnKrEQ7D7OqYaGw_Uzscs9gX2RwwP4AmvtHIiTFLa0gkprzJSjG9pQSx7HtmSQ di ujung kanan bawah client ID yang baru dibuat. x-vb-sKZy-X8a1X4uTsBWotSd4wn0PGt4mHMNv6DUrq5J5ihpujUyTiIVr5SHw0p2ZDy0KTP-zqOaFX-Az9BYDWG90KNFmsRLTUOo1mUVk7dYRJiK3VwYJNU0bbxjsbbpqcTr5_oLw
  2. Tindakan ini akan membuka dialog untuk menyimpan file bernama client_secret-LONG-HASH-STRING.apps.googleusercontent.com.json, kemungkinan ke folder Download Anda. Sebaiknya persingkat menjadi nama yang lebih mudah seperti client_secret.json (yang digunakan oleh aplikasi contoh), lalu simpan ke direktori/folder tempat Anda akan membuat aplikasi contoh dalam codelab ini.

Ringkasan

Sekarang Anda siap untuk mengaktifkan Google API yang digunakan dalam codelab ini. Selain itu, untuk nama aplikasi pada layar izin OAuth, kami memilih, "demo Vision API", sehingga Anda dapat melihatnya di beberapa screenshot berikutnya.

Pengantar

Codelab ini menggunakan empat (4) Google Cloud API, sepasang dari GCP (Cloud Storage dan Cloud Vision) dan sepasang lainnya dari G Suite (Google Drive dan Google Spreadsheet). Di bawah ini adalah petunjuk untuk mengaktifkan Vision API saja. Setelah mengetahui cara mengaktifkan satu API, Anda harus mengaktifkan 3 API lainnya sendiri.

Sebelum Anda bisa mulai menggunakan Google API, Anda harus mengaktifkannya. Contoh di bawah menunjukkan apa yang akan Anda lakukan untuk mengaktifkan Cloud Vision API. Dalam codelab ini, Anda mungkin menggunakan satu atau beberapa API, dan harus mengikuti langkah-langkah yang serupa untuk mengaktifkannya sebelum penggunaan.

Dari Cloud Shell

Menggunakan Cloud Shell, Anda dapat mengaktifkan API dengan menggunakan perintah berikut:

gcloud services enable vision.googleapis.com

Dari Cloud Console

Anda juga dapat mengaktifkan Vision API di Pengelola API. Dari Cloud Console, buka Pengelola API, lalu pilih "Library".

mg03by3QV6kco0rVVV_8IA6VobAoMG4Yoyl-PofNM0dHK8IcoDmpoLUwWeiKFFjpxHWlS1td5-0n7kNkfqHVhSsTSW_hUMvRu3D72g3LCFb7u4v4bla_Z4XyonTVK8PpigMLJcE01g

Di kotak penelusuran, mulailah mengetik "vision", lalu pilih Vision API saat muncul. Tampilan mungkin terlihat seperti ini saat Anda mengetik:

B6fWWsVhymufgQx6oGIq4sgukK6JQ1VoguVOrSNf_anQb6Cv6RTLtsjx5Qdeu3-uO8-8PyqwZLYdDDjYW5o56R47cnsd_88RKTMqNkpFeDESW2hmBM_7FK2UAMz1_216yXERYSp_JA

Pilih Cloud Vision API untuk mendapatkan dialog yang Anda lihat di bawah, lalu klik tombol "Aktifkan":

D-MONPLi0UWH6Dp607Dod6JF-LJQZIiUQEPQNKM4Y0mSt09KfipbeeXRAE6cokArBYTfL9VQoONc4L0jlnsUYLsNytQIPfSKr9lCDrXmrrx-1w64LeWWa-byDxcyYWZdCI0mAcVzBw

Biaya

Meskipun banyak Google API yang dapat digunakan tanpa biaya, penggunaan GCP (produk & API) tidak gratis. Saat mengaktifkan Vision API (seperti dijelaskan di atas), Anda mungkin diminta untuk memberikan akun penagihan yang aktif. Sebelum mengaktifkan, pengguna harus merujuk pada informasi harga Vision API. Perlu diingat bahwa produk Google Cloud Platform (GCP) tertentu memiliki paket "Selalu Gratis" yang harus Anda lampaui agar muncul penagihan. Untuk keperluan codelab, setiap panggilan ke Vision API diperhitungkan terhadap paket gratis tersebut, dan selama Anda tidak melebihi batas agregat (dalam setiap bulan), Anda tidak akan dikenakan biaya apa pun.

Beberapa Google API, yaitu, G Suite, memiliki penggunaan yang tercakup dalam langganan bulanan, sehingga tidak ada penagihan langsung untuk penggunaan API Gmail, Google Drive, Kalender, Dokumen, Spreadsheet, dan Slide, misalnya. Produk Google yang berbeda ditagih secara berbeda, jadi pastikan untuk merujuk dokumentasi API Anda untuk informasi tersebut.

Ringkasan

Setelah Cloud Vision diaktifkan, aktifkan tiga API lainnya (Google Drive, Cloud Storage, Google Spreadsheet) dengan cara yang sama... dari Cloud Shell, gunakan gcloud services enable, atau dari Cloud Console:

  1. Kembali ke Library API
  2. Mulai penelusuran dengan mengetik beberapa huruf dari namanya
  3. Pilih API yang diinginkan, dan
  4. Aktifkan

Ulangi prosesnya. Untuk Cloud Storage, ada beberapa pilihan... pilih "Google Cloud Storage JSON API". Cloud Storage API juga akan meminta akun penagihan yang aktif.

Ini adalah bagian awal dari sebuah kode berukuran sedang, jadi kami ingin menerapkan praktik yang fleksibel dan memastikan bagian infrastruktur yang umum, stabil, dan berfungsi sebelum menangani aplikasi utama. Periksa kembali apakah client_secret.json tersedia di direktori Anda saat ini dan mulai ipython lalu masukkan cuplikan kode berikut, atau simpan ke analyze_gsimg.py dan jalankan dari shell (opsi kedua lebih disukai karena kita akan terus menambahkan ke contoh kode):

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)

Komponen inti ini mencakup blok kode untuk impor modul/paket, pemrosesan kredensial autentikasi pengguna, dan pembuatan endpoint layanan API. Bagian utama kode yang harus Anda tinjau:

  • Mengimpor fungsi print() membuat sampel Python 2-3 ini kompatibel, dan impor library Google menerapkan semua alat yang diperlukan untuk berkomunikasi dengan Google API.
  • Variabel SCOPES mewakili izin untuk meminta dari pengguna — untuk saat ini hanya ada satu: izin untuk membaca data dari Google Drive mereka
  • Sisa kode pemrosesan kredensial membaca di token OAuth2 yang disimpan dalam cache, kemungkinan memperbarui menjadi token akses baru dengan token refresh jika token akses asli telah kedaluwarsa.
  • Jika tidak ada token dibuat atau pengambilan token akses yang valid gagal karena alasan lain, pengguna harus melalui alur 3-legged OAuth2 (3LO): membuat dialog pengajuan izin dan meminta pengguna untuk menerima. Setelah melakukannya, aplikasi akan berlanjut, jika tidak, tools.run_flow() akan memberikan pengecualian dan eksekusi terhenti.
  • Setelah pengguna memberikan izin, klien HTTP dibuat untuk berkomunikasi dengan server, dan semua permintaan ditandatangani dengan kredensial pengguna untuk keamanan. Kemudian, endpoint layanan ke Google Drive API (versi 3) dibuat dengan klien HTTP tersebut yang kemudian ditetapkan ke DRIVE.

Menjalankan aplikasi

Saat pertama kali dijalankan, skrip tidak akan memiliki otorisasi untuk mengakses file pengguna di Drive (milik Anda). Outputnya akan terlihat seperti ini dengan eksekusi dijeda:

$ 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

Jika Anda menjalankan dari Cloud Shell, lanjutkan ke bagian "Dari Cloud Shell", lalu scroll kembali untuk meninjau layar yang relevan di bagian "Dari lingkungan pengembangan lokal" jika sesuai.

Dari lingkungan pengembangan lokal

Skrip command-line dijeda saat jendela browser terbuka. Anda mungkin mendapatkan halaman peringatan yang tampak menakutkan seperti ini:

250b74709b3737dc.png

Ini adalah masalah yang masuk akal, karena Anda mencoba menjalankan aplikasi yang mengakses data pengguna. Karena ini hanyalah aplikasi demo, dan Anda adalah developer-nya, semoga Anda dapat mempercayai diri sendiri untuk melanjutkan. Untuk lebih memahami langkah ini, tempatkan diri Anda di posisi pengguna: Anda diminta untuk mengizinkan kode orang lain mengakses data Anda. Jika Anda ingin memublikasikan aplikasi seperti ini, Anda akan melalui proses verifikasi sehingga pengguna tidak akan melihat layar ini.

Setelah mengklik link "masuk ke aplikasi 'tidak aman", Anda akan mendapatkan dialog izin OAuth2 yang terlihat seperti di bawah ini—kami selalu menyempurnakan antarmuka pengguna kami, jadi jangan khawatir jika tidak sama persis:

e3e6ef5503b2af1b.png

Dialog alur OAuth2 mencerminkan izin yang diminta developer (melalui variabel SCOPES). Dalam hal ini, ini adalah kemampuan untuk melihat dan mendownload dari Google Drive pengguna. Dalam kode aplikasi, cakupan izin ini muncul sebagai URI, namun URI tersebut diterjemahkan ke dalam bahasa yang ditentukan oleh lokal pengguna. Di sini, pengguna harus memberikan otorisasi eksplisit untuk izin yang diminta, jika tidak, pengecualian akan diterapkan sehingga skrip tidak diproses lebih lanjut.

Anda bahkan mungkin akan mendapatkan satu dialog lagi yang meminta konfirmasi:

b91997983fdc1889.png

CATATAN: Beberapa pengguna menggunakan sejumlah browser web yang login ke akun-akun yang berbeda, sehingga permintaan otorisasi ini mungkin masuk ke tab/jendela browser yang salah, dan Anda mungkin harus memotong-dan-menempel link untuk permintaan ini ke browser yang login dengan akun yang benar.

Dari Cloud Shell

Dari Cloud Shell, tidak ada jendela browser yang muncul, sehingga Anda berhenti bekerja. Ketahui bahwa pesan diagnostik di bagian bawah dimaksudkan untuk Anda... pesan ini:

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

  --noauth_local_webserver

Anda harus menekan ^C (Ctrl-C atau menekan tombol lainnya untuk menghentikan eksekusi skrip), dan menjalankannya dari shell dengan flag ekstra. Saat dijalankan dengan cara ini, Anda akan mendapatkan output berikut:

$ 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:

(Mengabaikan peringatan karena kami tahu bahwa storage.json belum dibuat dan) Dengan mengikuti petunjuk di tab browser lain dengan URL tersebut, Anda akan mendapatkan pengalaman yang hampir sama dengan yang dijelaskan di atas untuk lingkungan pengembangan lokal (lihat screenshot di atas). Di bagian akhir ada satu layar terakhir dengan kode verifikasi yang harus dimasukkan di Cloud Shell:

f6da2c335fb7c6a.png

Salin dan tempel kode ini ke jendela terminal.

Ringkasan

Selain "Authentication successful", jangan mengharapkan output tambahan. Ingatlah bahwa ini hanyalah penyiapan... Anda belum melakukan apa pun. Apa yang telah Anda lakukan adalah berhasil memulai perjalanan dengan hasil yang kemungkinan besar akan benar dalam sekali percobaan. (Bagian terbaiknya adalah Anda hanya diminta untuk otorisasi sekali; lewati semua eksekusi lanjutannya karena izin Anda telah disimpan dalam cache.) Sekarang mari kita membuat kode tersebut melakukan beberapa pekerjaan nyata yang menghasilkan output aktual.

Pemecahan masalah

Jika Anda mendapatkan error, bukan output, mungkin karena satu atau beberapa penyebab berikut ini:

Pada langkah sebelumnya, sebaiknya buat kode sebagai analyze_gsimg.py dan edit dari sana. Anda juga dapat memotong dan menempel semuanya secara langsung ke dalam iPython atau shell Python standar. Namun, itu akan lebih merepotkan karena kita akan terus membuild aplikasi ini sepotong demi sepotong.

Asumsikan aplikasi Anda telah diotorisasi dan endpoint layanan API telah dibuat. Dalam kode Anda, ini diwakili oleh variabel DRIVE. Sekarang, mari cari file gambar di Google Drive Anda dan

setel file gambar itu ke variabel yang disebut NAME. Masukkan variabel itu plus fungsi drive_get_img() berikut persis di bawah kode dari Langkah 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

Koleksi files() Drive memiliki metode list() yang menjalankan kueri (parameter q) untuk file yang ditentukan. Parameter fields digunakan untuk menentukan nilai yang ditampilkan yang Anda minati — mengapa harus bersusah payah mendapatkan kembali semuanya dan menyebabkan kelambatan jika Anda tidak peduli dengan nilai lainnya? Jika Anda baru mengenal penyamar kolom untuk memfilter nilai yang ditampilkan API, lihat postingan blog & video ini. Jika tidak, jalankan kueri dan ambil atribut files yang ditampilkan, men-default-kan ke array daftar kosong jika tidak ada yang cocok.

Jika tidak ada hasil, bagian lain dari fungsi akan dilewati dan None akan ditampilkan (secara implisit). Atau, ambil respons pertama yang cocok (rsp[0]), tampilkan nama file, MIMEtype-nya, stempel waktu modifikasi terakhir, dan terakhir, payload binernya, yang diambil oleh fungsi get_media() (melalui ID filenya), juga di koleksi files(). (Nama metode mungkin sedikit berbeda dengan library klien bahasa lain.)

Bagian terakhir adalah bagian "utama" yang mendorong keseluruhan aplikasi:

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)

Dengan mengasumsikan gambar bernama section-work-card-img_2x.jpg di Drive dan disetel ke FILE, setelah eksekusi skrip berhasil, Anda akan melihat output yang mengonfirmasi bahwa file dari Drive dapat dibaca (tetapi tidak disimpan di komputer Anda):

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

Pemecahan masalah

Jika Anda tidak mendapatkan output yang sukses seperti di atas, mungkin karena satu atau beberapa penyebab berikut ini:

Ringkasan

Di bagian ini, Anda telah mempelajari cara (dalam 2 panggilan API terpisah) untuk terhubung ke kueri Drive API yang membuat kueri untuk file tertentu, lalu mendownloadnya. Kasus penggunaan bisnis: mengarsipkan data Drive Anda dan mungkin menganalisisnya, misalnya dengan alat GCP. Kode untuk aplikasi Anda pada tahap ini seharusnya sesuai dengan yang ada dalam repo di step1-drive/analyze_gsimg.py.

Baca selengkapnya tentang mendownload file di Google Drive di sini atau lihat postingan blog & video ini. Bagian codelab ini hampir identik dengan seluruh pengantar ke codelab G Suite API —alih-alih mendownload file, bagian ini menampilkan 100 file/folder pertama di Google Drive pengguna dan menggunakan cakupan yang lebih ketat.

Langkah berikutnya adalah menambahkan dukungan untuk Google Cloud Storage. Untuk itu, kita perlu mengimpor paket Python lain, io. Pastikan bagian atas impor kini terlihat seperti ini:

from __future__ import print_function
import io

Selain nama file Drive, kami memerlukan beberapa informasi tentang tempat untuk menyimpan file ini di Cloud Storage, khususnya nama "bucket" yang akan menjadi tempatnya dan awalan "folder induk" apa pun... selengkapnya tentang hal ini berikutnya:

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

Sekilas tentang bucket... Cloud Storage menyediakan penyimpanan blob yang amorf/tanpa bentuk. Saat mengupload file ke dalamnya, Cloud Storage tidak memahami konsep tentang jenis file, ekstensi, dll., seperti yang dilakukan Google Drive. Bagi Cloud Storage, file tersebut hanya "blob". Selain itu, tidak ada konsep tentang folder atau subdirektori di Cloud Storage.

Ya, Anda dapat memiliki garis miring (/) dalam nama file untuk mewakili abstraksi beberapa sub-folder, tetapi pada akhirnya, semua blob Anda akan dimasukkan ke dalam bucket, dan "/" hanyalah karakter dalam nama file. Lihat halaman konvensi penamaan bucket dan objek untuk info selengkapnya.

Langkah 1 di atas meminta cakupan hanya baca di Drive. Di tahap tersebut, itu saja yang Anda butuhkan. Sekarang, izin upload (baca-tulis) ke Cloud Storage diperlukan. Ubah SCOPES dari variabel string tunggal menjadi array (Python tuple [atau list]) cakupan izin sehingga terlihat seperti ini:

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

Sekarang buat endpoint layanan ke Cloud Storage tepat di bawah endpoint untuk Drive. Perhatikan bahwa kita sedikit mengubah panggilan untuk menggunakan kembali objek klien HTTP yang sama karena tidak perlu membuat yang baru jika dapat menjadi resource bersama.

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

Sekarang tambahkan fungsi ini (setelah drive_get_img()) yang akan diupload ke Cloud Storage:

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

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

Panggilan objects.().insert() memerlukan nama bucket, metadata file, dan blob biner itu sendiri. Untuk memfilter nilai yang ditampilkan, variabel fields hanya meminta nama bucket dan objek yang ditampilkan dari API. Untuk mempelajari lebih lanjut tentang penyamar kolom di permintaan baca API, lihat postingan & video ini.

Sekarang integrasikan penggunaan gcs_blob_upload() ke dalam aplikasi utama:

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

Variabel gcsname menggabungkan setiap nama "subdirektori induk" yang ditambahi dengan nama file itu sendiri, dan jika diawali dengan nama bucket, memberikan kesan Anda sedang mengarsipkan file di "/bucket/parent.../filename". Selipkan potongan ini tepat setelah fungsi print() pertama di atas klausa else sehingga seluruh aplikasi "utama" terlihat seperti ini:

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)

Misalnya, kita menentukan bucket bernama "vision-demo" dengan "analyzed_imgs" sebagai "subdirektori induk". Setelah Anda menetapkan variabel tersebut dan menjalankan skrip lagi, section-work-card-img_2x.jpg akan didownload dari Drive lalu diupload ke Cloud Storage, bukan? Tidak begitu.

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

Perhatikan baik-baik, saat download dari Drive berhasil, upload ke Cloud Storage gagal. Mengapa demikian?

Alasannya adalah saat kita mengotorisasi aplikasi ini sebelumnya di Langkah 1, kita cuma mengotorisasikan akses hanya baca ke Google Drive. Ketika kita menambahkan cakupan baca-tulis untuk Cloud Storage, kita tidak pernah meminta pengguna untuk mengotorisasikan akses tersebut. Untuk membuatnya berfungsi, kita perlu menyingkirkan file storage.json yang tidak memiliki cakupan ini, lalu menjalankannya kembali.

Setelah Anda mengotorisasi ulang (konfirmasikan hal ini dengan melihat ke dalam storage.json dan melihat kedua cakupan di sana), output Anda akan seperti yang diharapkan:

$ 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'

Ringkasan

Ini pengetahuan yang penting, yang menunjukkan kepada Anda, dalam beberapa baris kode yang relatif sedikit, cara mentransfer file antara kedua sistem penyimpanan berbasis Cloud. Kasus penggunaan bisnis di sini adalah untuk mencadangkan resource yang mungkin terbatas ke penyimpanan "yang lebih dingin" dan lebih murah seperti yang disebutkan sebelumnya. Cloud Storage menawarkan berbagai kelas penyimpanan bergantung pada apakah Anda mengakses data secara rutin, bulanan, tiga bulanan, atau tahunan.

Tentu saja, developer bertanya kepada kami dari waktu ke waktu mengapa ada Google Drive dan ada Cloud Storage... Bukankah keduanya sama-sama menyimpan file di cloud? Itulah sebabnya kami membuat video ini. Kode Anda di tahap ini seharusnya cocok dengan yang ada di repo distep2-gcs/analyze_gsimg.py.

Meskipun sekarang kita tahu bahwa Anda dapat memindahkan data antara GCP dan G Suite, kita masih belum melakukan analisis apa pun. Jadi, ini saatnya mengirimkan gambar ke Cloud Vision untuk anotasi label alias deteksi objek. Untuk melakukannya, kita perlu melakukan encoding Base64 terhadap data, yang berarti modul Python lainnya, base64. Pastikan bagian impor teratas Anda terlihat seperti ini:

from __future__ import print_function
import base64
import io

Secara default, Vision API menampilkan semua label yang ditemukan. Untuk menjaga konsistensi, mari kita minta hanya 5 teratas (dapat disesuaikan oleh pengguna). Kita akan menggunakan variabel konstan TOP untuk ini; tambahkan di bawah semua konstanta lainnya:

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

Seperti langkah sebelumnya, kita memerlukan cakupan izin lain, kali ini untuk Vision API. Perbarui SCOPES dengan string-nya:

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

Sekarang buat endpoint layanan ke Cloud Vision agar sesuai dengan yang lainnya seperti ini:

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

Sekarang tambahkan fungsi ini yang mengirimkan payload gambar ke 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'])

Panggilan images().annotate() memerlukan data plus fitur API yang diinginkan. Batas label 5 teratas merupakan bagian dari payload juga (namun sepenuhnya opsional). Jika panggilan berhasil, payload akan menampilkan 5 label objek teratas serta skor keyakinan objek di dalam gambar. (Jika tidak ada respons yang muncul, tetapkan kamus Python kosong sehingga pernyataan if berikut tidak gagal.) Fungsi ini hanya mengumpulkan data tersebut ke dalam string CSV untuk penggunaan akhir dalam laporan.

Ke-5 baris yang memanggil vision_label_img() harus ditempatkan tepat setelah upload sukses ke Cloud Storage:

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

Dengan tambahan tersebut, seluruh driver utama akan terlihat seperti ini:

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)

Menghapus storage.json untuk menyegarkan cakupan dan menjalankan kembali aplikasi yang diupdate akan menghasilkan output yang mirip dengan berikut ini, dengan memperhatikan penambahan analisis Cloud Vision:

$ python3 analyze_gsimg.py

    . . .

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

Ringkasan

Tidak semua orang memiliki keahlian machine learning untuk membuat dan melatih model ML mereka sendiri guna menganalisis data mereka. Tim Google Cloud telah menyediakan beberapa model terlatih Google untuk penggunaan umum dan menempatkannya di belakang API, yang membantu mendemokratisasikan AI & ML untuk semua orang.

Jika Anda seorang developer dan dapat memanggil API, Anda dapat menggunakan machine learning. Cloud Vision adalah salah satu layanan API yang dapat Anda gunakan untuk menganalisis data. Pelajari lainnya di sini. Kode Anda sekarang seharusnya cocok dengan yang ada di repo di step3-vision/analyze_gsimg.py.

Pada tahap ini, Anda dapat mengarsipkan data perusahaan dan menganalisisnya, tetapi yang kurang adalah ringkasan pekerjaan ini. Mari kita susun semua hasil dalam satu laporan yang dapat Anda berikan kepada atasan Anda. Apa yang lebih menarik bagi pengelolaan selain spreadsheet?

Tidak ada impor tambahan yang diperlukan untuk Google Spreadsheet API, dan satu-satunya informasi baru yang diperlukan adalah ID file spreadsheet yang sudah ada yang telah diformat dan menunggu baris data baru, seperti konstanta SHEET. Sebaiknya buat spreadsheet baru yang terlihat mirip dengan berikut ini:

ca435d8aafd72ff4.png

URL untuk spreadsheet tersebut akan terlihat seperti berikut: https://docs.google.com/spreadsheets/d/FILE_ID/edit. Ambil FILE_ID dan tetapkan sebagai string pada SHEET.

Kami juga menyelipkan fungsi kecil bernama k_ize() yang mengubah byte menjadi kilobyte, yang mendefinisikannya sebagai Python lambda karena merupakan 1-baris sederhana. Kedua fungsi ini diintegrasikan dengan konstanta lainnya sehingga terlihat seperti ini:

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

Seperti langkah sebelumnya, kita memerlukan cakupan izin lain, kali ini izin baca-tulis untuk Sheets API. SCOPES kini memiliki semua yang dibutuhkan:

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

Sekarang buat endpoint layanan ke Google Spreadsheet di dekat yang lain, sehingga terlihat seperti ini:

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

Fungsi sheet_append_row() sangat mudah: ambil baris data dan ID Spreadsheet, lalu tambahkan baris tersebut ke Spreadsheet itu:

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

Panggilan spreadsheets().values().append() memerlukan ID file Spreadsheet, rentang sel, cara data dimasukkan, dan data itu sendiri. ID file cukup jelas, rentang sel diberikan dalam notasi A1. Rentang "Sheet1" berarti seluruh Spreadsheet—ini memberi sinyal kepada API untuk menambahkan baris setelah semua data di Spreadsheet. Ada beberapa pilihan tentang cara data harus ditambahkan ke Spreadsheet, "RAW" (masukkan data string secara verbatim) atau "USER_ENTERED" (tuliskan data seolah-olah pengguna memasukkannya di keyboard dengan aplikasi Google Spreadsheet, mempertahankan fitur pemformatan sel apa pun).

Jika panggilan berhasil, nilai yang ditampilkan tidak benar-benar memiliki sesuatu yang sangat berguna, jadi kami memilih untuk mendapatkan jumlah sel yang diperbarui oleh permintaan API. Berikut adalah kode yang memanggil fungsi tersebut:

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

Spreadsheet Google memiliki kolom yang menampilkan data seperti "subdirektori" induk, lokasi file yang diarsipkan di Cloud Storage (bucket + nama file), MIMEtype file, ukuran file (awalnya dalam byte, namun dikonversi ke kilobyte dengank_ize()), dan string label Cloud Vision. Perhatikan juga bahwa lokasi yang diarsipkan adalah hyperlink sehingga manajer Anda dapat mengklik untuk memastikan bahwa lokasi tersebut telah dicadangkan dengan aman.

Menambahkan blok kode di atas tepat setelah menampilkan hasil dari Cloud Vision, bagian utama yang mendorong aplikasi sekarang selesai, walaupun secara struktural sedikit rumit:

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)

Menghapus storage.json satu kali terakhir dan menjalankan kembali aplikasi yang telah diupdate akan menghasilkan output yang serupa dengan berikut ini, yang menunjukkan penambahan analisis Cloud Vision:

$ python3 analyze_gsimg.py

    . . .

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

Baris output ekstra, meskipun berguna, lebih baik divisualisasikan dengan melihat sekilas di Spreadsheet Google yang telah diupdate, dengan baris terakhir (baris 7 dalam contoh di bawah) ditambahkan ke kumpulan data yang ada yang ditambahkan sebelumnya:

a7f821fa497e6bbe.png

Ringkasan

Pada 3 langkah pertama dalam tutorial ini, Anda terhubung dengan G Suite dan GCP API untuk memindahkan data dan menganalisisnya, yang mewakili 80% dari semua tugas. Namun, pada akhirnya, tidak satu pun dari hal ini berarti apa pun jika Anda tidak dapat menunjukkan kepada manajemen tentang semua yang telah Anda capai. Demi memvisualisasikan hasil secara lebih baik, tunjukkan dengan merangkum semua hasil dalam sebuah laporan yang disusun.

Untuk lebih meningkatkan kegunaan analisis, selain menulis hasil ke dalam spreadsheet, satu penyempurnaan yang memungkinkan adalah mengindeks ke-5 label teratas untuk setiap gambar sehingga database internal bisa dibuat, yang memungkinkan karyawan yang berwenang untuk membuat kueri gambar melalui penelusuran, namun kami menyerahkannya kepada para pembaca sebagai latihan.

Untuk saat ini, hasil kita tersedia di Spreadsheet dan dapat diakses oleh manajemen. Kode untuk aplikasi Anda pada tahap ini seharusnya sesuai dengan yang ada dalam repo di step4-sheets/analyze_gsimg.py. Langkah terakhir adalah membersihkan kode dan mengubahnya menjadi skrip yang dapat digunakan.

(opsional) Bagus, aplikasi ini berfungsi dengan baik. Bisakah kita menyempurnakannya? Ya, khususnya aplikasi utama yang tampak berantakan. Mari kita letakkan ke dalam fungsinya sendiri dan mendorongnya, sehingga memungkinkan input pengguna, bukan konstanta tetap. Kita akan melakukannya dengan modul argparse. Selain itu, mari kita luncurkan tab browser web untuk menampilkan Spreadsheet begitu kita selesai menuliskan baris data ke spreadsheet tersebut. Hal ini dapat dilakukan dengan modul webbrowser. Rangkai impor ini dengan impor lainnya sehingga impor teratas terlihat seperti ini:

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

Agar dapat menggunakan kode ini di aplikasi lain, kita memerlukan kemampuan untuk menekan output, jadi mari tambahkan flag DEBUG untuk mewujudkannya, dengan menambahkan baris ini ke akhir bagian konstanta di dekat bagian atas:

DEBUG = False

Sekarang, tentang bagian utama. Seiring kita sedang membuild contoh ini, Anda akan mulai merasa "tidak nyaman" karena kode kita menambahkan banyak tingkatan, dengan masing-masing tingkatan menambahkan layanan. Jika Anda merasa seperti itu, Anda tidak sendiri, karena hal ini menambah kerumitan kode seperti yang dijelaskan dalam postingan Blog Pengujian Google ini.

Setelah praktik terbaik ini, mari kita atur ulang bagian utama aplikasi menjadi fungsi dan return pada setiap "titik jeda", bukan menumpuknya (menampilkan None jika ada langkah yang gagal dan True jika semuanya berhasil):

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

Ini menjadi lebih rapi dan bersih, menanggalkan rantai if-else yang berulang serta mengurangi kerumitan kode sebagaimana dijelaskan di atass. Bagian terakhir dari teka-teki ini adalah membuat driver utama yang "nyata", yang memungkinkan untuk penyesuaian pengguna, dan meminimalkan output (kecuali jika diinginkan):

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)

Jika semua langkah berhasil, skrip meluncurkan browser web ke spreadsheet yang ditentukan di mana baris data baru ditambahkan.

Ringkasan

Tidak perlu menghapus storage.json karena tidak ada perubahan cakupan yang terjadi. Menjalankan ulang aplikasi yang telah diupdate menampilkan jendela browser baru yang terbuka ke Spreadsheet yang telah dimodifikasi, baris output yang lebih sedikit, dan memunculkan opsi -h yang menampilkan opsi kepada pengguna, termasuk -v untuk memulihkan baris output yang kini sebelumnya terlihat dan kini ditekan:

$ 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

Opsi lain memungkinkan pengguna bisa memilih nama file Drive yang berbeda, nama "subdirektori" Cloud Storage dan nama bucket, Hasil "N" teratas dari Cloud Vision, dan ID file Spreadsheet. Dengan update terakhir ini, versi akhir dari kode Anda sekarang seharusnya cocok dengan apa yang ada di repo di final/analyze_gsimg.py serta di sini, secara keseluruhan:

## Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

'''
analyze_gsimg.py - analyze G Suite 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)

Kami akan terus berupaya membuat konten tutorial ini tetap terbaru, tetapi akan ada saatnya repo memiliki versi kode terbaru.

Tentu saja ada banyak pembelajaran dalam codelab ini, dan Anda berhasil mencapainya, bertahan dalam salah satu codelab yang panjang. Hasilnya, Anda menangani kemungkinan skenario perusahaan dengan sekitar ~130 baris Python, memanfaatkan semua Google Cloud (GCP + G Suite), dan memindahkan data di antara GCP dan G Suite untuk membuat solusi yang berfungsi. Silakan pelajari repo open source untuk semua versi aplikasi ini (info lebih lanjut di bawah).

Pembersihan

  1. Penggunaan GCP API tidak gratis, sementara G Suite API tercakup oleh biaya langganan G Suite bulanan atau biaya bulanan nol Anda sebagai pengguna konsumen Gmail, sehingga tidak ada API pembersihan/penonaktifan yang diperlukan untuk pengguna G Suite. Untuk GCP, Anda dapat membuka dasbor Cloud Console dan memeriksa "kartu" Penagihan untuk estimasi tagihan.
  2. Untuk Cloud Vision, Anda memiliki jumlah panggilan API gratis yang tetap per bulan. Jadi, selama Anda tetap berada dalam batasan jumlah panggilan ini, tidak perlu mematikan apa pun atau menonaktifkan/menghapus project Anda. Informasi lebih lanjut tentang penagihan Vision API dan kuota gratis dapat ditemukan di halaman harganya.
  3. Beberapa pengguna Cloud Storage menerima jumlah penyimpanan gratis per bulan. Jika gambar yang Anda arsipkan menggunakan codelab ini tidak membuat Anda melebihi kuota tersebut, Anda tidak akan dikenakan biaya apa pun. Informasi lebih lanjut tentang penagihan GCS dan kuota gratis dapat ditemukan di halaman harganya. Anda dapat melihat dan menghapus blob dengan mudah dari browser Cloud Storage.
  4. Penggunaan Google Drive Anda juga mungkin memiliki kuota penyimpanan, dan jika Anda melampauinya (atau mendekatinya), Anda dapat mempertimbangkan untuk menggunakan alat yang Anda buat dalam codelab ini untuk mengarsipkan gambar tersebut ke Cloud Storage demi memberi Anda lebih banyak ruang di Drive. Informasi selengkapnya tentang penyimpanan Google Drive dapat ditemukan di halaman harga yang sesuai untuk pengguna G Suite Basic atau Gmail/konsumen.

Meskipun sebagian besar paket G Suite Business dan Enterprise memiliki penyimpanan tidak terbatas, hal ini dapat menyebabkan folder Drive Anda menjadi berantakan dan/atau berlebihan, dan aplikasi yang Anda buat dalam tutorial ini menjadi cara yang bagus untuk mengarsipkan file yang tidak relevan dan membersihkan Google Drive Anda.

Versi alternatif

Meskipun final/analyze_gsimg.py adalah versi resmi "terakhir" yang sedang Anda kerjakan dalam tutorial ini, ini bukanlah akhir dari cerita. Salah satu masalah dengan versi akhir dari aplikasi ini adalah aplikasi ini menggunakan library autentikasi lama yang sudah tidak digunakan lagi. Kami memilih jalur ini karena, pada saat penulisan tutorial ini, library autentikasi yang lebih baru tidak mendukung beberapa elemen utama: pengelolaan penyimpanan token OAuth dan threadsafety.

Library autentikasi terbaru (yang lebih baru)

Namun, pada titik tertentu, library autentikasi lama tidak akan didukung lagi, jadi sebaiknya Anda meninjau versi yang menggunakan library autentikasi yang lebih baru (terbaru) di folder alt repo meskipun jika library tersebut tidak threadsafe (tetapi Anda dapat membuat solusi sendiri). Cari file dengan *newauth* dalam nama mereka.

Library klien produk GCP

Google Cloud merekomendasikan semua developer menggunakan library klien produk saat menggunakan GCP API. Sayangnya, saat ini API non-GCP tidak memiliki library tersebut. Penggunaan library platform tingkat yang lebih rendah memungkinkan penggunaan API yang konsisten dan lebih mudah dibaca. Serupa dengan rekomendasi di atas, versi alternatif yang menggunakan library klien produk GCP tersedia di folder alt repo untuk Anda tinjau. Cari file dengan *-gcp* dalam nama mereka.

Otorisasi akun layanan

Saat bekerja hanya di cloud, secara umum tidak ada data milik pengguna (manusia) atau milik manusia, karena itulah akun layanan dan otorisasi akun layanan terutama digunakan dengan GCP. Namun, dokumen G Suite umumnya dimiliki oleh pengguna (manusia), sehingga tutorial ini menggunakan otorisasi akun pengguna. Itu tidak berarti bahwa mustahil untuk menggunakan G Suite API dengan akun layanan. Selama memiliki tingkat akses yang sesuai, akun layanan tersebut dapat digunakan dalam aplikasi. Sama seperti di atas, versi alternatif yang menggunakan otorisasi akun layanan tersedia di folder alt repo untuk Anda tinjau. Cari file dengan *-svc* dalam nama mereka.

Katalog versi alternatif

Di bawah ini, Anda akan menemukan semua versi alternatif dari final/analyze_gsimg.py, yang masing-masing memiliki satu atau beberapa properti di atas. Di setiap nama file versi, cari...

  • "oldauth" untuk versi yang menggunakan library autentikasi lama (selain final/analyze_gsimg.py)
  • "newauth" untuk versi yang menggunakan library autentikasi yang lebih baru/terbaru
  • "gcp" untuk versi yang menggunakan library klien produk GCP, yaitu google-cloud-storage, dll.
  • "svc" untuk versi yang menggunakan autentikasi akun layanan ("svc acct"), bukan akun pengguna

Berikut adalah semua versinya:

Nama file

Deskripsi

final/analyze_gsimg.py

Contoh utama; menggunakan library autentikasi lama

alt/analyze_gsimg-newauth.py

Sama seperti final/analyze_gsimg.py tetapi menggunakan library autentikasi yang lebih baru

alt/analyze_gsimg-oldauth-gcp.py

Sama seperti final/analyze_gsimg.py tetapi menggunakan library klien produk GCP

alt/analyze_gsimg-newauth-gcp.py

Sama seperti alt/analyze_gsimg-newauth.py tetapi menggunakan library klien produk GCP

alt/analyze_gsimg-oldauth-svc.py

Sama seperti final/analyze_gsimg.py tetapi menggunakan akun layanan, bukan akun pengguna

alt/analyze_gsimg-newauth-svc.py

Sama seperti alt/analyze_gsimg-newauth.py tetapi menggunakan autentikasi akun layanan, bukan akun pengguna

alt/analyze_gsimg-oldauth-svc-gcp.py

Sama seperti alt/analyze_gsimg-oldauth-svc.py tetapi menggunakan library klien produk GCP dan sama seperti alt/analyze_gsimg-oldauth-gcp.py tetapi menggunakan autentikasi akun layanan, bukan akun pengguna

alt/analyze_gsimg-newauth-svc-gcp.py

Sama seperti alt/analyze_gsimg-oldauth-svc-gcp.py tetapi menggunakan library autentikasi yang lebih baru

Dipasangkan dengan final/analyze_gsimg.py yang asli, Anda memiliki semua kemungkinan kombinasi solusi akhir, terlepas dari lingkungan pengembangan Google API Anda, dan dapat memilih solusi akhir yang paling sesuai dengan kebutuhan Anda. Lihat juga alt/README.md untuk penjelasan serupa.

Studi Tambahan

Di bawah ini adalah beberapa ide tentang bagaimana Anda dapat melakukan latihan ini satu atau dua langkah lebih jauh. Masalah yang bisa diatasi dengan solusi saat ini dapat diperluas, sehingga memungkinkan Anda untuk melakukan penyempurnaan ini:

  1. (beberapa gambar di folder) Alih-alih memproses satu gambar. Misalnya, Anda memiliki beberapa gambar di folder Google Drive.
  2. (beberapa gambar dalam beberapa file ZIP) Alih-alih satu folder dengan beberapa gambar, bagaimana dengan beberapa arsip ZIP yang berisi beberapa file gambar? Jika menggunakan Python, pertimbangkan modul zipfile.
  3. (menganalisis label Vision) Mengelompokkan gambar-gambar yang mirip menjadi satu, mungkin mulai dengan mencari label yang paling umum, kemudian paling umum kedua, dan seterusnya.
  4. (buat chart) Tindak lanjut #3, buat chart dengan Sheets API berdasarkan analisis dan kategorisasi Vision API
  5. (kategorikan dokumen) Alih-alih menganalisis gambar dengan Cloud Vision API. Misalnya, Anda memiliki beberapa file PDF untuk dikategorikan dengan Cloud Natural Language API. Menggunakan solusi di atas, PDF tersebut dapat berada di folder Drive atau arsip ZIP di Drive.
  6. (buat presentasi) Gunakan Slide API untuk membuat deretan slide dari konten laporan Google Spreadsheet. Untuk mendapatkan inspirasi, lihat postingan blog & video ini tentang cara membuat slide dari data spreadsheet.
  7. (ekspor sebagai PDF) Ekspor spreadsheet dan/atau deretan slide sebagai PDF, tetapi ini bukan fitur dari Spreadsheet atau Slide API. Petunjuk: Google Drive API. Kredit ekstra: menggabungkan PDF Spreadsheet dan Slide menjadi satu PDF master dengan alat seperti Ghostscript (Linux, Windows) atau Combine PDF Pages.action (Mac OS X).

Pelajari Lebih Lanjut

Codelabs

Umum

G Suite

Google Cloud Platform (GCP)

Lisensi

Karya ini dilisensikan berdasarkan Lisensi Umum Creative Commons Attribution 2.0.