1. Panoramica
Questo codelab descrive un possibile workflow aziendale: archiviazione, analisi e generazione di report delle immagini. Immagina la tua organizzazione che ha una serie di immagini che occupano spazio su una risorsa vincolata. Vuoi archiviare questi dati, analizzare queste immagini e, soprattutto, generare un report che riepiloghi le posizioni archiviate e i risultati dell'analisi, raccolti e pronti per essere utilizzati dal management. Google Cloud fornisce gli strumenti per farlo, utilizzando le API di due delle sue linee di prodotti, Google Workspace (in precedenza G Suite o Google Apps) e Google Cloud (in precedenza GCP).
Nel nostro scenario, l'utente aziendale avrà immagini su Google Drive. È opportuno eseguire il backup di questi dati in un'archiviazione "più fredda" ed economica, ad esempio le classi di archiviazione disponibili in Google Cloud Storage. Google Cloud Vision consente agli sviluppatori di integrare facilmente le funzionalità di rilevamento della visione nelle applicazioni, tra cui il rilevamento di oggetti e punti di riferimento, il riconoscimento ottico dei caratteri (OCR) e così via. Infine, un foglio di lavoro Fogli Google è uno strumento di visualizzazione utile per riassumere tutto questo per il tuo capo.
Dopo aver completato questo codelab per creare una soluzione che sfrutti tutte le potenzialità di Google Cloud, ci auguriamo che tu possa trovare l'ispirazione per creare qualcosa di ancora più efficace per la tua organizzazione o per i tuoi clienti.
Obiettivi didattici
- Come utilizzare Cloud Shell
- Come autenticare le richieste API
- Come installare la libreria client delle API di Google per Python
- Come abilitare le API di Google
- Come scaricare file da Google Drive
- Come caricare oggetti/blob in Cloud Storage
- Come analizzare i dati con Cloud Vision
- Come scrivere righe in Fogli Google
Che cosa ti serve
- Un Account Google (gli account Google Workspace potrebbero richiedere l'approvazione dell'amministratore)
- Un progetto Google Cloud con un account di fatturazione Google Cloud attivo
- Familiarità con i comandi del terminale/della shell del sistema operativo
- Competenze di base in Python (2 o 3), ma puoi utilizzare qualsiasi linguaggio supportato
L'esperienza pregressa con i quattro prodotti Google Cloud elencati sopra sarebbe utile, ma non è obbligatoria. Se hai tempo per familiarizzare con loro separatamente, puoi fare i codelab per ciascuno prima di affrontare l'esercizio qui:
- Introduzione a Google Drive (utilizzo delle API Google Workspace) (Python)
- Utilizzo di Cloud Vision con Python (Python)
- Crea strumenti di reporting personalizzati con l'API Sheets (JS/Node)
- Carica oggetti in Google Cloud Storage (non è richiesta alcuna codifica)
Sondaggio
Come utilizzerai questo tutorial?
Come valuteresti la tua esperienza con Python?
Come valuti la tua esperienza di utilizzo dei servizi Google Cloud?
Come valuti la tua esperienza con l'utilizzo dei servizi per sviluppatori Google Workspace?
Ti piacerebbe vedere più codelab "orientati al business" rispetto a quelli che introducono le funzionalità dei prodotti?
2. Configurazione e requisiti
Configurazione dell'ambiente autonomo
- Accedi alla console Google Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai ancora un account Gmail o Google Workspace, devi crearne uno.



- Il nome del progetto è il nome visualizzato per i partecipanti a questo progetto. È una stringa di caratteri non utilizzata dalle API di Google. Puoi aggiornarlo in qualsiasi momento.
- L'ID progetto deve essere univoco in tutti i progetti Google Cloud ed è immutabile (non può essere modificato dopo essere stato impostato). La console Cloud genera automaticamente una stringa univoca, di solito non ti interessa di cosa si tratta. Nella maggior parte dei codelab, devi fare riferimento all'ID progetto (in genere è identificato come
PROJECT_ID). Se non ti piace l'ID generato, puoi generarne un altro casuale. In alternativa, puoi provare a crearne uno e vedere se è disponibile. Non può essere modificato dopo questo passaggio e rimarrà per tutta la durata del progetto. - Per tua informazione, esiste un terzo valore, un numero di progetto, utilizzato da alcune API. Scopri di più su tutti e tre questi valori nella documentazione.
- Successivamente, devi abilitare la fatturazione in Cloud Console per utilizzare le risorse/API Cloud. L'esecuzione di questo codelab non dovrebbe costare molto, se non nulla. Per arrestare le risorse in modo da non incorrere in costi di fatturazione al termine di questo tutorial, puoi eliminare le risorse che hai creato o l'intero progetto. I nuovi utenti di Google Cloud possono beneficiare del programma prova senza costi di 300$.
Avvia Cloud Shell
Riepilogo
Sebbene tu possa sviluppare codice localmente sul tuo laptop, un obiettivo secondario di questo codelab è insegnarti a utilizzare Google Cloud Shell, un ambiente a riga di comando in esecuzione nel cloud tramite il tuo browser web moderno.
Attiva Cloud Shell
- Nella console Cloud, fai clic su Attiva Cloud Shell
.

Se non hai mai avviato Cloud Shell, viene visualizzata una schermata intermedia (sotto la piega) che ne descrive le funzionalità. In questo caso, fai clic su Continua e non comparirà più. Ecco come si presenta la schermata intermedia:

Bastano pochi istanti per eseguire il provisioning e connettersi a Cloud Shell.

