1. Przegląd
W tym samouczku przedstawiamy możliwy przepływ pracy w przedsiębiorstwie: archiwizowanie, analizowanie i generowanie raportów dotyczących obrazów. Wyobraź sobie, że Twoja organizacja ma serię obrazów zajmujących miejsce w zasobie o ograniczonej pojemności. Chcesz zarchiwizować te dane, przeanalizować obrazy, a co najważniejsze, wygenerować raport podsumowujący zarchiwizowane lokalizacje oraz wyniki analizy, zebrane i gotowe do wykorzystania przez kierownictwo. Google Cloud udostępnia narzędzia, które to umożliwiają, korzystając z interfejsów API z dwóch linii produktów: Google Workspace (wcześniej G Suite lub Google Apps) i Google Cloud (wcześniej GCP).
W naszym scenariuszu użytkownik biznesowy będzie mieć obrazy na Dysku Google. Warto je przechowywać w „zimniejszych” i tańszych miejscach, takich jak klasy pamięci masowej dostępne w Google Cloud Storage. Google Cloud Vision umożliwia programistom łatwą integrację w aplikacjach funkcji związanych z wykrywaniem treści wizualnych, takich jak wykrywanie obiektów i punktów orientacyjnych, optyczne rozpoznawanie znaków (OCR) itp. Arkusz kalkulacyjny Arkusz Google to przydatne narzędzie do wizualizacji, które pozwala podsumować wszystkie te informacje dla szefa.
Po ukończeniu tego laboratorium, w którym zbudujesz rozwiązanie wykorzystujące wszystkie usługi Google Cloud, mamy nadzieję, że zainspiruje Cię to do stworzenia czegoś jeszcze bardziej przydatnego dla Twojej organizacji lub Twoich klientów.
Czego się nauczysz
- Jak korzystać z Cloud Shell
- Uwierzytelnianie żądań do interfejsu API
- Instalowanie biblioteki klienta interfejsów API Google dla Pythona
- Jak włączyć interfejsy API Google
- Jak pobierać pliki z Dysku Google
- Jak przesyłać obiekty/obiekty blob do Cloud Storage
- Jak analizować dane za pomocą Cloud Vision
- Zapisywanie wierszy w Arkuszach Google
Czego potrzebujesz
- konto Google (w przypadku kont Google Workspace może być wymagana zgoda administratora);
- Projekt Google Cloud z aktywnym kontem rozliczeniowym Google Cloud
- Znajomość poleceń terminala/powłoki systemu operacyjnego
- podstawowe umiejętności w zakresie Pythona (2 lub 3), ale możesz używać dowolnego obsługiwanego języka;
Znajomość wymienionych powyżej 4 usług Google Cloud może być przydatna, ale nie jest wymagana. Jeśli masz czas, możesz najpierw zapoznać się z nimi osobno, wykonując ćwiczenia z każdej z nich, a potem przejść do tego ćwiczenia:
- Wprowadzenie do Dysku Google (korzystanie z interfejsów Google Workspace API) (Python)
- Korzystanie z Cloud Vision w Pythonie (Python)
- Tworzenie niestandardowych narzędzi do raportowania za pomocą interfejsu Sheets API (JS/Node)
- Przesyłanie obiektów do Google Cloud Storage (bez konieczności pisania kodu)
Ankieta
Jak zamierzasz korzystać z tego samouczka?
Jak oceniasz swoje doświadczenie z Pythonem?
Jak oceniasz korzystanie z usług Google Cloud?
Jak oceniasz korzystanie z usług dla deweloperów Google Workspace?
Czy wolisz codelaby „biznesowe” od tych, które są wprowadzeniem do funkcji usługi?
2. Konfiguracja i wymagania
Samodzielne konfigurowanie środowiska
- Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub użyj istniejącego. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.



- Nazwa projektu to wyświetlana nazwa uczestników tego projektu. Jest to ciąg znaków, który nie jest używany przez interfejsy API Google. Możesz ją zaktualizować w dowolnym momencie.
- Identyfikator projektu musi być unikalny we wszystkich projektach Google Cloud i jest niezmienny (nie można go zmienić po ustawieniu). Konsola Cloud automatycznie generuje unikalny ciąg znaków. Zwykle nie musisz się nim przejmować. W większości ćwiczeń z programowania musisz odwoływać się do identyfikatora projektu (zwykle jest on oznaczony jako
PROJECT_ID). Jeśli wygenerowany identyfikator Ci się nie podoba, możesz wygenerować inny losowy identyfikator. Możesz też spróbować własnej nazwy i sprawdzić, czy jest dostępna. Po tym kroku nie można go zmienić i będzie obowiązywać przez cały czas trwania projektu. - Warto wiedzieć, że istnieje też trzecia wartość, czyli numer projektu, z której korzystają niektóre interfejsy API. Więcej informacji o tych 3 wartościach znajdziesz w dokumentacji.
- Następnie musisz włączyć płatności w konsoli Cloud, aby korzystać z zasobów i interfejsów API Google Cloud. Ukończenie tego laboratorium nie powinno wiązać się z dużymi kosztami, a nawet z żadnymi. Aby wyłączyć zasoby i uniknąć naliczania opłat po zakończeniu tego samouczka, możesz usunąć utworzone zasoby lub cały projekt. Nowi użytkownicy Google Cloud mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.
Uruchamianie Cloud Shell
Podsumowanie
Kod możesz tworzyć lokalnie na laptopie, ale dodatkowym celem tego modułu jest nauczenie Cię, jak korzystać z Google Cloud Shell, czyli środowiska wiersza poleceń działającego w chmurze w nowoczesnej przeglądarce internetowej.
Aktywowanie Cloud Shell
- W konsoli Cloud kliknij Aktywuj Cloud Shell
.

Jeśli uruchamiasz Cloud Shell po raz pierwszy, zobaczysz ekran pośredni (część strony widoczna po przewinięciu) z opisem tego środowiska. W takim przypadku kliknij Dalej, a ten ekran nie będzie się już wyświetlać. Ten wyświetlany jednorazowo ekran wygląda tak:

Uzyskanie dostępu do środowiska Cloud Shell i połączenie się z nim powinno zająć tylko kilka chwil.