Questa macchina virtuale è caricata con tutti gli strumenti per sviluppatori di cui hai bisogno. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione della rete. Gran parte del lavoro per questo codelab, se non tutto, può essere svolto semplicemente con un browser o con Chromebook.
Una volta eseguita la connessione a Cloud Shell, dovresti vedere che il tuo account è già autenticato e il progetto è già impostato sul tuo ID progetto.
- Esegui questo comando in Cloud Shell per verificare che l'account sia autenticato:
gcloud auth list
Output comando
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- Esegui questo comando in Cloud Shell per verificare che il comando gcloud conosca il tuo progetto:
gcloud config list project
Output comando
[core] project = <PROJECT_ID>
In caso contrario, puoi impostarlo con questo comando:
gcloud config set project <PROJECT_ID>
Output comando
Updated property [core/project].
3. Conferma l'ambiente Python
Questo codelab richiede l'utilizzo del linguaggio Python (anche se le librerie client delle API di Google supportano molti linguaggi, quindi sentiti libero di creare qualcosa di equivalente nel tuo strumento di sviluppo preferito e di utilizzare Python come pseudocodice). In particolare, questo codelab supporta Python 2 e 3, ma ti consigliamo di passare alla versione 3.x il prima possibile.
Cloud Shell è uno strumento pratico disponibile per gli utenti direttamente dalla console Cloud e non richiede un ambiente di sviluppo locale, quindi questo tutorial può essere completato interamente nel cloud con un browser web. Più nello specifico per questo codelab, Cloud Shell ha già preinstallato entrambe le versioni di Python.
Cloud Shell ha anche IPython installato: si tratta di un interprete Python interattivo di livello superiore che consigliamo, soprattutto se fai parte della community di data science o machine learning. In caso affermativo, IPython è l'interprete predefinito per i notebook Jupyter e per Colab, i notebook Jupyter ospitati da Google Research.
IPython preferisce prima un interprete Python 3, ma torna a Python 2 se la versione 3.x non è disponibile. È possibile accedere a IPython da Cloud Shell, ma può anche essere installato in un ambiente di sviluppo locale. Esci con ^D (Ctrl+D) e accetta l'offerta di uscire. L'output di esempio dell'avvio di ipython sarà simile al seguente:
$ 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]:
Se IPython non è la tua preferenza, l'utilizzo di un interprete interattivo Python standard (Cloud Shell o il tuo ambiente di sviluppo locale) è perfettamente accettabile (esci anche con ^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. >>>
Il codelab presuppone inoltre che tu disponga dello strumento di installazione pip (gestore pacchetti e risolutore di dipendenze Python). È incluso nelle versioni 2.7.9+ o 3.4+. Se hai una versione precedente di Python, consulta questa guida per le istruzioni di installazione. A seconda delle autorizzazioni, potresti dover disporre dell'accesso sudo o superutente, ma in genere non è così. Puoi anche utilizzare esplicitamente pip2 o pip3 per eseguire pip per versioni specifiche di Python.
Il resto del codelab presuppone che tu stia utilizzando Python 3. Se le istruzioni per Python 2 differiscono in modo significativo da quelle per la versione 3.x, verranno fornite istruzioni specifiche.
[Facoltativo] Crea e utilizza ambienti virtuali
Questa sezione è facoltativa e necessaria solo per chi deve utilizzare un ambiente virtuale per questo codelab (come indicato nella barra laterale di avviso sopra). Se sul computer è installato solo Python 3, puoi semplicemente eseguire questo comando per creare un virtualenv chiamato my_env (puoi scegliere un altro nome, se vuoi):
virtualenv my_env
Tuttavia, se hai sia Python 2 che 3 sul computer, ti consigliamo di installare un virtualenv Python 3, che puoi fare con -p flag in questo modo:
virtualenv -p python3 my_env
Inserisci il virtualenv appena creato "attivandolo" in questo modo:
source my_env/bin/activate
Conferma di trovarti nell'ambiente osservando che il prompt della shell ora è preceduto dal nome dell'ambiente, ad esempio
(my_env) $
Ora dovresti essere in grado di pip install tutti i pacchetti richiesti, eseguire codice all'interno di questo ambiente e così via. Un altro vantaggio è che, se fai un pasticcio, ti trovi in una situazione in cui l'installazione di Python è danneggiata e così via, puoi eliminare l'intero ambiente senza influire sul resto del sistema.
4. Installa la libreria client delle API di Google per Python
Questo codelab richiede l'utilizzo della libreria client delle API di Google per Python, quindi si tratta di un semplice processo di installazione oppure potresti non dover fare nulla.
In precedenza ti abbiamo consigliato di utilizzare Cloud Shell per comodità. Puoi completare l'intero tutorial da un browser web nel cloud. Un altro motivo per utilizzare Cloud Shell è che molti strumenti di sviluppo e librerie necessari sono già preinstallati.
*Installa librerie client
(facoltativo) Questo passaggio può essere ignorato se utilizzi Cloud Shell o un ambiente locale in cui hai già installato le librerie client. Devi eseguire questa operazione solo se stai sviluppando localmente e non li hai installati (o non sei sicuro di averlo fatto). Il modo più semplice è utilizzare pip (o pip3) per eseguire l'installazione (incluso l'aggiornamento di pip stesso, se necessario):
pip install -U pip google-api-python-client oauth2client
Conferma l'installazione
Questo comando installa la libreria client e tutti i pacchetti da cui dipende. Indipendentemente dall'ambiente in uso, Cloud Shell o il tuo, verifica che la libreria client sia installata importando i pacchetti necessari e conferma che non siano presenti errori di importazione (né output):
python3 -c "import googleapiclient, httplib2, oauth2client"
Se utilizzi Python 2 (da Cloud Shell), riceverai un avviso che ti informa che il supporto è stato ritirato:
******************************************************************************* 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. *******************************************************************************
Una volta eseguito correttamente il comando "test" di importazione (senza errori/output), puoi iniziare a comunicare con le API di Google.
Riepilogo
Poiché si tratta di un codelab intermedio, si presume che tu abbia già esperienza nella creazione e nell'utilizzo di progetti nella console. Se non hai mai utilizzato le API di Google e in particolare le API di Google Workspace, prova prima il codelab introduttivo alle API di Google Workspace. Inoltre, se sai come creare (o riutilizzare) le credenziali di un account utente (non service account), trascina il file client_secret.json nella directory di lavoro, salta il modulo successivo e vai a "Attiva le API di Google".
5. *Autorizza le richieste API (autorizzazione utente)
Questa sezione può essere ignorata se hai già creato le credenziali di autorizzazione dell'account utente e conosci la procedura. È diverso dall'autorizzazione del service account, la cui tecnica è diversa, quindi continua a leggere di seguito.
Introduzione all'autorizzazione (più qualche autenticazione)
Per effettuare richieste alle API, la tua applicazione deve disporre dell'autorizzazione appropriata. Autenticazione, un termine simile, descrive le credenziali di accesso. Ti autentichi quando accedi al tuo Account Google con un nome utente e una password. Una volta autenticato, il passaggio successivo consiste nel verificare se tu, o meglio, il tuo codice, sei autorizzato ad accedere ai dati, ad esempio ai file blob su Cloud Storage o ai file personali di un utente su Google Drive.
Le API di Google supportano diversi tipi di autorizzazione, ma quella più comune per gli utenti delle API G Suite è l'autorizzazione utente, poiché l'applicazione di esempio in questo codelab accede ai dati appartenenti agli utenti finali. Questi utenti finali devono concedere l'autorizzazione alla tua app per accedere ai loro dati. Ciò significa che il codice deve ottenere le credenziali OAuth2 dell'account utente.
Per ottenere le credenziali OAuth2 per l'autorizzazione utente, torna a Gestione API e seleziona la scheda "Credenziali" nel riquadro di navigazione a sinistra:

Una volta lì, vedrai tutte le tue credenziali in tre sezioni separate:

Il primo è per le chiavi API, il secondo per gli ID client OAuth 2.0 e l'ultimo per gli account di servizio OAuth2. Utilizziamo quello centrale.
Creazione delle credenziali
Nella pagina Credenziali, fai clic sul pulsante + Crea credenziali in alto, che apre una finestra di dialogo in cui scegliere "ID client OAuth":

Nella schermata successiva, hai due azioni: configurare la "schermata di consenso" dell'autorizzazione dell'app e scegliere il tipo di applicazione:

Se non hai impostato una schermata per il consenso, vedrai l'avviso nella console e dovrai farlo ora. Salta i passaggi successivi se la schermata per il consenso è già stata configurata.
Schermata consenso OAuth
Fai clic su "Configura schermata di consenso" in cui selezioni un'app"Esterna " (o"Interna" se sei un cliente G Suite):