Ta maszyna wirtualna zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera również stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i usprawnia proces uwierzytelniania. Większość zadań w tym module, a być może wszystkie, możesz wykonać w przeglądarce lub na Chromebooku.
Po połączeniu z Cloud Shell zobaczysz, że uwierzytelnianie zostało już przeprowadzone, a projekt jest już ustawiony na Twój identyfikator projektu.
- Aby potwierdzić, że uwierzytelnianie zostało przeprowadzone, uruchom w Cloud Shell to polecenie:
gcloud auth list
Wynik polecenia
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- Aby potwierdzić, że polecenie gcloud zna Twój projekt, uruchom w Cloud Shell to polecenie:
gcloud config list project
Wynik polecenia
[core] project = <PROJECT_ID>
Jeśli nie, możesz go ustawić za pomocą tego polecenia:
gcloud config set project <PROJECT_ID>
Wynik polecenia
Updated property [core/project].
3. Potwierdź środowisko Pythona
W tym laboratorium musisz użyć języka Python (chociaż biblioteki klienta interfejsów API Google obsługują wiele języków, więc możesz utworzyć odpowiednik w ulubionym narzędziu programistycznym i używać Pythona jako pseudokodu). W szczególności te warsztaty obsługują Pythona w wersjach 2 i 3, ale zalecamy jak najszybsze przejście na wersję 3.x.
Cloud Shell to wygodne narzędzie dostępne dla użytkowników bezpośrednio z konsoli Cloud. Nie wymaga lokalnego środowiska programistycznego, więc ten samouczek można w całości wykonać w chmurze za pomocą przeglądarki internetowej. W tym ćwiczeniu w Cloud Shell są już zainstalowane obie wersje Pythona.
W Cloud Shell jest też zainstalowany interpreter IPython, czyli interaktywny interpreter Pythona wyższego poziomu, który zalecamy, zwłaszcza jeśli należysz do społeczności zajmującej się nauką o danych lub uczeniem maszynowym. Jeśli tak jest, IPython jest domyślnym interpreterem notatników Jupyter oraz Colab, czyli notatników Jupyter hostowanych przez zespół ds. badań Google.
IPython preferuje interpreter Pythona 3, ale jeśli nie jest on dostępny, używa Pythona 2. Do IPythona można uzyskać dostęp z Cloud Shell, ale można go też zainstalować w lokalnym środowisku programistycznym. Wyjdź, naciskając ^D (Ctrl-d), i zaakceptuj ofertę wyjścia. Przykładowe dane wyjściowe po uruchomieniu ipython będą wyglądać tak:
$ 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]:
Jeśli nie chcesz używać IPythona, możesz użyć standardowego interaktywnego interpretera Pythona (w Cloud Shell lub w lokalnym środowisku programistycznym). W tym przypadku również możesz zakończyć działanie interpretera za pomocą kombinacji klawiszy ^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. >>>
W tym samouczku zakłada się też, że masz zainstalowane pip narzędzie do instalacji (menedżer pakietów Pythona i rozwiązywanie zależności). Jest on dołączony do wersji 2.7.9+ lub 3.4+. Jeśli masz starszą wersję Pythona, instrukcje instalacji znajdziesz w tym przewodniku. W zależności od uprawnień może być konieczne uzyskanie dostępu sudo lub dostępu superużytkownika, ale zwykle nie jest to wymagane. Możesz też użyć pip2 lub pip3, aby wykonać pip w przypadku konkretnych wersji Pythona.
W dalszej części tego samouczka założono, że używasz języka Python 3. Jeśli instrukcje dla języka Python 2 będą się znacznie różnić od instrukcji dla wersji 3.x, podamy je osobno.
[Opcjonalnie] Tworzenie i używanie środowisk wirtualnych
Ta sekcja jest opcjonalna i jest wymagana tylko w przypadku osób, które muszą używać środowiska wirtualnego w tym laboratorium programowania (zgodnie z ostrzeżeniem w pasku bocznym powyżej). Jeśli na komputerze masz tylko Pythona 3, możesz po prostu wydać to polecenie, aby utworzyć środowisko wirtualne o nazwie my_env (możesz wybrać inną nazwę):
virtualenv my_env
Jeśli jednak masz na komputerze zarówno Pythona 2, jak i 3, zalecamy zainstalowanie wirtualnego środowiska Python 3, co możesz zrobić za pomocą polecenia -p flag:
virtualenv -p python3 my_env
Wejdź do nowo utworzonego środowiska wirtualnego, „aktywując” je w ten sposób:
source my_env/bin/activate
Sprawdź, czy jesteś w środowisku, obserwując, czy przed promptem powłoki znajduje się teraz nazwa środowiska, np.
(my_env) $
Teraz możesz pip install wszystkie wymagane pakiety, wykonywać kod w tym środowisku itp. Kolejną zaletą jest to, że jeśli coś zepsujesz, na przykład uszkodzisz instalację Pythona, możesz usunąć całe środowisko bez wpływu na resztę systemu.
4. Instalowanie biblioteki klienta interfejsów API Google dla Pythona
W tym laboratorium programowania wymagane jest użycie biblioteki klienta interfejsów API Google dla języka Python, więc albo jest to prosty proces instalacji, albo nie musisz nic robić.
Wcześniej zalecaliśmy korzystanie z Cloud Shell ze względu na wygodę. Cały samouczek możesz przejść w przeglądarce internetowej w chmurze. Innym powodem, dla którego warto korzystać z Cloud Shell, jest to, że wiele popularnych narzędzi programistycznych i niezbędnych bibliotek jest już zainstalowanych.
*Instalowanie bibliotek klienta
(opcjonalnie) Możesz pominąć ten krok, jeśli używasz Cloud Shell lub środowiska lokalnego, w którym biblioteki klienta są już zainstalowane. Tę czynność musisz wykonać tylko wtedy, gdy tworzysz aplikację lokalnie i nie masz zainstalowanych tych narzędzi (lub nie masz pewności, czy są zainstalowane). Najłatwiej jest użyć pip (lub pip3) do instalacji (w razie potrzeby w tym do zaktualizowania samego pip):
pip install -U pip google-api-python-client oauth2client
Potwierdź instalację
To polecenie instaluje bibliotekę klienta oraz wszystkie pakiety, od których jest ona zależna. Niezależnie od tego, czy używasz Cloud Shell, czy własnego środowiska, sprawdź, czy biblioteka klienta jest zainstalowana. W tym celu zaimportuj niezbędne pakiety i upewnij się, że nie ma błędów importu (ani danych wyjściowych):
python3 -c "import googleapiclient, httplib2, oauth2client"
Jeśli zamiast tego użyjesz języka Python 2 (w Cloud Shell), zobaczysz ostrzeżenie, że jego obsługa została wycofana:
******************************************************************************* 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. *******************************************************************************
Gdy uda Ci się uruchomić polecenie importu „test” (bez błędów i danych wyjściowych), możesz zacząć korzystać z interfejsów API Google.
Podsumowanie
Jest to kurs na poziomie średnio zaawansowanym, więc zakładamy, że masz już doświadczenie w tworzeniu projektów i korzystaniu z nich w konsoli. Jeśli dopiero zaczynasz korzystać z interfejsów API Google, a w szczególności z interfejsów Google Workspace API, najpierw wypróbuj wprowadzenie do Codelabs interfejsów Google Workspace API. Jeśli wiesz, jak utworzyć (lub ponownie wykorzystać istniejące) dane logowania konta użytkownika (nie konta usługi), upuść plik client_secret.json w katalogu roboczym, pomiń następny moduł i przejdź do sekcji „Włączanie interfejsów API Google”.
5. *Autoryzowanie żądań interfejsu API (autoryzacja użytkownika)
Jeśli masz już dane logowania autoryzacji konta użytkownika i znasz ten proces, możesz pominąć tę sekcję. Różni się od autoryzacji konta usługi, która wykorzystuje inną technikę, więc czytaj dalej.
Wprowadzenie do autoryzacji (wraz z pewnymi informacjami o uwierzytelnianiu)
Aby wysyłać żądania do interfejsów API, aplikacja musi mieć odpowiednią autoryzację. Uwierzytelnianie to podobne słowo, które opisuje dane logowania. Uwierzytelniasz się, gdy logujesz się na konto Google za pomocą loginu i hasła. Po uwierzytelnieniu kolejnym krokiem jest sprawdzenie, czy kod jest autoryzowany do uzyskiwania dostępu do danych, takich jak pliki binarne w Cloud Storage czy osobiste pliki użytkownika na Dysku Google.
Interfejsy API Google obsługują kilka rodzajów autoryzacji, ale w przypadku użytkowników interfejsów API G Suite najczęściej stosowana jest autoryzacja użytkownika, ponieważ przykładowa aplikacja w tym laboratorium kodu uzyskuje dostęp do danych należących do użytkowników. Użytkownicy muszą zezwolić Twojej aplikacji na dostęp do ich danych. Oznacza to, że Twój kod musi uzyskać dane logowania OAuth2 do konta użytkownika.
Aby uzyskać dane logowania OAuth2 do autoryzacji użytkownika, wróć do menedżera interfejsów API i w menu po lewej stronie wybierz kartę „Dane logowania”:

Gdy to zrobisz, zobaczysz wszystkie swoje certyfikaty w 3 osobnych sekcjach:

Pierwszy to klucze interfejsu API, drugi to identyfikatory klientów OAuth 2.0,a ostatni to konta usługi OAuth2. My używamy tego środkowego.
Tworzenie danych logowania
Na stronie Dane logowania kliknij u góry przycisk + Utwórz dane logowania. Wyświetli się okno, w którym wybierzesz „Identyfikator klienta OAuth”:

Na następnym ekranie możesz wykonać 2 działania: skonfigurować „ekran zgody” autoryzacji aplikacji i wybrać typ aplikacji:

Jeśli nie masz skonfigurowanego ekranu zgody, w konsoli zobaczysz ostrzeżenie i musisz to zrobić. (Jeśli ekran zgody został już skonfigurowany, pomiń te kroki).
Ekran zgody OAuth
Kliknij „Skonfiguruj ekran zgody”, a następnie wybierz aplikację „Zewnętrzna” (lub „Wewnętrzna”, jeśli jesteś klientem G Suite):

Pamiętaj, że na potrzeby tego ćwiczenia nie ma znaczenia, którą opcję wybierzesz, ponieważ nie publikujesz przykładowego Codelabs. Większość osób wybierze opcję „Zewnętrzna”, aby przejść do bardziej złożonego ekranu, ale wystarczy wypełnić tylko pole „Nazwa aplikacji” u góry:

W tym momencie potrzebujesz tylko nazwy aplikacji, więc wybierz taką, która odzwierciedla Codelabs, który wykonujesz, a potem kliknij Zapisz.
Tworzenie identyfikatora klienta OAuth (uwierzytelnianie konta użytkownika)
Wróć na kartę Dane logowania, aby utworzyć identyfikator klienta OAuth2. Zobaczysz tu różne identyfikatory klienta OAuth, które możesz utworzyć:

Tworzymy narzędzie wiersza poleceń, czyli Inne. Wybierz tę opcję, a potem kliknij przycisk Utwórz. Wybierz nazwę identyfikatora klienta, która odzwierciedla tworzoną aplikację, lub po prostu zaakceptuj nazwę domyślną, która zwykle brzmi „Inny klient N”.
Zapisywanie danych logowania
- Pojawi się okno z nowymi danymi logowania. Aby je zamknąć, kliknij OK.

- Wróć na stronę Dane logowania, przewiń w dół do sekcji „Identyfikatory klientów OAuth 2.0” i znajdź ikonę pobierania
w prawym dolnym rogu nowo utworzonego identyfikatora klienta. Kliknij ją.
- Otworzy się okno dialogowe, w którym możesz zapisać plik o nazwie
client_secret-LONG-HASH-STRING.apps.googleusercontent.com.json, prawdopodobnie w folderze Pobrane. Zalecamy skrócenie nazwy do prostszej, np.client_secret.json(takiej jak w przykładowej aplikacji), a następnie zapisanie jej w katalogu lub folderze, w którym w tym laboratorium kodowania utworzysz przykładową aplikację.
Podsumowanie
Teraz możesz włączyć interfejsy API Google używane w tym ćwiczeniu z programowania. Jako nazwę aplikacji na ekranie zgody OAuth wybraliśmy „Vision API demo”, więc spodziewaj się, że pojawi się ona na niektórych z nadchodzących zrzutów ekranu.
6. Włączanie interfejsów API Google
W tym samouczku używane są 4 interfejsy API Google Cloud: 2 z Google Cloud (Cloud Storage i Cloud Vision) i 2 z Google Workspace (Dysk Google i Arkusze Google). Poniżej znajdziesz ogólne instrukcje włączania interfejsów API Google. Gdy dowiesz się, jak włączyć jeden interfejs API, włączenie pozostałych będzie podobne.
Niezależnie od tego, którego interfejsu Google API chcesz używać w swojej aplikacji, musi on być włączony. Interfejsy API można włączyć w wierszu poleceń lub w konsoli Cloud. Proces włączania interfejsów API jest identyczny, więc po włączeniu jednego interfejsu API możesz włączyć inne w podobny sposób.
Opcja 1. gcloud interfejs wiersza poleceń (Cloud Shell lub środowisko lokalne)
Włączanie interfejsów API w konsoli Cloud jest bardziej powszechne, ale niektórzy programiści wolą wykonywać wszystkie czynności w wierszu poleceń. Aby to zrobić, musisz wyszukać „nazwę usługi” interfejsu API. Wygląda na adres URL: SERVICE_NAME.googleapis.com. Znajdziesz je w tabeli obsługiwanych usług lub możesz wysłać do nich zapytanie programowe za pomocą interfejsu Google Discovery API.
Mając te informacje, możesz włączyć interfejs API lub usługę za pomocą Cloud Shell (lub lokalnego środowiska programistycznego z zainstalowanym narzędziem wiersza poleceń gcloud):
gcloud services enable SERVICE_NAME.googleapis.com
Przykład 1. Włącz Cloud Vision API.
gcloud services enable vision.googleapis.com
Przykład 2. Włączanie platformy obliczeniowej bezserwerowej Google App Engine
gcloud services enable appengine.googleapis.com
Przykład 3. Włączanie wielu interfejsów API za pomocą jednego żądania. Jeśli na przykład w tym module z kodem uczestnicy wdrażają aplikację korzystającą z interfejsu Cloud Translation API w usługach App Engine, Cloud Functions i Cloud Run, wiersz poleceń będzie wyglądać tak:
gcloud services enable appengine.googleapis.com cloudfunctions.googleapis.com artifactregistry.googleapis.com run.googleapis.com translate.googleapis.com
To polecenie włącza App Engine, Cloud Functions, Cloud Run i Cloud Translation API. Umożliwia też korzystanie z Cloud Artifact Registry, ponieważ to w nim system Cloud Build musi rejestrować obrazy kontenerów, aby można było je wdrożyć w Cloud Run.
Dostępnych jest też kilka poleceń, które umożliwiają wyszukiwanie interfejsów API do włączenia lub interfejsów API, które zostały już włączone w Twoim projekcie.
Przykład 4. Zapytanie o interfejsy API Google, które można włączyć w projekcie
gcloud services list --available --filter="name:googleapis.com"
Przykład 5. Zapytanie o interfejsy API Google włączone w projekcie
gcloud services list
Więcej informacji o powyższych poleceniach znajdziesz w dokumentacji dotyczącej włączania i wyłączania usług oraz wyświetlania listy usług.
Opcja 2. Cloud Console
Interfejsy API Google możesz też włączyć w Menedżerze interfejsów API. W Cloud Console otwórz Menedżera interfejsów API. Na tej stronie panelu zobaczysz informacje o przeciętnym ruchu w aplikacji, wykresy przedstawiające żądania aplikacji, błędy generowane przez aplikację i czasy odpowiedzi aplikacji:

Pod tymi wykresami znajduje się lista interfejsów API Google włączonych w Twoim projekcie:

Aby włączyć (lub wyłączyć) interfejsy API, kliknij u góry Włącz interfejsy API i usługi:

Możesz też otworzyć pasek nawigacyjny po lewej stronie i kliknąć Interfejsy API i usługi → Biblioteka:

W obu przypadkach otworzy się strona Biblioteka interfejsów API:

Wpisz nazwę interfejsu API, aby wyszukać pasujące wyniki:

Wybierz interfejs API, który chcesz włączyć, i kliknij przycisk Włącz:

Proces włączania wszystkich interfejsów API jest podobny niezależnie od tego, którego interfejsu Google API chcesz używać.
Koszt
Wiele interfejsów API Google można używać bez opłat, ale korzystanie z większości usług i interfejsów API Google Cloud wiąże się z kosztami. Podczas włączania interfejsów API Google Cloud możesz zostać poproszony(-a) o podanie aktywnego konta rozliczeniowego. Niektóre usługi Google Cloud mają jednak poziom „Zawsze bezpłatny”, który musisz przekroczyć, aby ponieść opłaty.
Nowi użytkownicy Google Cloud mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD do wykorzystania w ciągu pierwszych 90 dni. Codelaby zwykle nie generują dużych kosztów lub nie generują ich wcale, dlatego sugerujemy, aby nie korzystać z bezpłatnego okresu próbnego, dopóki nie będziesz gotowy(-a) na jego wypróbowanie. Jest to oferta jednorazowa. Limity na poziomie bezpłatnym nie wygasają i obowiązują niezależnie od tego, czy korzystasz z bezpłatnego okresu próbnego.
Przed włączeniem dowolnego interfejsu API użytkownicy powinni zapoznać się z informacjami o cenach (np. na stronie cennika Cloud Vision API ), zwracając szczególną uwagę na to, czy jest on dostępny w ramach bezpłatnego limitu, a jeśli tak, to jaki jest ten limit. Jeśli nie przekroczysz określonych dziennych lub miesięcznych limitów, nie poniesiesz żadnych opłat. Ceny i bezpłatne poziomy różnią się w zależności od interfejsów API grup produktów Google. Przykłady:
- Google Cloud – każda usługa jest rozliczana inaczej, ale zwykle płaci się za wykorzystanie. Informacje o poziomie bezpłatnym znajdziesz powyżej.
- Mapy Google – obejmują zestaw interfejsów API i oferują użytkownikom bezpłatne środki o wartości 200 USD miesięcznie.
- Interfejsy API Google Workspace (wcześniej G Suite) – zapewniają wykorzystanie (do określonych limitów) objęte miesięczną opłatą za subskrypcję Google Workspace, więc nie ma bezpośrednich opłat za korzystanie z interfejsów API w aplikacjach takich jak Gmail, Dysk Google, Kalendarz, Dokumenty, Arkusze czy Prezentacje.
Różne usługi Google są rozliczane w różny sposób, dlatego zapoznaj się z odpowiednią dokumentacją, aby uzyskać te informacje.
Podsumowanie
Po włączeniu Cloud Vision włącz pozostałe 3 interfejsy API (Dysk Google, Cloud Storage, Arkusze Google) w ten sam sposób. W Cloud Shell użyj gcloud services enable lub w konsoli Cloud:
- Wróć do biblioteki API
- Rozpocznij wyszukiwanie, wpisując kilka liter nazwy.
- Wybierz odpowiedni interfejs API.
- Włącz
Spień, spłucz i powtórz. W przypadku Cloud Storage masz kilka opcji: wybierz „Google Cloud Storage JSON API”. Interfejs Cloud Storage API również będzie wymagać aktywnego konta rozliczeniowego.
7. Krok 0. Skonfiguruj importy i kod autoryzacji
To początek średniej wielkości fragmentu kodu, więc stosowanie praktyk zwinnych pomaga zapewnić wspólną, stabilną i działającą infrastrukturę przed przystąpieniem do głównej aplikacji. Sprawdź, czy w bieżącym katalogu jest dostępny plik client_secret.json. Następnie uruchom plik ipython i wpisz ten fragment kodu lub zapisz go w pliku analyze_gsimg.py i uruchom z powłoki (to drugie rozwiązanie jest lepsze, ponieważ będziemy dodawać kolejne przykładowe kody):
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)
Ten podstawowy komponent zawiera bloki kodu do importowania modułów lub pakietów, przetwarzania danych logowania użytkownika i tworzenia punktów końcowych usługi API. Najważniejsze fragmenty kodu, które należy sprawdzić:
- Zaimportowanie funkcji
print()sprawia, że ten przykładowy kod w języku Python jest zgodny z wersjami 2 i 3, a importowanie biblioteki Google zapewnia wszystkie narzędzia niezbędne do komunikacji z interfejsami API Google. - Zmienna
SCOPESreprezentuje uprawnienia, o które należy poprosić użytkownika. Obecnie jest tylko jedno: uprawnienie do odczytywania danych z jego Dysku Google. - Pozostała część kodu przetwarzania danych logowania odczytuje tokeny OAuth2 zapisane w pamięci podręcznej, a w razie potrzeby aktualizuje je do nowego tokena dostępu za pomocą tokena odświeżania, jeśli pierwotny token dostępu wygasł.
- Jeśli nie utworzono żadnych tokenów lub pobranie prawidłowego tokena dostępu nie powiodło się z innego powodu, użytkownik musi przejść proces OAuth2 3LO: utworzyć okno z wymaganymi uprawnieniami i poprosić użytkownika o zaakceptowanie. Jeśli tak się stanie, aplikacja będzie kontynuować działanie. W przeciwnym razie funkcja
tools.run_flow()zwróci wyjątek i wykonanie zostanie przerwane. - Gdy użytkownik przyzna uprawnienia, zostanie utworzony klient HTTP do komunikacji z serwerem, a wszystkie żądania będą podpisywane danymi logowania użytkownika w celu zapewnienia bezpieczeństwa. Następnie tworzony jest punkt końcowy usługi interfejsu Google Drive API (wersja 3) z tym klientem HTTP, który jest następnie przypisywany do
DRIVE.
Uruchamianie aplikacji
Gdy uruchomisz skrypt po raz pierwszy, nie będzie on mieć uprawnień do uzyskiwania dostępu do plików użytkownika na Dysku (Twoich). Dane wyjściowe wyglądają tak po wstrzymaniu wykonywania:
$ 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
Jeśli korzystasz z Cloud Shell, przejdź do sekcji „Z Cloud Shell”, a potem wróć, aby w razie potrzeby przejrzeć odpowiednie ekrany w sekcji „Z lokalnego środowiska programistycznego”.
z lokalnego środowiska programistycznego,
Skrypt wiersza poleceń zostanie wstrzymany, a otworzy się okno przeglądarki. Może pojawić się strona z ostrzeżeniem, która wygląda tak:

Jest to uzasadniona obawa, ponieważ próbujesz uruchomić aplikację, która uzyskuje dostęp do danych użytkowników. To tylko aplikacja w wersji demonstracyjnej, a Ty jesteś jej deweloperem, więc ufamy, że masz do siebie wystarczająco dużo zaufania, aby przejść dalej. Aby lepiej to zrozumieć, postaw się na miejscu użytkownika: prosisz go o zezwolenie na dostęp do jego danych za pomocą kodu innej osoby. Jeśli zamierzasz opublikować taką aplikację, musisz przejść proces weryfikacji, aby użytkownicy nie widzieli tego ekranu.
Po kliknięciu linku „Przejdź do aplikacji „niebezpiecznej”” pojawi się okno uprawnień OAuth2, które wygląda mniej więcej tak jak poniżej. Stale ulepszamy nasz interfejs, więc nie martw się, jeśli nie będzie to dopasowanie ścisłe:

Okno dialogowe procesu OAuth2 odzwierciedla uprawnienia, o które prosi deweloper (za pomocą zmiennej SCOPES). W tym przypadku jest to możliwość wyświetlania i pobierania plików z Dysku Google użytkownika. W kodzie aplikacji te zakresy uprawnień są wyświetlane jako identyfikatory URI, ale są tłumaczone na język określony przez ustawienia regionalne użytkownika. W tym przypadku użytkownik musi wyraźnie zezwolić na wymagane uprawnienia. W przeciwnym razie zostanie zgłoszony wyjątek, a skrypt nie będzie kontynuowany.
Może się nawet pojawić kolejne okno dialogowe z prośbą o potwierdzenie:

NOTE niektórzy użytkownicy korzystają z kilku przeglądarek internetowych, w których są zalogowani na różne konta. W takim przypadku prośba o autoryzację może zostać wysłana do niewłaściwej karty lub okna przeglądarki. Może być konieczne skopiowanie i wklejenie linku do tej prośby w przeglądarce, w której zalogowane jest właściwe konto.
Z Cloud Shell
W Cloud Shell nie pojawia się okno przeglądarki, co uniemożliwia dalsze działanie. Zauważ, że komunikat diagnostyczny u dołu jest przeznaczony dla Ciebie:
If your browser is on a different machine then exit and re-run this application with the command-line parameter --noauth_local_webserver
Musisz nacisnąć ^C (Ctrl-C lub inny klawisz, aby zatrzymać wykonywanie skryptu) i stosować go z poziomu powłoki z dodatkową flagą. W takim przypadku otrzymasz te wyniki:
$ 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:
(Ignorujemy ostrzeżenie, ponieważ wiemy, że storage.json nie został jeszcze utworzony). Postępując zgodnie z instrukcjami na innej karcie przeglądarki z tym adresem URL, uzyskasz środowisko niemal identyczne z opisanym powyżej w przypadku lokalnych środowisk deweloperskich (patrz zrzuty ekranu powyżej). Na końcu pojawi się ostatni ekran z kodem weryfikacyjnym, który należy wpisać w Cloud Shell:

Skopiuj ten kod i wklej go w oknie terminala.
Podsumowanie
Oprócz „Authentication successful” nie oczekuj żadnych dodatkowych danych wyjściowych. Pamiętaj, że to tylko konfiguracja. Nic jeszcze nie zostało zrobione. To, co zrobisz, będzie początkiem drogi do czegoś, co prawdopodobnie od razu zadziała prawidłowo. (Najlepsze jest to, że prośba o autoryzację została wyświetlona tylko raz. Wszystkie kolejne wykonania są pomijane, ponieważ Twoje uprawnienia zostały zapisane w pamięci podręcznej). Teraz sprawimy, że kod wykona prawdziwą pracę i wygeneruje rzeczywiste dane wyjściowe.
Rozwiązywanie problemów
Jeśli zamiast braku danych wyjściowych pojawi się błąd, może to być spowodowane co najmniej jedną z tych przyczyn:
8. Krok 1. Pobierz obraz z Dysku Google
W poprzednim kroku zalecaliśmy utworzenie kodu jako analyze_gsimg.py i wprowadzenie w nim zmian. Możesz też po prostu skopiować i wkleić wszystko bezpośrednio do iPythona lub standardowej powłoki Pythona, ale jest to bardziej kłopotliwe, ponieważ będziemy dalej budować aplikację krok po kroku.
Załóżmy, że Twoja aplikacja została autoryzowana i utworzono punkt końcowy usługi API. W kodzie jest ona reprezentowana przez zmienną DRIVE. Teraz znajdź plik obrazu na Dysku Google i
ustawić ją na zmienną o nazwie NAME. Wpisz ten kod oraz funkcję drive_get_img() poniżej kodu z kroku 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
Kolekcja files() na Dysku ma metodę list(), która wykonuje zapytanie (parametr q) dotyczące określonego pliku. Parametr fields służy do określania, które wartości zwrotne Cię interesują. Po co pobierać wszystkie wartości i spowalniać działanie, jeśli nie zależy Ci na innych wartościach? Jeśli dopiero zaczynasz korzystać z masek pól do filtrowania wartości zwracanych przez interfejs API, przeczytaj ten post na blogu i obejrzyj film. W przeciwnym razie wykonaj zapytanie i pobierz zwrócony atrybut files. Jeśli nie ma dopasowań, domyślnie użyj pustej tablicy listy.
Jeśli nie ma wyników, pozostała część funkcji jest pomijana i zwracana jest wartość None (niejawnie). W przeciwnym razie pobierz pierwszą pasującą odpowiedź (rsp[0]), zwróć nazwę pliku, jego typ MIME, sygnaturę czasową ostatniej modyfikacji i wreszcie jego binarną zawartość, pobraną przez funkcję get_media() (za pomocą identyfikatora pliku), również w kolekcji files(). (Nazwy metod mogą się nieznacznie różnić w przypadku bibliotek klienta w innych językach).
Ostatnia część to „główna” treść, która steruje całą aplikacją:
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)
Załóżmy, że na Dysku znajduje się obraz o nazwie section-work-card-img_2x.jpg, który ma ustawienie FILE. Po pomyślnym wykonaniu skryptu powinny pojawić się dane wyjściowe potwierdzające, że udało się odczytać plik z Dysku (ale nie został on zapisany na komputerze):
$ python3 analyze_gsimg.py Downloaded 'section-work-card-img_2x.jpg' (image/jpeg, 2020-02-27T09:27:22.095Z, size: 27781)
Rozwiązywanie problemów
Jeśli nie uzyskasz podobnych wyników, może to być spowodowane co najmniej jedną z tych przyczyn:
Podsumowanie
W tej sekcji dowiesz się, jak (w 2 oddzielnych wywołaniach interfejsu API) połączyć się z interfejsem Drive API, aby wyszukać określony plik, a następnie go pobrać. Zastosowanie biznesowe: archiwizowanie danych z Dysku i ich analiza, np. za pomocą narzędzi Google Cloud. Kod aplikacji na tym etapie powinien być zgodny z kodem w repozytoriumstep1-drive/analyze_gsimg.py.
Więcej informacji o pobieraniu plików z Dysku Google znajdziesz tutaj. Możesz też zapoznać się z tym postem na blogu i filmem. Ta część kursu Codelabs jest niemal identyczna z całym kursem wprowadzającym do interfejsów Google Workspace API. Zamiast pobierać plik, wyświetla pierwsze 100 plików lub folderów na Dysku Google użytkownika i używa bardziej restrykcyjnego zakresu.
9. Krok 2. Archiwizowanie pliku w Cloud Storage
Następnym krokiem jest dodanie obsługi Google Cloud Storage. W tym celu musimy zaimportować kolejny pakiet Pythona, io. Sprawdź, czy górna sekcja importowanych danych wygląda teraz tak:
from __future__ import print_function
import io
Oprócz nazwy pliku na Dysku potrzebujemy informacji o tym, gdzie przechowywać ten plik w Cloud Storage, a w szczególności nazwy „zasobnika”, w którym ma się on znajdować, oraz prefiksów „folderu nadrzędnego”. Więcej informacji na ten temat znajdziesz poniżej:
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = '' # YOUR IMG FILE PREFIX
Słowo o zasobnikach: Cloud Storage zapewnia bezpostaciową pamięć masową typu blob. Podczas przesyłania plików nie rozpoznaje on typów plików, rozszerzeń itp., tak jak Dysk Google. Dla Cloud Storage są to po prostu „obiekty blob”. Ponadto w Cloud Storage nie ma pojęcia folderów ani podkatalogów.
Tak, w nazwach plików możesz używać ukośników (/), aby reprezentować abstrakcję wielu podfolderów, ale ostatecznie wszystkie obiekty blob trafiają do zasobnika, a „/” to tylko znaki w nazwach plików. Więcej informacji znajdziesz na stronie z konwencjami nazewnictwa zasobników i obiektów.
W kroku 1 powyżej poprosiliśmy o zakres tylko do odczytu na Dysku. W tamtych czasach to wystarczało. Teraz wymagane są uprawnienia do przesyłania (odczytu i zapisu) w Cloud Storage. Zmień SCOPES z pojedynczej zmiennej tekstowej na tablicę (krotkę lub listę w Pythonie) zakresów uprawnień, aby wyglądała tak:
SCOPES = (
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/devstorage.full_control',
)
Teraz utwórz punkt końcowy usługi Cloud Storage bezpośrednio pod punktem końcowym Dysku. Zmieniliśmy nieco wywołanie, aby ponownie użyć tego samego obiektu klienta HTTP, ponieważ nie ma potrzeby tworzenia nowego, gdy może on być zasobem współdzielonym.
# create API service endpoints
HTTP = creds.authorize(Http())
DRIVE = discovery.build('drive', 'v3', http=HTTP)
GCS = discovery.build('storage', 'v1', http=HTTP)
Teraz dodaj tę funkcję (po drive_get_img()), która przesyła pliki do 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()
Wywołanie objects.().insert() wymaga nazwy zasobnika, metadanych pliku i samego obiektu binarnego. Aby odfiltrować zwracane wartości, zmienna fields żąda tylko nazw zasobników i obiektów zwracanych przez interfejs API. Więcej informacji o tych maskach pól w żądaniach odczytu z interfejsu API znajdziesz w tym poście i filmie.
Teraz zintegruj korzystanie z gcs_blob_upload() z główną aplikacją:
# 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)
Zmienna gcsname scala nazwy „podkatalogów nadrzędnych” dołączone do nazwy pliku. Jeśli dodasz do niej nazwę zasobnika, uzyskasz wrażenie, że archiwizujesz plik w lokalizacji „/bucket/parent.../filename”. Wstaw ten fragment bezpośrednio po pierwszej funkcji print(), tuż nad klauzulą else, aby cała „główna” część wyglądała tak:
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)
Załóżmy, że określimy zasobnik o nazwie „vision-demo” z „analyzed_imgs” jako „nadrzędny podkatalog”. Gdy ustawisz te zmienne i ponownie uruchomisz skrypt, plik section-work-card-img_2x.jpg zostanie pobrany z Dysku, a następnie przesłany do Cloud Storage, prawda? NIE!
$ 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">
Zwróć uwagę, że pobieranie z Dysku się powiodło, ale przesyłanie do Cloud Storage nie. Dlaczego?
Dzieje się tak, ponieważ gdy pierwotnie autoryzowaliśmy tę aplikację w kroku 1, zezwoliliśmy jej tylko na dostęp do Dysku Google w trybie tylko do odczytu. Dodaliśmy zakres odczytu i zapisu w Cloud Storage, ale nigdy nie poprosiliśmy użytkownika o autoryzację tego dostępu. Aby to zadziałało, musimy usunąć plik storage.json, w którym brakuje tego zakresu, i ponownie uruchomić program.
Po ponownym autoryzowaniu (sprawdź to, otwierając storage.json i sprawdzając, czy są tam oba zakresy) wynik będzie zgodny z oczekiwaniami:
$ 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'
Podsumowanie
To bardzo ważne, ponieważ w stosunkowo niewielu wierszach kodu pokazuje, jak przesyłać pliki między obydwoma systemami pamięci w chmurze. W tym przypadku firma może tworzyć kopie zapasowe zasobów, które mogą być ograniczone, na „chłodniejszej” i tańszej przestrzeni dyskowej, jak wspomnieliśmy wcześniej. Cloud Storage oferuje różne klasy pamięci masowej w zależności od tego, czy dostęp do danych jest regularny, miesięczny, kwartalny czy roczny.
Programiści pytają nas czasem, dlaczego istnieją zarówno Dysk Google, jak i Cloud Storage. Przecież oba te rozwiązania służą do przechowywania plików w chmurze. Dlatego stworzyliśmy ten film. Kod na tym etapie powinien być zgodny z kodem w repozytoriumstep2-gcs/analyze_gsimg.py.
10. Krok 3. Analiza za pomocą Cloud Vision
Wiemy już, że możesz przenosić dane między Google Cloud a Google Workspace, ale nie przeprowadziliśmy jeszcze żadnej analizy, więc czas wysłać obraz do Cloud Vision w celu dodania adnotacji do etykiet, czyli wykrywania obiektów. W tym celu musimy zakodować dane w formacie Base64, co oznacza, że potrzebujemy kolejnego modułu Pythona, base64. Sprawdź, czy sekcja importu u góry wygląda teraz tak:
from __future__ import print_function
import base64
import io
Domyślnie interfejs Vision API zwraca wszystkie znalezione etykiety. Aby zachować spójność, poprośmy tylko o 5 najpopularniejszych (użytkownik może oczywiście dostosować tę liczbę). Użyjemy do tego stałej zmiennej TOP. Dodaj ją pod wszystkimi innymi stałymi:
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = '' # YOUR IMG FILE PREFIX
TOP = 5 # TOP # of VISION LABELS TO SAVE
Podobnie jak w przypadku poprzednich kroków, potrzebujemy kolejnego zakresu uprawnień, tym razem dla interfejsu Vision API. Zaktualizuj SCOPES za pomocą jego ciągu znaków:
SCOPES = (
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/devstorage.full_control',
'https://www.googleapis.com/auth/cloud-vision',
)
Teraz utwórz punkt końcowy usługi Cloud Vision, aby był zgodny z pozostałymi punktami, w ten sposób:
# 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)
Teraz dodaj tę funkcję, która wysyła ładunek obrazu do 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'])
Wywołanie images().annotate() wymaga danych i odpowiednich funkcji interfejsu API. Limit 5 etykiet jest też częścią ładunku (ale jest całkowicie opcjonalny). Jeśli wywołanie się powiedzie, ładunek zwróci 5 najpopularniejszych etykiet obiektów oraz poziom ufności, że obiekt znajduje się na obrazie. (Jeśli nie otrzymasz odpowiedzi, przypisz pusty słownik Pythona, aby następna instrukcja if nie zakończyła się niepowodzeniem). Ta funkcja po prostu zbiera te dane w ciąg znaków CSV, który będzie można wykorzystać w raporcie.
Te 5 wierszy, które wywołują vision_label_img(), należy umieścić tuż po przesłaniu do 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)
Po dodaniu tego warunku cały główny sterownik powinien wyglądać tak:
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)
Usunięcie storage.json w celu odświeżenia zakresów i ponowne uruchomienie zaktualizowanej aplikacji powinno dać dane wyjściowe podobne do tych poniżej, z uwzględnieniem analizy 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
Podsumowanie
Nie każdy ma wiedzę z zakresu uczenia maszynowego, która pozwala tworzyć i trenować własne modele ML do analizowania danych. Zespół Google Cloud udostępnił niektóre wytrenowane modele Google do ogólnego użytku i umieścił je za interfejsami API, pomagając w demokratyzacji AI i ML dla wszystkich.
Jeśli jesteś programistą i możesz wywoływać interfejs API, możesz używać uczenia maszynowego. Cloud Vision to tylko jedna z usług API, których możesz używać do analizowania danych. Więcej informacji o pozostałych znajdziesz tutaj. Twój kod powinien teraz być zgodny z tym, co znajduje się w repozytoriumstep3-vision/analyze_gsimg.py.
11. Krok 4. Wygeneruj raport w Arkuszu Google
Na tym etapie możesz archiwizować dane firmowe i je analizować, ale brakuje Ci podsumowania tych działań. Zbierzmy wszystkie wyniki w jednym raporcie, który możesz przekazać szefowi. Co jest bardziej odpowiednie do zaprezentowania kierownictwu niż arkusz kalkulacyjny?
W przypadku interfejsu Google Sheets API nie są potrzebne żadne dodatkowe importy, a jedyną nową informacją jest identyfikator pliku istniejącego arkusza kalkulacyjnego, który jest już sformatowany i oczekuje na nowy wiersz danych, stąd stała SHEET. Zalecamy utworzenie nowego arkusza kalkulacyjnego, który będzie wyglądać podobnie do tego:

Adres URL tego arkusza kalkulacyjnego będzie wyglądać tak: https://docs.google.com/spreadsheets/d/FILE_ID/edit. Pobierz ten FILE_ID i przypisz go jako ciąg do SHEET.
Dodaliśmy też małą funkcję o nazwie k_ize(), która konwertuje bajty na kilobajty. Zdefiniowaliśmy ją jako funkcję Pythona lambda, ponieważ jest to prosta funkcja jednoelementowa. Obie te wartości zintegrowane z pozostałymi stałymi wyglądają tak:
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
Podobnie jak w przypadku poprzednich kroków, potrzebujemy kolejnego zakresu uprawnień, tym razem do odczytu i zapisu w interfejsie API Arkuszy. SCOPES ma teraz wszystkie 4 potrzebne elementy:
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',
)
Teraz utwórz punkt końcowy usługi Arkuszy Google w pobliżu innych, aby wyglądał tak:
# 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)
Funkcja sheet_append_row() jest prosta: pobiera wiersz danych i identyfikator arkusza, a następnie dodaje ten wiersz do tego arkusza:
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')
Wywołanie spreadsheets().values().append() wymaga podania identyfikatora pliku Arkuszy, zakresu komórek, sposobu wprowadzania danych i samych danych. Identyfikator pliku jest prosty, a zakres komórek jest podany w notacji A1. Zakres „Sheet1” oznacza cały arkusz. Informuje to interfejs API, że wiersz ma zostać dołączony po wszystkich danych w arkuszu. Dostępne są 2 opcje dodawania danych do arkusza: „RAW” (wprowadź dane tekstowe dosłownie) lub „USER_ENTERED” (zapisz dane tak, jakby użytkownik wprowadził je na klawiaturze w aplikacji Arkusze Google, zachowując wszystkie funkcje formatowania komórek).
Jeśli wywołanie się powiedzie, wartość zwracana nie jest zbyt przydatna, dlatego zdecydowaliśmy się na pobranie liczby komórek zaktualizowanych przez żądanie do interfejsu API. Poniżej znajdziesz kod, który wywołuje tę funkcję:
# 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')
Arkusz Google zawiera kolumny z danymi, takimi jak dowolny „podkatalog” nadrzędny, lokalizacja zarchiwizowanego pliku w Cloud Storage (zasobnik + nazwa pliku), typ MIME pliku, rozmiar pliku (pierwotnie w bajtach, ale przekonwertowany na kilobajty z k_ize()) i ciąg etykiet Cloud Vision. Zwróć też uwagę, że zarchiwizowana lokalizacja jest hiperlinkiem, dzięki czemu menedżer może kliknąć go, aby potwierdzić, że została bezpiecznie zapisana.
Dodanie powyższego bloku kodu bezpośrednio po wyświetleniu wyników z Cloud Vision spowoduje, że główna część aplikacji będzie gotowa, choć pod względem struktury jest nieco złożona:
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)
Usunięcie storage.json po raz ostatni i ponowne uruchomienie zaktualizowanej aplikacji powinno dać wynik podobny do tego poniżej, z uwzględnieniem analizy 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
Dodatkowy wiersz danych wyjściowych, choć przydatny, jest lepiej widoczny w zaktualizowanym arkuszu Google, do którego dodano ostatni wiersz (wiersz 7 w przykładzie poniżej) dodany wcześniej do istniejącego zbioru danych:

Podsumowanie
W pierwszych 3 krokach tego samouczka połączyliśmy się z interfejsami Google Workspace i Google Cloud API, aby przenieść dane i je przeanalizować. To 80% całej pracy. Jednak na koniec dnia nic z tego nie będzie miało znaczenia, jeśli nie będziesz w stanie przedstawić kierownictwu swoich osiągnięć. Aby lepiej wizualizować wyniki, warto podsumować je w wygenerowanym raporcie.
Aby zwiększyć przydatność analizy, oprócz zapisania wyników w arkuszu kalkulacyjnym można na przykład zindeksować 5 najpopularniejszych etykiet dla każdego obrazu, aby utworzyć wewnętrzną bazę danych, która umożliwi uprawnionym pracownikom wyszukiwanie obrazów według zespołu wyszukiwania. Pozostawiamy to jednak jako zadanie dla czytelników.
Obecnie wyniki są dostępne w arkuszu i może je wyświetlać kadra kierownicza. Kod aplikacji na tym etapie powinien być zgodny z kodem w repozytoriumstep4-sheets/analyze_gsimg.py. Ostatnim krokiem jest oczyszczenie kodu i przekształcenie go w skrypt, którego można używać.
12. *Ostatni krok: refaktoryzacja
(opcjonalnie) Aplikacja działa, ale czy możemy ją ulepszyć? Tak, zwłaszcza główna aplikacja, która wydaje się być chaotyczna. Umieśćmy to w osobnej funkcji i umożliwmy wprowadzanie danych wejściowych przez użytkownika zamiast stałych wartości. Zrobimy to za pomocą argparse. Dodatkowo po zapisaniu w arkuszu wiersza danych otwórzmy kartę przeglądarki, aby go wyświetlić. Możesz to zrobić za pomocą modułu webbrowser. Połącz te importy z pozostałymi, aby najważniejsze importy wyglądały tak:
from __future__ import print_function
import argparse
import base64
import io
import webbrowser
Aby móc używać tego kodu w innych aplikacjach, musimy mieć możliwość pomijania danych wyjściowych, więc dodajmy flagę DEBUG, aby to zrobić. W tym celu dodaj ten wiersz na końcu sekcji stałych u góry:
DEBUG = False
A teraz przejdźmy do głównej części. Podczas tworzenia tego przykładu powinieneś zacząć odczuwać „dyskomfort”, ponieważ nasz kod dodaje kolejny poziom zagnieżdżenia z każdą dodaną usługą. Jeśli tak uważasz, nie jesteś sam(a), ponieważ zwiększa to złożoność kodu, co opisaliśmy w tym poście na blogu Google Testing Blog.
Zgodnie z tą sprawdzoną metodą przekształćmy główną część aplikacji w funkcję i użyjmy return w każdym „punkcie przerwania” zamiast zagnieżdżania (zwracając None, jeśli którykolwiek krok się nie powiedzie, i True, jeśli wszystkie się powiodą):
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
Jest bardziej przejrzysta i schludna, nie pozostawia wrażenia łańcucha rekurencyjnego if-else i zmniejsza złożoność kodu, jak opisano powyżej. Ostatnim elementem układanki jest utworzenie „prawdziwego” głównego sterownika, który umożliwia dostosowywanie przez użytkownika i minimalizuje dane wyjściowe (chyba że jest to pożądane):
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)
Jeśli wszystkie kroki zostaną wykonane prawidłowo, skrypt uruchomi przeglądarkę internetową z określonym arkuszem kalkulacyjnym, do którego dodano nowy wiersz danych.
Podsumowanie
Nie musisz usuwać storage.json, ponieważ nie nastąpiły żadne zmiany zakresu. Ponowne uruchomienie zaktualizowanej aplikacji spowoduje otwarcie nowego okna przeglądarki ze zmodyfikowanym arkuszem, mniejszą liczbą wierszy danych wyjściowych, a wydanie polecenia -h spowoduje wyświetlenie opcji, w tym -v, które przywróci wcześniej ukryte wiersze danych wyjściowych:
$ 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
Pozostałe opcje umożliwiają użytkownikom wybór różnych nazw plików na Dysku, „podkatalogów” i nazw zasobników Cloud Storage, „N” najlepszych wyników z Cloud Vision oraz identyfikatorów plików arkusza kalkulacyjnego (Arkusz Google). Po wprowadzeniu tych ostatnich zmian ostateczna wersja kodu powinna być zgodna z wersją w repozytoriumfinal/analyze_gsimg.py, a także z wersją podaną poniżej w całości:
'''
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)
Dołożymy wszelkich starań, aby zawartość tego samouczka była aktualna, ale czasami najnowsza wersja kodu będzie dostępna w repozytorium.
13. Gratulacje!
W tym ćwiczeniu z programowania było wiele do nauczenia się, a Ty to osiągnąłeś(-aś), przechodząc przez jedno z dłuższych ćwiczeń. W rezultacie udało Ci się rozwiązać możliwy scenariusz dla przedsiębiorstwa za pomocą około 130 wierszy kodu w języku Python, wykorzystując wszystkie usługi Google Cloud i Google Workspace oraz przenosząc między nimi dane, aby stworzyć działające rozwiązanie. Wszystkie wersje tej aplikacji znajdziesz w repozytorium open source (więcej informacji poniżej).
Czyszczenie danych
- Korzystanie z interfejsów Google Cloud API nie jest bezpłatne, a interfejsy Google Workspace API są objęte miesięczną opłatą za abonament Google Workspace (użytkownicy Gmaila w wersji konsumenckiej nie płacą miesięcznej opłaty). Dlatego użytkownicy Google Workspace nie muszą usuwać ani wyłączać interfejsów API. W przypadku Google Cloud możesz otworzyć panel konsoli Cloud i sprawdzić szacunkowe opłaty na „karcie” Płatności.
- W przypadku Cloud Vision możesz bezpłatnie wykonać określoną liczbę wywołań interfejsu API miesięcznie. Dopóki nie przekroczysz tych limitów, nie musisz niczego wyłączać ani usuwać projektu. Więcej informacji o rozliczeniach i bezpłatnym limicie interfejsu Vision API znajdziesz na stronie z cenami.
- Niektórzy użytkownicy Cloud Storage otrzymują bezpłatną ilość miejsca na dane miesięcznie. Jeśli obrazy zarchiwizowane w ramach tego modułu nie spowodują przekroczenia limitu, nie poniesiesz żadnych opłat. Więcej informacji o rozliczeniach GCS i bezpłatnym limicie znajdziesz na stronie z cenami. Obiekty blob możesz wyświetlać i łatwo usuwać w przeglądarce Cloud Storage.
- Korzystanie z Dysku Google może być objęte limitem miejsca na dane. Jeśli go przekroczysz (lub będziesz blisko jego przekroczenia), możesz użyć narzędzia utworzonego w tym module, aby zarchiwizować obrazy w Cloud Storage i zyskać więcej miejsca na Dysku. Więcej informacji o miejscu na dane na Dysku Google znajdziesz na odpowiedniej stronie z cenami dla użytkowników Google Workspace Basic lub Gmaila/konsumentów.
Większość abonamentów Google Workspace Business i Enterprise oferuje nieograniczone miejsce na dane, ale może to powodować przepełnienie folderów na Dysku i utrudniać poruszanie się po nich. Aplikacja utworzona w tym samouczku to świetny sposób na archiwizowanie zbędnych plików i porządkowanie Dysku Google.
Wersje alternatywne
Wersja final/analyze_gsimg.py jest „ostatnią” oficjalną wersją, nad którą pracujesz w tym samouczku, ale to nie koniec. Jednym z problemów z ostateczną wersją aplikacji jest to, że korzysta ona ze starszych bibliotek uwierzytelniania, które zostały wycofane. Wybraliśmy tę ścieżkę, ponieważ w momencie pisania tego artykułu nowsze biblioteki uwierzytelniania nie obsługiwały kilku kluczowych elementów: zarządzania przechowywaniem tokenów OAuth i bezpieczeństwa wątków.
Obecne (nowsze) biblioteki uwierzytelniania
W pewnym momencie starsze biblioteki uwierzytelniania przestaną być obsługiwane, dlatego zachęcamy do zapoznania się z wersjami, które korzystają z nowszych (bieżących) bibliotek uwierzytelniania, w folderze alt repozytorium, nawet jeśli nie są one bezpieczne dla wątków (ale możesz stworzyć własne rozwiązanie, które będzie bezpieczne). Wyszukaj pliki, których nazwy zawierają znak *newauth*.
Biblioteki klienta usług Google Cloud
Google Cloud zaleca wszystkim deweloperom korzystanie z bibliotek klienta usługi podczas używania interfejsów API Google Cloud. Niestety interfejsy API inne niż Google Cloud nie mają obecnie takich bibliotek. Korzystanie z bibliotek niższego poziomu umożliwia spójne używanie interfejsu API i zapewnia lepszą czytelność. Podobnie jak w przypadku powyższej rekomendacji, alternatywne wersje korzystające z bibliotek klienta usług Google Cloud są dostępne w folderze alt repozytorium. Wyszukaj pliki, których nazwy zawierają znak *-gcp*.
Autoryzacja za pomocą konta usługi
W przypadku pracy wyłącznie w chmurze zwykle nie ma ludzi ani danych należących do użytkowników (ludzi), dlatego konta usługi i autoryzacja kont usługi są używane głównie w Google Cloud. Dokumenty Google Workspace należą jednak zwykle do użytkowników (osób), dlatego w tym samouczku używamy autoryzacji konta użytkownika. Nie oznacza to jednak, że nie można używać interfejsów Google Workspace API z kontami usługi. Jeśli tylko te konta mają odpowiedni poziom dostępu, można ich używać w aplikacjach. Podobnie jak powyżej, alternatywne wersje korzystające z autoryzacji konta usługi są dostępne w folderze alt repozytorium. Wyszukaj pliki, których nazwy zawierają znak *-svc*.
Katalog wersji alternatywnych
Poniżej znajdziesz wszystkie alternatywne wersje final/analyze_gsimg.py, z których każda ma co najmniej 1 z powyższych atrybutów. W nazwie pliku każdej wersji poszukaj:
- „
oldauth” w przypadku wersji korzystających ze starszych bibliotek uwierzytelniania (opróczfinal/analyze_gsimg.py). - „
newauth” dla osób korzystających z obecnych lub nowszych bibliotek uwierzytelniania - „
gcp” dla osób korzystających z bibliotek klienta usług Google Cloud, np. google-cloud-storage itp. - „
svc” w przypadku użytkowników, którzy zamiast konta użytkownika korzystają z uwierzytelniania konta usługi („svc acct”)
Oto wszystkie wersje:
Nazwa pliku | Opis |
| Przykładowy kod podstawowy, który korzysta ze starszych bibliotek uwierzytelniania |
| Podobnie jak |
| Tak samo jak |
| Tak samo jak |
| Tak samo jak |
| Tak samo jak |
| Podobnie jak |
| Podobnie jak |
W połączeniu z oryginalnym final/analyze_gsimg.py masz wszystkie możliwe kombinacje ostatecznego rozwiązania , niezależnie od środowiska programistycznego interfejsu API Google, i możesz wybrać tę, która najlepiej odpowiada Twoim potrzebom. Podobne wyjaśnienie znajdziesz też w sekcji alt/README.md.
Dodatkowe badania
Poniżej znajdziesz kilka pomysłów na to, jak pójść o krok lub dwa dalej. Zestaw problemów, z którymi radzi sobie obecne rozwiązanie, można rozszerzyć, co pozwoli Ci wprowadzić te ulepszenia:
- (wiele obrazów w folderach) Zamiast przetwarzać jeden obraz, załóżmy, że masz obrazy w folderach na Dysku Google.
- (wiele obrazów w plikach ZIP) Zamiast folderu z obrazami możesz użyć archiwów ZIP zawierających pliki obrazów. Jeśli używasz Pythona, rozważ użycie
zipfilemodułu. - (analizuj etykiety Vision) Grupuj podobne obrazy. Zacznij od najczęstszych etykiet, a potem przejdź do kolejnych.
- (tworzenie wykresów) Dalsze działanie 3: generowanie wykresów za pomocą interfejsu Sheets API na podstawie analizy i kategoryzacji wykonanej przez interfejs Vision API.
- (kategoryzowanie dokumentów) Zamiast analizować obrazy za pomocą Cloud Vision API, załóżmy, że masz pliki PDF, które chcesz skategoryzować za pomocą Cloud Natural Language API. Korzystając z powyższych rozwiązań, możesz przechowywać pliki PDF w folderach na Dysku lub w archiwach ZIP na Dysku.
- (tworzenie prezentacji) Użyj interfejsu Slides API, aby wygenerować prezentację na podstawie zawartości raportu w Arkuszach Google. Inspirację znajdziesz w tym poście na blogu i filmie o generowaniu slajdów na podstawie danych z arkusza kalkulacyjnego.
- (eksportowanie do formatu PDF) Eksportowanie arkusza kalkulacyjnego lub prezentacji do formatu PDF, ale nie jest to funkcja interfejsów API Arkuszy ani Prezentacji. Wskazówka: Google Drive API. Dodatkowe punkty: połącz oba pliki PDF z Arkuszy i Prezentacji w jeden główny plik PDF za pomocą narzędzi takich jak Ghostscript (Linux, Windows) lub
Combine PDF Pages.action(Mac OS X).
Więcej informacji
Codelabs
- Wprowadzenie do interfejsów Google Workspace API (Google Drive API) (Python)
- Korzystanie z Cloud Vision w Pythonie (Python)
- Tworzenie dostosowanych narzędzi do raportowania (interfejs Google Sheets API) (JS/Node)
- Przesyłanie obiektów do Google Cloud Storage (bez konieczności pisania kodu)
Ogólne
- Biblioteka klienta interfejsów API Google do języka Python
- Biblioteki klienta interfejsów API Google
Google Workspace
- Strona główna interfejsu Google Drive API
- Strona główna Google Sheets API
- Omówienie i dokumentacja dla deweloperów Google Workspace
Google Cloud
- Strona główna Google Cloud Storage
- Strona główna Google Cloud Vision i wersja demonstracyjna na żywo
- Dokumentacja Cloud Vision API
- Dokumentacja etykietowania obrazów za pomocą Vision API
- Python w Google Cloud
- Biblioteki klienta usług Google Cloud
- Dokumentacja Google Cloud
Licencja
To zadanie jest licencjonowane na podstawie ogólnej licencji Creative Commons Attribution 2.0.