Tieni presente che ai fini di questo esercizio, non importa quale scegli perché non pubblicherai l'esempio di codelab. La maggior parte degli utenti selezionerà "Esterno" per accedere a una schermata più complessa, ma in realtà devi solo compilare il campo "Nome applicazione" in alto:

L'unica cosa che ti serve al momento è un nome dell'applicazione, quindi scegli un nome che rifletta il codelab che stai seguendo e fai clic su Salva.
Creazione dell'ID client OAuth (autenticazione dell'account utente)
Ora torna alla scheda Credenziali per creare un ID client OAuth2. Qui vedrai una serie di ID client OAuth che puoi creare:

Stiamo sviluppando uno strumento a riga di comando, ovvero Altro, quindi scegli questa opzione e fai clic sul pulsante Crea. Scegli un nome per l'ID client che rifletta l'app che stai creando o accetta il nome predefinito, che di solito è "Altro client N".
Salvataggio delle credenziali
- Viene visualizzata una finestra di dialogo con le nuove credenziali; fai clic su Ok per chiuderla.

- Torna alla pagina Credenziali, scorri verso il basso fino alla sezione "ID client OAuth 2.0", individua e fai clic sull'icona di download
in basso a destra dell'ID client appena creato. 
- Si apre una finestra di dialogo per salvare un file denominato
client_secret-LONG-HASH-STRING.apps.googleusercontent.com.json, probabilmente nella cartella Download. Ti consigliamo di abbreviare il nome in uno più semplice, ad esempioclient_secret.json(che è quello utilizzato dall'app di esempio), quindi di salvarlo nella directory/cartella in cui creerai l'app di esempio in questo codelab.
Riepilogo
Ora puoi abilitare le API di Google utilizzate in questo codelab. Inoltre, per il nome dell'applicazione nella schermata per il consenso OAuth, abbiamo scelto "Demo dell'API Vision", quindi aspettati di vederlo in alcuni degli screenshot imminenti.
6. Abilita le API di Google
Questo codelab utilizza quattro API Google Cloud, una coppia di Google Cloud (Cloud Storage e Cloud Vision) e un'altra coppia di Google Workspace (Google Drive e Google Sheets). Di seguito sono riportate le istruzioni generali per abilitare le API di Google. Una volta che sai come abilitare un'API, le altre sono simili.
Indipendentemente dall'API Google che vuoi utilizzare nella tua applicazione, deve essere abilitata. Le API possono essere abilitate dalla riga di comando o dalla console Cloud. La procedura di attivazione delle API è identica, quindi una volta attivata un'API, puoi attivare le altre in modo simile.
Opzione 1: interfaccia a riga di comando gcloud (Cloud Shell o ambiente locale)
Sebbene l'abilitazione delle API dalla console Cloud sia più comune, alcuni sviluppatori preferiscono fare tutto dalla riga di comando. Per farlo, devi cercare il "nome del servizio " di un'API. Sembra un URL: SERVICE_NAME.googleapis.com. Puoi trovarli nel grafico dei prodotti supportati oppure puoi eseguire query in modo programmatico con l'API Google Discovery.
Con queste informazioni, utilizzando Cloud Shell (o il tuo ambiente di sviluppo locale con lo strumento a riga di comando gcloud installato), puoi abilitare un'API o un servizio nel seguente modo:
gcloud services enable SERVICE_NAME.googleapis.com
Esempio 1: abilita l'API Cloud Vision
gcloud services enable vision.googleapis.com
Esempio 2: attiva la piattaforma di calcolo serverless Google App Engine
gcloud services enable appengine.googleapis.com
Esempio 3: abilita più API con una sola richiesta. Ad esempio, se questo codelab ha visualizzatori che eseguono il deployment di un'app utilizzando l'API Cloud Translation in App Engine, Cloud Functions e Cloud Run, la riga di comando sarebbe:
gcloud services enable appengine.googleapis.com cloudfunctions.googleapis.com artifactregistry.googleapis.com run.googleapis.com translate.googleapis.com
Questo comando abilita App Engine, Cloud Functions, Cloud Run e l'API Cloud Translation. Inoltre, abilita Cloud Artifact Registry perché è qui che le immagini container devono essere registrate dal sistema Cloud Build per poter essere sottoposte a deployment su Cloud Run.
Esistono anche alcuni comandi per eseguire query sulle API da abilitare o su quelle già abilitate per il tuo progetto.
Esempio 4: query per le API di Google disponibili per l'abilitazione per il tuo progetto
gcloud services list --available --filter="name:googleapis.com"
Esempio 5: query per le API di Google abilitate per il tuo progetto
gcloud services list
Per ulteriori informazioni sui comandi precedenti, consulta la documentazione relativa all'attivazione e disattivazione dei servizi e all'elenco dei servizi.
Opzione 2: Cloud Console
Puoi anche abilitare le API di Google in API Manager. Nella console Google Cloud, vai a API Manager. In questa pagina della dashboard, vedrai alcune informazioni sul traffico della tua app, grafici che mostrano le richieste dell'applicazione, gli errori generati dalla tua app e i tempi di risposta della tua app:

Sotto questi grafici è riportato un elenco delle API Google abilitate per il tuo progetto:

Per attivare (o disattivare) le API, fai clic su Abilita API e servizi in alto:

In alternativa, vai alla barra di navigazione a sinistra e seleziona API e servizi → Libreria:

In entrambi i casi, arriverai alla pagina Libreria API:

Inserisci un nome API per cercare e visualizzare i risultati corrispondenti:

Seleziona l'API che vuoi abilitare e fai clic sul pulsante Abilita:

La procedura di attivazione di tutte le API è simile, indipendentemente dall'API Google che vuoi utilizzare.
Costo
Molte API di Google possono essere utilizzate senza costi, tuttavia, l'utilizzo della maggior parte dei prodotti e delle API Google Cloud comporta dei costi. Quando abiliti le API Cloud, potrebbe esserti chiesto un account di fatturazione attivo. Tuttavia, alcuni prodotti Google Cloud includono un livello"Always Free", che devi superare per incorrere in addebiti di fatturazione.
I nuovi utenti di Google Cloud hanno diritto alla prova senza costi, attualmente pari a 300 $per i primi 90 giorni. I codelab in genere non comportano costi di fatturazione elevati o nulli, quindi ti consigliamo di rimandare la prova senza costi finché non sei pronto a provarla, soprattutto perché si tratta di un'offerta una tantum. Le quote del Livello senza costi non scadono e si applicano indipendentemente dal fatto che tu utilizzi o meno la prova senza costi.
Gli utenti devono fare riferimento alle informazioni sui prezzi di qualsiasi API prima di attivarla (ad esempio, la pagina Prezzi dell'API Cloud Vision ), in particolare per verificare se è disponibile un livello senza costi e, in caso affermativo, qual è. Se rispetti i limiti giornalieri o mensili specificati in totale, non dovresti sostenere alcun costo. I prezzi e i livelli senza costi variano a seconda delle API del gruppo di prodotti Google. Esempi:
- Google Cloud: ogni prodotto viene fatturato in modo diverso e generalmente in base al consumo. Consulta le informazioni sul Livello senza costi riportate sopra.
- Google Maps: offre una suite di API e un credito mensile senza costi di 200$.
- API Google Workspace (in precedenza G Suite): forniscono l'utilizzo (fino a determinati limiti) coperto da una tariffa di abbonamento mensile a Google Workspace, pertanto non è prevista una fatturazione diretta per l'utilizzo delle API per applicazioni come Gmail, Google Drive, Calendar, Documenti, Fogli o Presentazioni.
I diversi prodotti Google vengono fatturati in modo diverso, quindi assicurati di consultare la documentazione appropriata per queste informazioni.
Riepilogo
Ora che Cloud Vision è stata abilitata, attiva le altre tre API (Google Drive, Cloud Storage, Fogli Google) nello stesso modo. Da Cloud Shell, utilizza gcloud services enable o dalla console Cloud:
- Torna alla libreria API
- Avvia una ricerca digitando alcune lettere del nome
- Seleziona l'API che ti interessa e
- Attiva
Insapona, risciacqua e ripeti. Per Cloud Storage, ci sono diverse opzioni: scegli "API JSON di Google Cloud Storage". Anche l'API Cloud Storage si aspetterà un account di fatturazione attivo.
7. Passaggio 0: configura le importazioni e il codice di autorizzazione
Si tratta dell'inizio di un blocco di codice di medie dimensioni, quindi seguire in qualche modo le pratiche agili aiuta a garantire un'infrastruttura comune, stabile e funzionante prima di affrontare l'applicazione principale. Verifica che client_secret.json sia disponibile nella directory corrente e avvia ipython e inserisci il seguente snippet di codice oppure salvalo in analyze_gsimg.py ed eseguilo dalla shell (quest'ultima opzione è preferibile perché continueremo ad aggiungere elementi al codice di esempio):
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)
Questo componente principale include blocchi di codice per le importazioni di moduli/pacchetti, l'elaborazione delle credenziali di autenticazione utente e la creazione di endpoint di servizio API. Gli elementi chiave del codice da esaminare:
- L'importazione della funzione
print()rende questo esempio compatibile con Python 2-3 e le importazioni della libreria Google includono tutti gli strumenti necessari per comunicare con le API di Google. - La variabile
SCOPESrappresenta le autorizzazioni da richiedere all'utente. Per ora ce n'è solo una: l'autorizzazione a leggere i dati da Google Drive - Il resto del codice di elaborazione delle credenziali legge i token OAuth2 memorizzati nella cache, aggiornandoli eventualmente a un nuovo token di accesso con il token di aggiornamento se il token di accesso originale è scaduto.
- Se non sono stati creati token o il recupero di un token di accesso valido non è riuscito per un altro motivo, l'utente deve seguire il flusso OAuth2 a tre passaggi: creare la finestra di dialogo con le autorizzazioni richieste e chiedere all'utente di accettare. In caso affermativo, l'app continua, altrimenti
tools.run_flow()genera un'eccezione e l'esecuzione si interrompe. - Una volta che l'utente concede l'autorizzazione, viene creato un client HTTP per comunicare con il server e tutte le richieste vengono firmate con le credenziali dell'utente per motivi di sicurezza. Viene quindi creato un endpoint di servizio per l'API Google Drive (versione 3) con il client HTTP, che viene poi assegnato a
DRIVE.
Esecuzione dell'applicazione
La prima volta che esegui lo script, non avrà l'autorizzazione per accedere ai file dell'utente su Drive (i tuoi). L'output è simile al seguente con l'esecuzione in pausa:
$ 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
Se esegui l'operazione da Cloud Shell, vai alla sezione "Da Cloud Shell" e torna indietro per esaminare le schermate pertinenti in "Dall'ambiente di sviluppo locale" quando opportuno.
Dall'ambiente di sviluppo locale
Lo script della riga di comando viene messo in pausa all'apertura di una finestra del browser. Potresti visualizzare una pagina di avviso dall'aspetto spaventoso simile alla seguente:

Si tratta di una preoccupazione legittima, in quanto stai tentando di eseguire un'app che accede ai dati utente. Poiché si tratta solo di un'app demo e tu sei lo sviluppatore, ci auguriamo che tu ti fidi abbastanza di te stesso per procedere. Per capire meglio, mettiti nei panni dell'utente: ti viene chiesto di consentire al codice di un'altra persona di accedere ai tuoi dati. Se intendi pubblicare un'app di questo tipo, dovrai completare il processo di verifica, in modo che i tuoi utenti non vedano questa schermata.
Dopo aver fatto clic sul link "Vai all'app "non sicura"", verrà visualizzata una finestra di dialogo delle autorizzazioni OAuth2 simile a quella riportata di seguito. Miglioriamo costantemente la nostra interfaccia utente, quindi non preoccuparti se non corrisponde esattamente:

La finestra di dialogo del flusso OAuth2 riflette le autorizzazioni richieste dallo sviluppatore (tramite la variabile SCOPES). In questo caso, si tratta della possibilità di visualizzare e scaricare i contenuti da Google Drive dell'utente. Nel codice dell'applicazione, questi ambiti di autorizzazione vengono visualizzati come URI, ma vengono tradotti nella lingua specificata dalle impostazioni internazionali dell'utente. Qui l'utente deve fornire un'autorizzazione esplicita per le autorizzazioni richieste, altrimenti viene generata un'eccezione e lo script non procede oltre.
Potresti anche visualizzare un'altra finestra di dialogo che ti chiede la conferma:

NOTE: alcuni utenti utilizzano più browser web con accesso a diversi account, pertanto questa richiesta di autorizzazione potrebbe essere inviata alla scheda/finestra del browser sbagliata e potrebbe essere necessario tagliare e incollare il link di questa richiesta in un browser in cui è stato eseguito l'accesso con l'account corretto.
Da Cloud Shell
Da Cloud Shell non viene visualizzata alcuna finestra del browser, quindi non puoi procedere. Renditi conto che il messaggio diagnostico in basso è per te:
If your browser is on a different machine then exit and re-run this application with the command-line parameter --noauth_local_webserver
Dovrai premere ^C (Ctrl+C o un altro tasto per interrompere l'esecuzione dello script) ed eseguirlo dalla shell con il flag aggiuntivo. Se lo esegui in questo modo, otterrai il seguente output:
$ 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:
Ignora l'avviso perché sappiamo che storage.json non è ancora stato creato e, seguendo le istruzioni in un'altra scheda del browser con quell'URL, otterrai un'esperienza quasi identica a quella descritta sopra per gli ambienti di sviluppo locali (vedi gli screenshot sopra). Alla fine c'è una schermata finale con il codice di verifica da inserire in Cloud Shell:

Copia questo codice e incollalo nella finestra del terminale.
Riepilogo
A parte "Authentication successful", non aspettarti altri output. Ricorda che questa è solo la configurazione, non hai ancora fatto nulla. Ciò che hai fatto è l'inizio del tuo percorso verso qualcosa che ha più probabilità di essere eseguito correttamente al primo tentativo. La cosa migliore è che ti è stata richiesta l'autorizzazione una sola volta; tutte le esecuzioni successive la saltano perché le tue autorizzazioni sono state memorizzate nella cache. Ora facciamo in modo che il codice svolga un lavoro reale che produca un output effettivo.
Risoluzione dei problemi
Se viene visualizzato un errore anziché nessun output, il problema potrebbe essere dovuto a una o più cause, ad esempio:
8. Passaggio 1: scarica l'immagine da Google Drive
Nel passaggio precedente, ti abbiamo consigliato di creare il codice come analyze_gsimg.py e di modificarlo da lì. È anche possibile tagliare e incollare tutto direttamente in iPython o nella shell Python standard, ma è più macchinoso perché continueremo a creare l'app pezzo per pezzo.
Supponi che la tua app sia stata autorizzata e che sia stato creato l'endpoint del servizio API. Nel codice, è rappresentato dalla variabile DRIVE. Ora cerchiamo un file immagine su Google Drive e
impostalo su una variabile denominata NAME. Inserisci questo valore più la seguente funzione drive_get_img() appena sotto il codice del passaggio 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
La raccolta files() di Drive ha un metodo list() che esegue una query (il parametro q) per il file specificato. Il parametro fields viene utilizzato per specificare i valori restituiti che ti interessano. Perché preoccuparsi di recuperare tutto e rallentare le operazioni se non ti interessano gli altri valori? Se non hai mai utilizzato le maschere di campo per filtrare i valori restituiti dall'API, consulta questo post del blog e questo video. Altrimenti, esegui la query e recupera l'attributo files restituito, impostando come predefinito un array di elenchi vuoto se non ci sono corrispondenze.
Se non ci sono risultati, il resto della funzione viene ignorato e viene restituito (implicitamente) None. In caso contrario, recupera la prima risposta corrispondente (rsp[0]), restituisci il nome file, il tipo MIME, il timestamp dell'ultima modifica e, infine, il payload binario, recuperato dalla funzione get_media() (tramite il relativo ID file), anche nella raccolta files(). I nomi dei metodi potrebbero variare leggermente con altre librerie client di linguaggi.
L'ultima parte è il corpo "principale" che guida l'intera applicazione:
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)
Supponendo che su Drive sia presente un'immagine denominata section-work-card-img_2x.jpg e impostata su FILE, dopo l'esecuzione dello script, dovresti visualizzare un output che conferma che è stato possibile leggere il file da Drive (ma non salvarlo sul computer):
$ python3 analyze_gsimg.py Downloaded 'section-work-card-img_2x.jpg' (image/jpeg, 2020-02-27T09:27:22.095Z, size: 27781)
Risoluzione dei problemi
Se non ottieni l'output riuscito come sopra, il problema potrebbe essere dovuto a una o più cause, ad esempio questa:
Riepilogo
In questa sezione hai imparato come connetterti all'API Drive (in due chiamate API separate) per eseguire query su un file specifico e scaricarlo. Il caso d'uso aziendale: archiviare i dati di Drive e magari analizzarli, ad esempio con gli strumenti Google Cloud. Il codice della tua app in questa fase dovrebbe corrispondere a quello presente nel repository all'indirizzostep1-drive/analyze_gsimg.py.
Scopri di più sul download di file su Google Drive qui o guarda questo post del blog e questo video. Questa parte del codelab è quasi identica all'intero codelab introduttivo alle API Google Workspace: anziché scaricare un file, mostra i primi 100 file/cartelle sul Google Drive di un utente e utilizza un ambito più restrittivo.
9. Passaggio 2: archivia il file in Cloud Storage
Il passaggio successivo consiste nell'aggiungere il supporto per Google Cloud Storage. Per questo, dobbiamo importare un altro pacchetto Python, io. Assicurati che la sezione superiore delle importazioni ora abbia il seguente aspetto:
from __future__ import print_function
import io
Oltre al nome del file di Drive, abbiamo bisogno di alcune informazioni su dove archiviare questo file su Cloud Storage, in particolare il nome del "bucket" in cui lo inserirai e gli eventuali prefissi delle "cartelle principali". Scopri di più su questo argomento tra poco:
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = '' # YOUR IMG FILE PREFIX
Una nota sui bucket: Cloud Storage fornisce un'archiviazione blob amorfa. Quando carichi file, non comprende il concetto di tipi di file, estensioni e così via, come Google Drive. Per Cloud Storage sono solo "blob". Inoltre, in Cloud Storage non esiste il concetto di cartelle o sottodirectory.
Sì, puoi utilizzare le barre (/) nei nomi dei file per rappresentare l'astrazione di più sottocartelle, ma alla fine tutti i blob vengono inseriti in un bucket e "/" sono solo caratteri nei nomi dei file. Per saperne di più, consulta la pagina sulle convenzioni di denominazione di bucket e oggetti.
Il passaggio 1 sopra riportato ha richiesto l'ambito di sola lettura di Drive. All'epoca, era tutto ciò che ti serviva. Ora è richiesta l'autorizzazione di lettura/scrittura per Cloud Storage. Modifica SCOPES da una singola variabile stringa a un array (tupla o elenco Python) di ambiti di autorizzazione in modo che appaia come segue:
SCOPES = (
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/devstorage.full_control',
)
Ora crea un endpoint di servizio per Cloud Storage subito sotto quello per Drive. Tieni presente che abbiamo modificato leggermente la chiamata per riutilizzare lo stesso oggetto client HTTP, in quanto non è necessario crearne uno nuovo quando può essere una risorsa condivisa.
# create API service endpoints
HTTP = creds.authorize(Http())
DRIVE = discovery.build('drive', 'v3', http=HTTP)
GCS = discovery.build('storage', 'v1', http=HTTP)
Ora aggiungi questa funzione (dopo drive_get_img()) che carica i dati su 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()
La chiamata objects.().insert() richiede il nome del bucket, i metadati del file e il blob binario stesso. Per filtrare i valori restituiti, la variabile fields richiede solo i nomi del bucket e dell'oggetto restituiti dall'API. Per scoprire di più su queste maschere di campo nelle richieste di lettura dell'API, consulta questo post e questo video.
Ora integra l'utilizzo di gcs_blob_upload() nell'applicazione principale:
# 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)
La variabile gcsname unisce i nomi delle "sottodirectory principali" aggiunti al nome del file stesso e, se preceduta dal nome del bucket, dà l'impressione di archiviare il file in "/bucket/parent.../filename". Inserisci questo blocco subito dopo la prima funzione print(), appena sopra la clausola else, in modo che l'intera "main" si presenti così:
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)
Supponiamo di specificare un bucket denominato "vision-demo" con "analyzed_imgs" come "sottodirectory principale". Una volta impostate queste variabili ed eseguito di nuovo lo script, section-work-card-img_2x.jpg verrà scaricato da Drive e caricato in Cloud Storage, giusto? NO!
$ 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">
Guarda attentamente: il download da Drive è riuscito, ma il caricamento su Cloud Storage non è andato a buon fine. Perché?
Il motivo è che quando abbiamo autorizzato originariamente questa applicazione per il passaggio 1, abbiamo autorizzato solo l'accesso in sola lettura a Google Drive. Sebbene abbiamo aggiunto l'ambito di lettura/scrittura per Cloud Storage, non abbiamo mai chiesto all'utente di autorizzare l'accesso. Per farlo funzionare, dobbiamo eliminare il file storage.json a cui manca questo ambito ed eseguire di nuovo il comando.
Dopo aver eseguito nuovamente l'autorizzazione (conferma questa operazione controllando all'interno di storage.json e verificando che siano presenti entrambi gli ambiti), l'output sarà quello previsto:
$ 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'
Riepilogo
Si tratta di un aspetto importante, in quanto mostra, in un numero relativamente ridotto di righe di codice, come trasferire file tra entrambi i sistemi di archiviazione basati sul cloud. Il caso d'uso aziendale qui è il backup di una risorsa potenzialmente vincolata in uno spazio di archiviazione "più freddo" ed economico, come accennato in precedenza. Cloud Storage offre diverse classi di archiviazione a seconda che tu acceda ai tuoi dati regolarmente, mensilmente, trimestralmente o annualmente.
Naturalmente, di tanto in tanto gli sviluppatori ci chiedono perché esistono sia Google Drive che Cloud Storage. Dopo tutto, non sono entrambi sistemi di archiviazione di file nel cloud? Ecco perché abbiamo realizzato questo video. Il codice in questa fase deve corrispondere a quello presente nel repository all'indirizzostep2-gcs/analyze_gsimg.py.
10. Passaggio 3: analizza con Cloud Vision
Ora sappiamo che puoi spostare i dati tra Google Cloud e Google Workspace, ma non abbiamo ancora eseguito alcuna analisi, quindi è il momento di inviare l'immagine a Cloud Vision per l'annotazione delle etichette, ovvero il rilevamento degli oggetti. Per farlo, dobbiamo codificare i dati in Base64, il che significa un altro modulo Python, base64. Assicurati che la sezione di importazione principale ora abbia il seguente aspetto:
from __future__ import print_function
import base64
import io
Per impostazione predefinita, l'API Vision restituisce tutte le etichette che trova. Per mantenere la coerenza, richiediamo solo i primi 5 (regolabili dall'utente, ovviamente). A questo scopo, utilizzeremo una variabile costante TOP. Aggiungila sotto tutte le altre costanti:
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = '' # YOUR IMG FILE PREFIX
TOP = 5 # TOP # of VISION LABELS TO SAVE
Come nei passaggi precedenti, abbiamo bisogno di un altro ambito di autorizzazione, questa volta per l'API Vision. Aggiorna SCOPES con la relativa stringa:
SCOPES = (
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/devstorage.full_control',
'https://www.googleapis.com/auth/cloud-vision',
)
Ora crea un endpoint di servizio per Cloud Vision in modo che sia allineato agli altri in questo modo:
# 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)
Ora aggiungi questa funzione che invia il payload dell'immagine a 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'])
La chiamata images().annotate() richiede i dati più le funzionalità API desiderate. Anche il limite di 5 etichette principali fa parte del payload (ma è completamente facoltativo). Se la chiamata ha esito positivo, il payload restituisce le prime 5 etichette degli oggetti più un punteggio di confidenza che indica la presenza di un oggetto nell'immagine. Se non viene restituita alcuna risposta, assegna un dizionario Python vuoto in modo che l'istruzione if seguente non generi errori. Questa funzione raccoglie semplicemente i dati in una stringa CSV per l'eventuale utilizzo nel report.
Queste 5 righe che chiamano vision_label_img() devono essere inserite subito dopo il caricamento riuscito in 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)
Con questa aggiunta, l'intero driver principale dovrebbe avere l'aspetto seguente:
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)
L'eliminazione di storage.json per aggiornare gli ambiti e la nuova esecuzione dell'applicazione aggiornata dovrebbe generare un output simile al seguente, in cui è stata aggiunta l'analisi di 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
Riepilogo
Non tutti hanno le competenze di machine learning per creare e addestrare i propri modelli ML per analizzare i dati. Il team di Google Cloud ha reso disponibili alcuni dei modelli preaddestrati di Google per uso generale e li ha inseriti dietro le API, contribuendo a democratizzare l'AI e il machine learning per tutti.
Se sei uno sviluppatore e puoi chiamare un'API, puoi utilizzare il machine learning. Cloud Vision è solo uno dei servizi API che puoi utilizzare per analizzare i tuoi dati. Scopri di più sugli altri qui. Il codice ora dovrebbe corrispondere a quello del repository all'indirizzostep3-vision/analyze_gsimg.py.
11. Passaggio 4: genera un report con Fogli Google
A questo punto, hai potuto archiviare i dati aziendali e analizzarli, ma manca un riepilogo di questo lavoro. Organizziamo tutti i risultati in un unico report da consegnare al tuo capo. Cosa c'è di più presentabile alla direzione di un foglio di lavoro?
Non sono necessarie importazioni aggiuntive per l'API Google Sheets e l'unica nuova informazione necessaria è l'ID file di un foglio di lavoro esistente già formattato e in attesa di una nuova riga di dati, da cui la costante SHEET. Ti consigliamo di creare un nuovo foglio di lavoro simile al seguente:

L'URL del foglio di lavoro sarà simile al seguente: https://docs.google.com/spreadsheets/d/FILE_ID/edit. Prendi FILE_ID e assegnalo come sting a SHEET.
Abbiamo anche inserito una piccola funzione chiamata k_ize() che converte i byte in kilobyte, definendola come lambda Python, poiché si tratta di una semplice funzione di una riga. Entrambe queste costanti integrate con le altre hanno il seguente aspetto:
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
Come nei passaggi precedenti, abbiamo bisogno di un altro ambito di autorizzazione, questa volta di lettura/scrittura per l'API Sheets. Ora SCOPES ha tutti e quattro i requisiti necessari:
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',
)
Ora crea un endpoint di servizio per Fogli Google vicino agli altri, in modo che abbia il seguente aspetto:
# 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)
La funzionalità di sheet_append_row() è semplice: prendi una riga di dati e l'ID di un foglio, poi aggiungi la riga a quel foglio:
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')
La chiamata spreadsheets().values().append() richiede l'ID file del foglio, un intervallo di celle, la modalità di inserimento dei dati e i dati stessi. L'ID file è semplice, l'intervallo di celle è indicato nella notazione A1. Un intervallo di "Sheet1" indica l'intero foglio, il che segnala all'API di aggiungere la riga dopo tutti i dati del foglio. Esistono due opzioni su come aggiungere i dati al foglio: "RAW" (inserisci i dati della stringa letteralmente) o "USER_ENTERED" (scrivi i dati come se un utente li avesse inseriti sulla tastiera con l'applicazione Fogli Google, conservando le funzionalità di formattazione delle celle).
Se la chiamata ha esito positivo, il valore restituito non è particolarmente utile, quindi abbiamo scelto di ottenere il numero di celle aggiornate dalla richiesta API. Di seguito è riportato il codice che chiama la funzione:
# 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')
Il foglio Google ha colonne che rappresentano dati come qualsiasi "sottodirectory" principale, la posizione del file archiviato su Cloud Storage (bucket + nome file), il tipo MIME del file, le dimensioni del file (originariamente in byte, ma convertite in kilobyte con k_ize()) e la stringa delle etichette Cloud Vision. Tieni presente inoltre che la posizione archiviata è un collegamento ipertestuale, quindi il tuo manager può fare clic per confermare che è stato eseguito il backup in modo sicuro.
Aggiungendo il blocco di codice riportato sopra subito dopo la visualizzazione dei risultati di Cloud Vision, la parte principale che guida l'app è ora completa, anche se strutturalmente un po' complessa:
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)
L'eliminazione di storage.json un'ultima volta e la nuova esecuzione dell'applicazione aggiornata dovrebbero generare un output simile al seguente, in cui è stata aggiunta l'analisi di 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
La riga di output aggiuntiva, sebbene utile, viene visualizzata meglio dando un'occhiata al foglio Google aggiornato, con l'ultima riga (riga 7 nell'esempio riportato di seguito) aggiunta al set di dati esistente aggiunto in precedenza:

Riepilogo
Nei primi tre passaggi di questo tutorial, hai eseguito la connessione alle API di Google Workspace e Google Cloud per spostare i dati e analizzarli, completando l'80% del lavoro. Tuttavia, alla fine della giornata, tutto questo non significa nulla se non riesci a presentare alla direzione tutto ciò che hai realizzato. Per visualizzare meglio i risultati, riassumere tutti i risultati in un report generato è molto utile.
Per migliorare ulteriormente l'utilità dell'analisi, oltre a scrivere i risultati in un foglio di lavoro, un possibile miglioramento potrebbe essere quello di indicizzare queste 5 etichette principali per ogni immagine in modo da poter creare un database interno che consenta ai dipendenti autorizzati di eseguire query per immagini in base al team di ricerca, ma lasciamo questo compito ai lettori.
Per il momento, i nostri risultati sono in un foglio e accessibili alla direzione. Il codice della tua app in questa fase dovrebbe corrispondere a quello presente nel repository all'indirizzostep4-sheets/analyze_gsimg.py. Il passaggio finale consiste nel ripulire il codice e trasformarlo in uno script utilizzabile.
12. *Ultimo passaggio: refactoring
(facoltativo) È bene avere un'app funzionante, ma possiamo migliorarla? Sì, soprattutto l'applicazione principale, che sembra un caos. Inseriamo questa logica in una funzione separata e consentiamo l'input dell'utente anziché costanti fisse. Lo faremo con il modulo argparse. Inoltre, avviamo una scheda del browser web per visualizzare il foglio una volta scritta la riga di dati. È possibile farlo con il modulo webbrowser. Combina queste importazioni con le altre in modo che le prime importazioni siano simili a queste:
from __future__ import print_function
import argparse
import base64
import io
import webbrowser
Per poter utilizzare questo codice in altre applicazioni, dobbiamo essere in grado di eliminare l'output, quindi aggiungiamo un flag DEBUG per farlo, aggiungendo questa riga alla fine della sezione delle costanti nella parte superiore:
DEBUG = False
Ora, parliamo del corpo principale. Durante la creazione di questo esempio, dovresti aver iniziato a sentirti "a disagio" man mano che il nostro codice aggiunge un altro livello di nidificazione a ogni servizio aggiunto. Se la pensi così, non sei solo, perché questo aumenta la complessità del codice, come descritto in questo post del blog di Google Testing.
Seguendo questa best practice, riorganizziamo la parte principale dell'app in una funzione e return in ogni "punto di interruzione" anziché nidificare (restituendo None se un passaggio non va a buon fine e True se tutti vanno a buon fine):
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
È più ordinato e pulito, lasciando alle spalle la sensazione di catena ricorsiva if-else e riducendo la complessità del codice come descritto sopra. L'ultimo pezzo del puzzle è creare un "vero" driver principale, consentendo la personalizzazione da parte dell'utente e riducendo al minimo l'output (se non desiderato):
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)
Se tutti i passaggi hanno esito positivo, lo script avvia un browser web nel foglio di lavoro specificato in cui è stata aggiunta la nuova riga di dati.
Riepilogo
Non è necessario eliminare storage.json perché non sono state apportate modifiche all'ambito. Se esegui di nuovo l'applicazione aggiornata, si apre una nuova finestra del browser con il foglio modificato, meno righe di output e l'emissione di un'opzione -h mostra agli utenti le loro opzioni, tra cui -v per ripristinare le righe di output ora eliminate visualizzate in precedenza:
$ 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
Le altre opzioni consentono agli utenti di scegliere nomi di file di Drive, nomi di "sottodirectory" e bucket Cloud Storage, i primi "N" risultati di Cloud Vision e ID file di fogli di lavoro (Sheets). Con questi ultimi aggiornamenti, la versione finale del codice dovrebbe ora corrispondere a quella presente nel repository all'indirizzofinal/analyze_gsimg.py, nonché qui, nella sua interezza:
'''
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)
Faremo ogni tentativo per mantenere aggiornato il contenuto di questo tutorial, ma in alcuni casi il repository conterrà la versione più recente del codice.
13. Complimenti!
In questo codelab hai imparato molte cose e sei riuscito a completarlo, superando uno dei codelab più lunghi. Di conseguenza, hai affrontato un possibile scenario aziendale con circa 130 righe di Python, sfruttando Google Cloud e Google Workspace e spostando i dati tra loro per creare una soluzione funzionante. Non esitare a esplorare il repository open source per tutte le versioni di questa app (maggiori informazioni di seguito).
Esegui la pulizia
- L'utilizzo delle API Google Cloud non è senza costi, mentre le API Google Workspace sono coperte dalla tariffa mensile dell'abbonamento a Google Workspace (gli utenti di Gmail consumer hanno una tariffa mensile pari a zero), quindi non è necessaria alcuna pulizia/ritiro delle API per gli utenti di Google Workspace. Per Google Cloud, puoi andare alla dashboard della console Cloud e controllare la "scheda" Fatturazione per gli addebiti stimati.
- Per Cloud Vision, è consentito un numero fisso di chiamate API al mese senza costi. Quindi, finché rispetti questi limiti, non è necessario chiudere nulla né disattivare/eliminare il progetto. Per ulteriori informazioni sulla fatturazione e sulla quota senza costi dell'API Vision, consulta la pagina dei prezzi.
- Alcuni utenti di Cloud Storage ricevono una quantità senza costi di spazio di archiviazione al mese. Se le immagini che archivi utilizzando questo codelab non ti fanno superare la quota, non ti verranno addebitati costi. Per ulteriori informazioni sulla fatturazione e sulla quota senza costi di GCS, consulta la pagina dei prezzi. Puoi visualizzare ed eliminare facilmente i blob dal browser Cloud Storage.
- Anche il tuo utilizzo di Google Drive potrebbe avere una quota di spazio di archiviazione e, se la superi (o ti avvicini), potresti prendere in considerazione l'utilizzo dello strumento che hai creato in questo codelab per archiviare le immagini in Cloud Storage e avere più spazio su Drive. Per ulteriori informazioni sullo spazio di archiviazione di Google Drive, consulta la pagina dei prezzi appropriata per gli utenti di Google Workspace Basic o di Gmail/consumer.
Sebbene la maggior parte dei piani Google Workspace Business ed Enterprise disponga di spazio di archiviazione illimitato, ciò potrebbe causare l'ingombro e/o la confusione delle cartelle di Drive. L'app che hai creato in questo tutorial è un ottimo modo per archiviare i file estranei e fare pulizia in Google Drive.
Versioni alternative
Anche se final/analyze_gsimg.py è l'ultima versione ufficiale su cui lavorerai in questo tutorial, non è la fine della storia. Un problema con la versione finale dell'app è che utilizza le librerie di autenticazione precedenti, che sono state ritirate. Abbiamo scelto questo percorso perché, al momento della stesura di questo articolo, le librerie di autenticazione più recenti non supportavano diversi elementi chiave: la gestione dell'archiviazione dei token OAuth e la sicurezza dei thread.
Librerie di autenticazione attuali (più recenti)
Tuttavia, a un certo punto, le librerie di autenticazione precedenti non saranno più supportate, pertanto ti consigliamo di esaminare le versioni che utilizzano le librerie di autenticazione più recenti (attuali) nella cartella alt del repository anche se non sono thread-safe (ma puoi creare una tua soluzione che lo sia). Cerca i file con *newauth* nel nome.
Librerie client di Google Cloud product
Google Cloud consiglia a tutti gli sviluppatori di utilizzare le librerie client del prodotto quando utilizzano le API Google Cloud. Purtroppo, al momento le API non Google Cloud non dispongono di queste librerie. L'utilizzo delle librerie di livello inferiore consente un utilizzo coerente delle API e una migliore leggibilità. Analogamente al suggerimento precedente, le versioni alternative che utilizzano le librerie client dei prodotti Google Cloud sono disponibili nella cartella alt del repository per la revisione. Cerca i file con *-gcp* nel nome.
Autorizzazione tramite service account
Quando si lavora esclusivamente nel cloud, in genere non sono presenti persone né dati di proprietà di utenti (umani), pertanto gli account di servizio e l'autorizzazione dell'account di servizio vengono utilizzati principalmente con Google Cloud. Tuttavia, i documenti Google Workspace sono generalmente di proprietà di utenti (umani), quindi questo tutorial utilizza l'autorizzazione dell'account utente. Ciò non significa che non sia possibile utilizzare le API Google Workspace con i service account. Se questi account hanno il livello di accesso appropriato, possono essere utilizzati nelle applicazioni. Analogamente a quanto sopra, le versioni alternative che utilizzano l'autorizzazione del service account sono disponibili nella cartella alt del repository per la revisione. Cerca i file con *-svc* nel nome.
Catalogo delle versioni alternative
Di seguito sono riportate tutte le versioni alternative di final/analyze_gsimg.py, ognuna delle quali presenta una o più delle proprietà sopra indicate. Nel nome file di ogni versione, cerca:
- "
oldauth" per le versioni che utilizzano le librerie di autenticazione precedenti (oltre afinal/analyze_gsimg.py) - "
newauth" per chi utilizza le librerie di autenticazione attuali/più recenti - "
gcp" per chi utilizza le librerie client dei prodotti Google Cloud, ad esempio google-cloud-storage e così via. - "
svc" per chi utilizza l'autenticazione di un account di servizio ("svc acct") anziché un account utente
Ecco tutte le versioni:
Nome file | Descrizione |
| L'esempio principale, che utilizza le librerie di autenticazione precedenti |
| Come |
| Come |
| Come |
| Come |
| Come |
| Come |
| Come |
Insieme all'final/analyze_gsimg.py originale , hai tutte le combinazioni possibili della soluzione finale, indipendentemente dall'ambiente di sviluppo delle API di Google, e puoi scegliere quella più adatta alle tue esigenze. Consulta anche alt/README.md per una spiegazione simile.
Studio aggiuntivo
Di seguito sono riportate alcune idee su come fare un passo o due in più. Il problema che la soluzione attuale può gestire può essere ampliato, consentendoti di apportare i seguenti miglioramenti:
- (più immagini nelle cartelle) Invece di elaborare una sola immagine, supponiamo di avere immagini in cartelle di Google Drive.
- (Più immagini in file ZIP) Invece di una cartella di immagini, che ne dici di archivi ZIP contenenti file di immagini? Se utilizzi Python, prendi in considerazione il modulo
zipfile. - (analizza le etichette Vision) Raggruppa le immagini simili, magari iniziando a cercare le etichette più comuni, poi le seconde più comuni e così via.
- (crea grafici) Follow-up n. 3, genera grafici con l'API Sheets in base all'analisi e alla classificazione dell'API Vision
- (categorizzare i documenti) Invece di analizzare le immagini con l'API Cloud Vision, supponiamo di avere file PDF da categorizzare con l'API Cloud Natural Language. Utilizzando le soluzioni precedenti, questi PDF possono trovarsi in cartelle di Drive o archivi ZIP su Drive.
- (crea presentazioni) Utilizza l'API Slides per generare una serie di diapositive dai contenuti del report del foglio Google. Per trovare ispirazione, dai un'occhiata a questo post del blog e a questo video sulla generazione di slide a partire dai dati del foglio di lavoro.
- (Esporta come PDF) Esporta il foglio di lavoro e/o il file di Presentazioni come PDF, ma questa non è una funzionalità delle API Fogli o Presentazioni. Suggerimento: API Google Drive. Punti extra: unisci i PDF di Fogli e Presentazioni in un unico PDF principale con strumenti come Ghostscript (Linux, Windows) o
Combine PDF Pages.action(Mac OS X).
Scopri di più
Codelab
- Introduzione alle API Google Workspace (API Google Drive) (Python)
- Utilizzo di Cloud Vision con Python (Python)
- Creare strumenti di reporting personalizzati (API Google Sheets) (JS/Node)
- Carica oggetti in Google Cloud Storage (non è richiesta alcuna codifica)
Generale
Google Workspace
- Home page dell'API Google Drive
- Home page dell'API Google Sheets
- Panoramica e documentazione per gli sviluppatori di Google Workspace
Google Cloud
- Home page di Google Cloud Storage
- Home page e demo dal vivo di Google Cloud Vision
- Documentazione dell'API Cloud Vision
- Documenti sull'etichettatura delle immagini dell'API Vision
- Python su Google Cloud
- Librerie client dei prodotti Google Cloud
- Documentazione di Google Cloud
Licenza
Questo lavoro è concesso in licenza ai sensi di una licenza Creative Commons Attribution 2.0 Generic.