Geração de relatórios, análise e geração de relatórios com o G Suite e o GCP

Esse codelab simula um possível fluxo de trabalho corporativo: arquivamento de imagens, análises e geração de relatórios. Imagine que sua organização tenha uma série de imagens ocupando espaço em um recurso restrito. Você quer arquivar esses dados, analisar essas imagens e, o mais importante, gerar um relatório resumindo os locais arquivados e os resultados da análise, agrupados e prontos para consumo pelo gerenciamento. O Google Cloud oferece as ferramentas para que isso aconteça, usando APIs de duas linhas de produtos, G Suite e Google Cloud Platform (GCP).

No nosso cenário, o usuário da empresa terá imagens no Google Drive. É recomendável fazer backup dessas informações para "armazenamento mais antigo", como as classes de armazenamento disponíveis no Google Cloud Storage. O Google Cloud Vision permite que os desenvolvedores integrem facilmente recursos de detecção de visão nos aplicativos, incluindo detecção de objetos e pontos de referência, reconhecimento ótico de caracteres (OCR) etc. Por fim, uma planilha do ( Planilhas Google). é uma ferramenta de visualização útil para resumir tudo isso para seu chefe.

Depois de concluir este codelab para criar uma solução que aproveite todo o Google Cloud, esperamos que você tenha inspiração para criar algo ainda mais relevante para sua organização ou seus clientes.

O que você aprenderá

  • Como usar o Cloud Shell
  • Como autenticar solicitações de API
  • Como instalar a biblioteca de cliente das APIs do Google para Python
  • Como ativar as APIs do Google
  • Como fazer o download de arquivos do Google Drive
  • Como fazer upload de objetos/blobs no Cloud Storage
  • Como analisar dados com o Cloud Vision
  • Como gravar linhas no Planilhas Google

Pré-requisitos

  • Uma Conta do Google (as contas do G Suite podem exigir a aprovação do administrador).
  • Um projeto do Google Cloud Platform com uma conta de faturamento do GCP ativa
  • Familiaridade com comandos de terminal/shell do sistema operacional
  • Habilidades básicas em Python (2 ou 3), mas você pode usar qualquer linguagem compatível

Ter experiência com os quatro produtos do Google Cloud listados acima seria útil, mas não obrigatório. Se você tiver tempo para se familiarizar com eles separadamente, fique à vontade para fazer codelabs para cada um deles antes de fazer o exercício aqui:

Pesquisa

Como você usará este tutorial?

Apenas leitura Leitura e exercícios

Como você classificaria sua experiência com o Python?

Iniciante Intermediário Proficiente

Como você classificaria sua experiência com o uso dos serviços do Google Cloud Platform?

Iniciante Intermediário Proficiente

Como você classificaria sua experiência com o uso dos serviços para desenvolvedores do G Suite?

Iniciante Intermediário Proficiente

Você gostaria de ver mais codelabs "orientados a empresas" do que os relativos à introdução de recursos do produto?

Sim Não Mais dos dois

Configuração de ambiente personalizada

  1. Faça login no Console do Cloud e crie um novo projeto ou reutilize um existente. Crie uma se você ainda não tiver uma conta do Gmail ou do G Suite.

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

Lembre-se do código do projeto, um nome exclusivo em todos os projetos do Google Cloud. O nome acima já foi escolhido e não servirá para você. Faremos referência a ele mais adiante neste codelab como PROJECT_ID.

  1. Em seguida, será necessário ativar o faturamento no Console do Cloud para usar os recursos do Google Cloud.

A execução deste codelab não será muito cara, se for o caso. Siga todas as instruções na seção "Limpeza", que orienta você sobre como encerrar recursos para não incorrer em cobranças além deste tutorial. Novos usuários do Google Cloud estão qualificados para o programa de avaliação gratuita de US$ 300.

Iniciar Cloud Shell

Resumo

Embora você possa desenvolver o código localmente em seu laptop, um objetivo secundário deste codelab é ensinar como usar o Google Cloud Shell, um ambiente de linha de comando executado na nuvem por meio de seu navegador da web moderno.

Ativar o Cloud Shell

  1. No Console do Cloud, clique em Ativar o Cloud ShellH7JlbhKGHITmsxhQIcLwoe5HXZMhDlYue4K-SPszMxUxDjIeWfOHBfxDHYpmLQTzUmQ7Xx8o6OJUlANnQF0iBuUyfp1RzVad_4nCa0Zz5LtwBlUZFXFCWFrmrWZLqg1MkZz2LdgUDQ.

zlNW0HehB_AFW1qZ4AyebSQUdWm95n7TbnOr7UVm3j9dFcg6oWApJRlC0jnU1Mvb-IQp-trP1Px8xKNwt6o3pP6fyih947sEhOFI4IRF0W7WZk6hFqZDUGXQQXrw21GuMm2ecHrbzQ

Se você nunca tiver iniciado o Cloud Shell, verá uma tela intermediária (abaixo da dobra) com a descrição do que ele é. Se esse for o caso, clique em Continuar e você não o verá novamente. Esta é uma tela única:

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

Leva apenas alguns instantes para provisionar e se conectar ao Cloud Shell.

pTv5mEKzWMWp5VBrg2eGcuRPv9dLInPToS-mohlrqDASyYGWnZ_SwE-MzOWHe76ZdCSmw0kgWogSJv27lrQE8pvA5OD6P1I47nz8vrAdK7yR1NseZKJvcxAZrPb8wRxoqyTpD-gbhA

Essa máquina virtual contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Praticamente todo o seu trabalho neste codelab pode ser feito em um navegador ou no seu Chromebook.

Depois de se conectar ao Cloud Shell, você já estará autenticado e o projeto já estará configurado com seu ID do projeto.

  1. Execute o seguinte comando no Cloud Shell para confirmar que você está autenticado:
gcloud auth list

Resposta ao comando

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

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

Resposta ao comando

[core]
project = <PROJECT_ID>

Se o projeto não estiver configurado, faça a configuração usando este comando:

gcloud config set project <PROJECT_ID>

Resposta ao comando

Updated property [core/project].

Esse codelab requer o uso da linguagem Python (embora muitas linguagens sejam compatíveis pelas bibliotecas cliente das APIs do Google, portanto, sinta-se à vontade para criar algo equivalente em sua ferramenta de desenvolvimento favorita e simplesmente usar o Python como pseudocódigo). Esse codelab é compatível com o Python 2 e 3, mas recomendamos migrar para o 3.x assim que possível.

O Cloud Shell é uma conveniência disponível para usuários do Console do Cloud e não requer um ambiente de desenvolvimento local. Portanto, esse tutorial pode ser feito na nuvem com um navegador da Web. O Cloud Shell será útil principalmente se você estiver desenvolvendo ou planejando continuar com os produtos e as APIs do GCP. Mais especificamente para este codelab, o Cloud Shell já instalou as duas versões do Python.

O Cloud Shell também tem o IPython instalado... é um interpretador Python de nível superior que recomendamos, especialmente se você fizer parte da comunidade de ciência de dados ou machine learning. Se você estiver, o IPython é o interpretador padrão para o Jupyter Notebooks e o Colab, os notebooks do Jupyter hospedados pelo Google Research.

O IPython favorece um interpretador do Python 3 primeiro, mas retorna para o Python 2, caso 3.x não esteja disponível. O IPython pode ser acessado no Cloud Shell, mas também pode ser instalado em um ambiente de desenvolvimento local. Saia com ^D (Ctrl-d) e aceite a oferta para sair. A saída de exemplo de ipython terá esta aparência:

$ 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 não for sua preferência, o uso de um interpretador interativo padrão do Python (o Cloud Shell ou seu ambiente de desenvolvimento local) é perfeitamente aceitável (também saia com ^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.
>>>

O codelab também pressupõe que você tenha a ferramenta de instalação pip (gerenciador de pacotes Python e resolvedor de dependências). Ele vem com as versões 2.7.9 ou superiores ou 3.4+. Se você tiver uma versão mais antiga do Python, consulte este guia para ver instruções de instalação. Dependendo das suas permissões, talvez seja necessário ter sudo ou acesso de superusuário, mas esse não é o caso. Também é possível usar explicitamente pip2 ou pip3 para executar pip para versões específicas do Python.

O restante do codelab considera que você está usando o Python 3. Instruções específicas serão fornecidas para o Python 2 se forem muito diferentes de 3.x.

*Crie e use ambientes virtuais

Esta seção é opcional e só é necessária para as pessoas que devem usar um ambiente virtual para este codelab (conforme a barra lateral de aviso acima). Se você tiver apenas o Python 3 no seu computador, basta emitir este comando para criar um virtualenv chamado my_env (você pode escolher outro nome, se quiser):

virtualenv my_env

No entanto, se você tiver o Python 2 e o 3 no computador, recomendamos instalar um virtualenv Python 3, que você pode fazer com o -p flag da seguinte maneira:

virtualenv -p python3 my_env

Insira o virtualenv recém-criado "ativando" assim:

source my_env/bin/activate

Para confirmar que você está no ambiente, observe que o prompt do shell agora está precedido pelo nome do seu ambiente, ou seja,

(my_env) $

Agora, você deverá ser capaz de pip install quaisquer pacotes necessários, executar o código nessa e assim por diante etc. Outro benefício é que, se você expuser o conteúdo completamente, entrar em uma situação em que a instalação do Python esteja corrompida etc., poderá explodir esse ambiente inteiro sem afetar o restante do sistema.

Esse codelab requer o uso da biblioteca de cliente de APIs do Google para Python. Portanto, é um processo de instalação simples ou você não precisa fazer nada.

Recomendamos que você use o Cloud Shell por conveniência. É possível concluir todo o tutorial em um navegador da Web na nuvem. Outro motivo para usar o Cloud Shell é que muitas ferramentas de desenvolvimento conhecidas e as bibliotecas necessárias já estão pré-instaladas.

Instalar bibliotecas de cliente

(opcional): é possível pular essa etapa se você estiver usando o Cloud Shell ou um ambiente local onde já instalou as bibliotecas de cliente. Só será necessário fazer isso se você estiver desenvolvendo localmente e não tiver instalado (ou tiver certeza). A maneira mais fácil é usar pip (ou pip3) para fazer a instalação (incluindo a atualização de pip se necessário):

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

Confirmar instalação

Esse comando instala a biblioteca de cliente e os pacotes de que ela depende. Se você está usando o Cloud Shell ou seu próprio ambiente, verifique se a biblioteca de cliente está instalada importando os pacotes necessários e confirme se não há erros de importação (ou saída):

python3 -c "import googleapiclient, httplib2, oauth2client"

Se você usar o Python 2 no Cloud Shell, verá um aviso de que o uso dele foi suspenso:

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

Agora que você pode executar o comando "test" de importação (sem erros/saída), estará pronto para começar a falar com as APIs do Google.

Resumo

Como este é um codelab intermediário, você presume que já tem experiência na criação e no uso de projetos no console. Se você nunca usou as APIs do Google e as APIs do G Suite, consulte o codelab de introdução às APIs do G Suite. Além disso, se você souber como criar (ou reutilizar as já existentes)conta de usuário (exceto conta de serviço ), solte aclient_secret.json no diretório de trabalho, pular o próximo módulo e pular para "Ativar APIs do Google".

Você pode pular esta seção se já tiver criado as credenciais de autorização da conta de usuário e estiver familiarizado com o processo. Isso é diferente da autorização da conta de serviço cuja técnica é diferente. Continue abaixo.

Introdução à autorização (além de alguma autenticação)

Para fazer solicitações às APIs, seu aplicativo precisa ter a autorização adequada. Autenticação, uma palavra semelhante, descreve credenciais de login. Você se autentica ao fazer login na sua Conta do Google com um login e uma senha. Após a autenticação, a próxima etapa é seu código é autorizado para acessar dados, como arquivos blob no Cloud Storage ou os arquivos pessoais de um usuário no Google Drive.

As APIs do Google permitem vários tipos de autorização, mas o mais comum para os usuários da API G Suite é a autorização do usuário, porque o aplicativo de exemplo neste codelab acessa dados pertencentes a usuários finais. Esses usuários finais precisam permitir que seu app acesse os dados. Isso significa que seu código precisa receber as credenciais do OAuth2 da conta de usuário.

Para obter as credenciais do OAuth2 para autorização do usuário, volte para o gerenciador de API e selecione a guia "Credenciais" no painel de navegação à esquerda:

Y33PZ_rJC1y7NH7Rrvq1kN_WxZ9CppDGJK8tTSaha298Jlm5pMqgnyweIO4oX34fcLy0_VI4gihYu5wpEM_LeJg1iDAFoidhUVyfqJX3QTzODQ_OGjHLXYBxPpUvihCJi9JGwvMREw

Quando chegar lá, você verá todas as suas credenciais em três seções separadas:

ComE4qh76dwZbIehkDUm1QawHGia_qVe7w7rkmgbeo_wjWS--kqXCt4_zvm55iy_RXA8dKYKvBxIKazkcYQ8871SA_kNslbvum_n1Ju4k9qJJSMtDhPAnofcvIlqlKm1nu7PBQhmEg

O primeiro é para chaves de API, os dois IDs de cliente do OAuth 2.0 e as últimas contas de serviço do OAuth2,que são usadas no do meio.

Como criar credenciais

Na página "Credenciais", clique no botão + Criar credenciais na parte superior. Você verá uma caixa de diálogo em que escolheria "ID do cliente OAuth":

C7jTddfrczo3GewPGCxbxX13GawtFc6FGvAPFusPc_IW-tr5M6xgXd1OzOHOUTo86WDa9fXiCITogv9b3wAgOcYM7xS3AmVNaPdTxbAynIe_sia2_x3LEPsBrdbX8NjeI2WaHRioOA

Na tela seguinte, você tem duas ações: configurar a "tela de consentimento" de autorização do seu aplicativo e escolher o tipo de aplicativo:

El9_aqPQ6Q9hOsOp3JUC5qnCm_A_BVI-oCEfPk_MsvybnWBmC5lT6CtXSoZ7EQoFzrcBEzo4zF9s8CbhXyo0e-eSY3pZ1zg0BRvT0YssMMhbzEG-gP_jiO8v9q9HYTjg-QW5jJ0RDA

Se você não definiu uma tela de consentimento, verá o aviso no console e precisará fazer isso agora. (Ignore esta etapa se a tela de consentimento já tiver sido configurada.)

Clique em "Configurar tela de consentimento" ao selecionar um aplicativo "Externo" (ou "Interno", se você for cliente do G Suite):

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

Para este exercício, não importa qual você escolher, porque você não está publicando seu exemplo de codelab. A maioria das pessoas seleciona a opção "Externo" para acessar uma tela mais complexa. No entanto, você só precisa preencher o campo "Nome do aplicativo" na parte superior:

8e9z_RQz8lumYbDIcBvm57_Gpptn9uhrVQHoRzJ01AJNOFmXloDO7Eg3hhzJZZIU2F5rR0MxTCw-oXVFCq683xUwD4O33pXeuFsOMtM8EZhyjDoYc8Kv4hEoaG0Ztq9ePx6De7YmfA

Agora, você só precisa do nome de um aplicativo. Escolha alguém que reflita o codelab que você está fazendo e clique em Salvar.

Como criar um ID do cliente OAuth (autenticação de conta de usuário)

Volte para a guia "Credenciais" para criar um ID do cliente do OAuth2. Aqui você verá vários IDs de cliente OAuth que podem ser criados:

f8reuhsxOUNLcVrEIyRVsmP_fX_ceIlLvEKql1YHwSPW9jk9Mm9fJ0UlfUoi8eRN3QQXar4xtpo071zj6LSczNN7TYY8zB96Dn6ICZuvCAtjIgJSKdMSlX-ZhMuSWFpxxv661aUemw

Estamos desenvolvendo uma ferramenta de linha de comando, que é Outro. Portanto, escolha essa opção e clique no botão Criar. Escolha o nome de um ID de cliente que reflita o aplicativo que você está criando ou simplesmente use o nome padrão, que geralmente é "Outro cliente N".

Salvar suas credenciais

  1. Será exibida uma caixa de diálogo com as novas credenciais. Clique em OK para fechar.

rAwekj_GNEuVwGbZOYYlGDQjlu4flE61OPEZIUmwMI5vGi3W365UwVCxi0mVNhg4WZSSczZywrZZ6NDM_U0FJ4b-TOIMEC189uybOJjgn8F_axesVMopel9RlehRBXdEFhN4d41WGQ

  1. Na página "Credenciais", role para baixo até a seção "IDs de cliente do OAuth2" e clique no ícone de download aAmje6kT_xSUM4BKIlPREpjosx7C_xxwpWqBgiGVfVWxQ8nnQOfxTPhuU0QwSnmbjykZffGrqyP1nnKrEQ7D7OqYaGw_Uzscs9gX2RwwP4AmvtHIiTFLa0gkprzJSjG9pQSx7HtmSQ, na parte inferior direita do seu ID do cliente recém-criado. x-vb-sKZy-X8a1X4uTsBWotSd4wn0PGt4mHMNv6DUrq5J5ihpujUyTiIVr5SHw0p2ZDy0KTP-zqOaFX-Az9BYDWG90KNFmsRLTUOo1mUVk7dYRJiK3VwYJNU0bbxjsbbpqcTr5_oLw
  2. Isso abre uma caixa de diálogo para salvar um arquivo chamado client_secret-LONG-HASH-STRING.apps.googleusercontent.com.json, provavelmente na pasta Downloads. Recomendamos encurtar para um nome mais fácil, como client_secret.json, que é o que o app de exemplo usa. Em seguida, salve-o no diretório/pasta em que você criará o app de amostra neste codelab.

Resumo

Agora você já pode ativar as APIs do Google usadas neste codelab. Além disso, para o nome do aplicativo na tela de consentimento do OAuth, escolhemos "Demonstração da API Vision". Por isso, esperamos ver em algumas das capturas de tela a seguir.

Introdução

Este codelab usa quatro (4) APIs do Google Cloud, um par do GCP (Cloud Storage e Cloud Vision) e outro par do G Suite (Google Drive e Planilhas Google). Veja abaixo as instruções para ativar apenas a API Vision. Quando você souber como ativar uma API, precisará ativar as outras três por conta própria.

Antes de começar a usar as APIs do Google, você precisa ativá-las. No exemplo abaixo, mostramos o que você faria para ativar a API Cloud Vision. Neste codelab, você pode estar usando uma ou mais APIs e deve seguir etapas semelhantes para ativá-las antes do uso.

No Cloud Shell

Com o Cloud Shell, é possível ativar a API com o seguinte comando:

gcloud services enable vision.googleapis.com

No Console do Cloud

Você também pode ativar a API Vision no Gerenciador de API. No Console do Cloud, acesse o Gerenciador de APIs e selecione "Biblioteca".

mg03by3QV6kco0rVVV_8IA6VobAoMG4Yoyl-PofNM0dHK8IcoDmpoLUwWeiKFFjpxHWlS1td5-0n7kNkfqHVhSsTSW_hUMvRu3D72g3LCFb7u4v4bla_Z4XyonTVK8PpigMLJcE01g

Na barra de pesquisa, comece a digitar "vision" e selecione a API Vision quando ela aparecer. Ao digitar, você pode ter esta aparência:

B6fWWsVhymufgQx6oGIq4sgukK6JQ1VoguVOrSNf_anQb6Cv6RTLtsjx5Qdeu3-uO8-8PyqwZLYdDDjYW5o56R47cnsd_88RKTMqNkpFeDESW2hmBM_7FK2UAMz1_216yXERYSp_JA

Selecione a API Cloud Vision para acessar a caixa de diálogo que aparece abaixo e clique no botão "Ativar":

D-MONPLi0UWH6Dp607Dod6JF-LJQZIiUQEPQNKM4Y0mSt09KfipbeeXRAE6cokArBYTfL9VQoONc4L0jlnsUYLsNytQIPfSKr9lCDrXmrrx-1w64LeWWa-byDxcyYWZdCI0mAcVzBw

Custo

Muitas APIs do Google podem ser usadas sem taxas, mas o uso de GCP (produtos e APIs) não é gratuito. Ao ativar a API Vision (conforme descrito acima), você será solicitado a fornecer uma conta de faturamento ativa. As informações de preços da API Vision precisam ser referenciadas pelo usuário antes da ativação. Lembre-se de que determinados produtos do Google Cloud Platform (GCP) têm um nível "Sempre gratuito" que você precisa exceder para incorrer no faturamento. Para os fins do codelab, cada chamada para a API do Vision é contabilizada nesse nível gratuito. Desde que você permaneça dentro dos limites agregados (em cada mês), não haverá cobranças.

Algumas APIs do Google, por exemplo, O G Suite tem o uso coberto por uma assinatura mensal, por isso não há cobrança direta para o uso das APIs Gmail, Google Drive, Agenda, Documentos, Planilhas e Apresentações, por exemplo. Diferentes produtos do Google são cobrados de maneira diferente. Portanto, consulte a documentação da sua API para obter essa informação.

Resumo

Agora que o Cloud Vision foi ativado, ative as outras três APIs (Google Drive, Cloud Storage, Planilhas Google) da mesma forma... no Cloud Shell, use gcloud services enable ou no Console do Cloud:

  1. Voltar para a biblioteca de APIs
  2. Inicie uma pesquisa digitando algumas letras do nome dela
  3. Selecione a API desejada.
  4. Ativar

Ensaboe, enxágue e repita. Para o Cloud Storage, há várias opções. Escolha a "API Google Cloud Storage JSON". A API Cloud Storage também espera uma conta de faturamento ativa.

Este é o começo de uma parte de código de tamanho médio, por isso, queremos um pouco de práticas rápidas e garantir uma infraestrutura comum, estável e funcional antes de processar o aplicativo principal. Verifique se o client_secret.json está disponível no seu diretório atual e na inicialização ipython e insira o seguinte snippet de código ou salve-o em analyze_gsimg.py e execute-o no shell (o último é preferível porque continuaremos adicione à amostra de código):

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)

Esse componente básico inclui blocos de código para importações de módulo/pacote, processamento de credenciais de autenticação de usuário e criação de endpoints de serviço de API. As principais partes do código a serem analisadas:

  • A importação da função print() torna esta amostra compatível com o Python 2-3, e as importações de biblioteca do Google trazem todas as ferramentas necessárias para a comunicação com as APIs do Google.
  • A variável SCOPES representa as permissões a serem solicitadas pelo usuário. Por enquanto, há apenas uma permissão: ler dados do Google Drive.
  • O restante do código de processamento de credenciais é lido nos tokens OAuth2 em cache, possivelmente atualizando para um novo token de acesso com o token de atualização, se o token de acesso original tiver expirado.
  • Se nenhum token tiver sido criado ou se um token de acesso válido for recuperado por outro motivo, o usuário precisará seguir o fluxo de OAuth de três pernas (3LO): criar a caixa de diálogo com permissões solicitadas e solicitar que o usuário a aceite. Depois disso, o aplicativo continua. Do contrário, tools.run_flow() gera uma exceção e a execução é interrompida.
  • Depois que o usuário concede a permissão, um cliente HTTP é criado para se comunicar com o servidor, e todas as solicitações são assinadas com as credenciais do usuário para fins de segurança. Em seguida, um endpoint do serviço para a API Google Drive (versão 3) é criado com esse cliente HTTP e atribuído a DRIVE.

Como executar o aplicativo

Na primeira vez que você executar o script, ele não terá autorização para acessar os arquivos do usuário no Google Drive. O resultado será assim com a execução pausada:

$ 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 você estiver executando no Cloud Shell, pule para a seção "Do Cloud Shell" e role de volta para analisar as telas relevantes em "Do ambiente de desenvolvimento local" quando apropriado.

Do ambiente de desenvolvimento local

O script de linha de comando é pausado quando uma janela do navegador é aberta. Talvez você veja uma página de aviso com aparência assustador:

250b74709b3737dc.png

Essa é uma preocupação legítima, porque você está tentando executar um app que acessa os dados do usuário. Como este é apenas um app de demonstração, e você é o desenvolvedor, esperamos que tenha confiança o suficiente para prosseguir. Para entender melhor, coloque-se no lugar do usuário: é necessário permitir que o código de outra pessoa acesse seus dados. Se você pretende publicar um app como esse, passe pelo processo de verificação para que os usuários não vejam a tela.

Após clicar no link "ir para acessar o aplicativo sem segurança", você verá uma caixa de diálogo de permissões do OAuth2, que tem uma aparência semelhante à mostrada a seguir. Estamos sempre melhorando a interface do usuário, portanto, não se preocupe se ela não corresponder exatamente:

e3e6ef5503b2af1b.png

A caixa de diálogo do fluxo do OAuth2 reflete as permissões que o desenvolvedor está solicitando (por meio da variável SCOPES). Nesse caso, ele pode visualizar e fazer o download a partir do Google Drive do usuário. No código do aplicativo, esses escopos de permissão aparecem como URIs, mas são traduzidos para o idioma especificado pela localidade do usuário. Aqui o usuário precisa conceder autorização explícita para as permissões solicitadas. Caso contrário, uma exceção é lançada, para que o script não prossiga mais.

Você pode até abrir mais uma caixa de diálogo para confirmar sua confirmação:

b91997983fdc1889.png

OBSERVAÇÃO: alguns usam vários navegadores da Web conectados a contas diferentes. Assim, essa solicitação de autorização pode acessar a guia/janela incorreta do navegador, e talvez seja necessário recortar o link desta solicitação em um navegador que esteja conectado com a conta correta.

No Cloud Shell

No Cloud Shell, nenhuma janela do navegador é exibida, deixando você travado. Na parte inferior, você recebeu esta mensagem de diagnóstico:

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

  --noauth_local_webserver

Você terá que pressionar ^C (Ctrl-C ou outro pressionamento de tecla para interromper a execução do script) e executá-lo no seu shell com a sinalização extra. Ao executá-lo dessa forma, você receberá a seguinte resposta:

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

Ignorar o aviso porque sabemos que o storage.json ainda não foi criado e que, de acordo com as instruções em outra guia do navegador com esse URL, você terá uma experiência quase idêntica ao descrito acima em ambientes de desenvolvimento local. (Veja as capturas de tela. acima). Ao final, você verá uma tela final com o código de verificação para inserir no Cloud Shell:

f6da2c335fb7c6a.png

Copie e cole este código na janela do terminal.

Resumo

Além de "Authentication successful", não há resposta adicional. Lembre-se de que isso é apenas a configuração, você ainda não fez nada. O que você concluiu fez com sucesso sua jornada para algo mais probabilidade de ser executado corretamente na primeira vez. A melhor parte é que você solicitou autorização apenas uma vez. Todas as execuções sucessivas pulam porque suas permissões foram armazenadas em cache. Agora, vamos fazer com que o código faça um trabalho real, resultando em uma saída real.

Solução de problemas

Se você receber um erro em vez da resposta, é possível que isso tenha ocorrido por causa de uma ou mais causas:

Na etapa anterior, recomendamos criar o código como analyze_gsimg.py e editá-lo. Também é possível simplesmente cortar e colar tudo diretamente no iPython ou shell padrão do Python. No entanto, é mais trabalhoso, porque continuaremos criando o aplicativo por partes.

Suponha que seu aplicativo tenha sido autorizado e que o endpoint do serviço da API tenha sido criado. Em seu código, ele é representado pela variável DRIVE. Agora vamos encontrar um arquivo de imagem no seu Google Drive e

defina-o como uma variável chamada NAME. Insira o comando a seguir mais uma função drive_get_img() logo abaixo do código da Etapa 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

A coleção files() do Drive tem um método list() que realiza uma consulta (o parâmetro q) do arquivo especificado. O parâmetro fields é usado para especificar em quais valores de retorno você tem interesse. Por que incomodar tudo e diminuir os itens se você não se importar com os outros valores? Se você não conhece bem as máscaras de campo para filtrar valores de retorno da API, confira esta postagem do blog e este vídeo. Caso contrário, execute a consulta e pegue o atributo files retornado, padronizando uma matriz de lista vazia se não houver correspondências.

Se não houver resultados, o restante da função será ignorado e None será retornado (implicita). Caso contrário, pegue a primeira resposta correspondente (rsp[0]), retorne o nome do arquivo, o MIMEtype dele, o carimbo de data/hora da última modificação e, por fim, seu payload binário, recuperado pela função get_media() (por meio do código do arquivo), também na coleção files(). (Os nomes dos métodos podem ser ligeiramente diferentes com outras bibliotecas de cliente da linguagem.)

A parte final é o corpo "principal" que direciona todo o aplicativo:

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)

Ao somar uma imagem chamada section-work-card-img_2x.jpg no Google Drive e definir como FILE, após a execução do script, você verá um resultado confirmando a leitura do arquivo no Google Drive (mas não salvo no seu computador):

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

Solução de problemas

Se você não receber a resposta bem-sucedida, como no exemplo acima, a causa pode ser uma ou mais causas:

Resumo

Nesta seção, você aprendeu como (em duas chamadas de API separadas) se conecta à consulta da API Drive para um arquivo específico e faz o download dele. O caso de uso comercial: arquive seus dados do Drive e analise-os, como ferramentas do GCP. O código do seu aplicativo nesse estágio deve corresponder ao que está no repositório em step1-drive/analyze_gsimg.py.

Leia mais sobre como fazer o download de arquivos no Google Drive aqui ou confira esta postagem de blog e vídeo. Esta parte do codelab é praticamente idêntica a todo o codelab de APIs do G Suite. Em vez de fazer o download de um arquivo, ele mostra os cem primeiros arquivos/pastas no Google Drive do usuário e usa um escopo mais restritivo.

A próxima etapa é adicionar suporte ao Google Cloud Storage. Para isso, é necessário importar outro pacote do Python, io. Certifique-se de que a seção superior das importações agora esteja assim:

from __future__ import print_function
import io

Além do nome de arquivo do Drive, precisamos de informações sobre onde armazenar esse arquivo no Cloud Storage, especificamente o nome do "bucket" em que você pretende colocá-lo e os prefixos "pasta pai". Mais sobre isso em um momento:

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

Uma palavra em buckets... O Cloud Storage fornece armazenamento de blobs morfos. Ao fazer o upload de arquivos nesse arquivo, ele não entende o conceito de tipos de arquivo, as extensões etc., a maneira como o Google Drive faz isso. Eles são apenas "blobs" no Cloud Storage. Além disso, não há um conceito de pastas ou subdiretórios no Cloud Storage.

Sim, há barras (/) nos nomes de arquivos para representar a abstração de várias subpastas. Porém, no fim do dia, todos os blobs entram em um bucket e "/" são apenas caracteres nos nomes de arquivos. Confira a página de convenções de nomenclatura de intervalos e objetos para mais informações.

A etapa 1 acima solicitou o escopo somente leitura do Drive. Na época, isso é tudo o que você precisa. Agora é necessária a permissão para fazer upload (leitura/gravação) no Cloud Storage. Altere SCOPES de uma única variável de string para uma matriz (tuple de Python [ou lista]) de escopos de permissão para que fique assim:

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

Agora, crie um endpoint do serviço para o Cloud Storage logo abaixo do que aparece no Drive. Observe que alteramos levemente a chamada para reutilizar o mesmo objeto cliente HTTP, já que não há necessidade de criar um novo quando ele puder ser um recurso compartilhado.

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

Agora, adicione esta função (após drive_get_img()) que seja carregada no 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()

A chamada objects.().insert() requer o nome do bucket, os metadados do arquivo e o próprio blob binário. Para filtrar os valores de retorno, a variável fields solicita apenas os nomes de bucket e de objeto retornados da API. Para saber mais sobre essas máscaras de campo em solicitações de leitura da API, confira esta postagem e o vídeo.

Agora integre o uso de gcs_blob_upload() no aplicativo principal:

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

A variável gcsname mescla os nomes de "subdiretórios pai" anexados com o próprio nome de arquivo e, quando prefixado com o nome do bucket, concede a impressão que você está arquivando o arquivo em "/bucket/parent.../filename". Ajuste esse bloco logo depois da primeira função print() logo acima da cláusula else para que todo o "principal" fique assim:

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)

Digamos que nós especifiquemos um bucket chamado "vision-demo" com "analyzed_imgs" como um "diretório pai". Depois de definir essas variáveis e executar o script novamente, section-work-card-img_2x.jpg será transferido do Drive para o Cloud Storage, certo? NÃO!

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

Observe que, durante o download do Google Drive, o upload para o Cloud Storage falhou. Por quê?

Isso acontece quando autorizamos esse aplicativo originalmente para a Etapa 1, autorizamos apenas o acesso somente leitura ao Google Drive. Adicionamos o escopo de leitura e gravação ao Cloud Storage, mas o usuário não precisa autorizar esse acesso. Para que isso funcione, precisamos remover o arquivo storage.json que não tem este escopo e ser executado novamente.

Após autorizar novamente e confirmar a operação dentro de storage.json, você verá a seguinte resposta:

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

Resumo

Esse é um resultado importante que mostra, em poucas linhas de código, como transferir arquivos entre os dois sistemas de armazenamento com base na nuvem. O caso de uso empresarial aqui é fazer backup de um recurso possivelmente restrito para um armazenamento mais antigo, conforme mencionado anteriormente. O Cloud Storage oferece diferentes classes de armazenamento dependendo se você acessa seus dados regularmente, mensais, trimestrais ou anuais.

É claro que os desenvolvedores perguntam periodicamente por que o Google Drive e o Cloud Storage existem. Afinal, eles não são armazenamentos de arquivos na nuvem? Por isso, criamos este vídeo. Seu código nesse estágio deve corresponder ao que está no repositório em step2-gcs/analyze_gsimg.py.

Sabemos que agora é possível mover dados entre o GCP e o G Suite, mas ainda não fizemos nenhuma análise. Portanto, é hora de enviar a imagem ao Cloud Vision para anotações de rótulos ou a detecção de objetos. Para isso, precisamos codificar os dados em Base64, o que significa outro módulo Python, base64. A seção de importação superior deve ter esta aparência:

from __future__ import print_function
import base64
import io

Por padrão, a API Vision retorna todos os rótulos encontrados. Para manter a consistência, vamos solicitar os cinco principais itens (ajustáveis pelo usuário, claro). Usaremos uma variável constante TOP para isso. adicione-o a todas as outras constantes:

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

Como nos passos anteriores, precisamos de outro escopo de permissão, desta vez para a API Vision. Atualize SCOPES com a string dela:

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

Agora, crie um endpoint de serviço para o Cloud Vision para que ele se alinhe aos demais:

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

Agora adicione esta função que envia o payload da imagem para o 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'])

A chamada images().annotate() requer os dados e os recursos da API desejados. O limite de cinco principais rótulos também faz parte do payload (mas totalmente opcional). Se a chamada for bem-sucedida, o payload retornará os cinco principais rótulos de objetos, além da pontuação de confiança de um objeto na imagem. Se não houver resposta, atribua um dicionário Python vazio para que a seguinte instrução if não falhe. Essa função simplesmente agrupa esses dados em uma string CSV para uso eventual no nosso relatório.

As cinco linhas que chamam vision_label_img() precisam ser colocadas logo após o upload bem-sucedido no 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)

Com essa adição, o driver principal deve ficar assim:

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)

A exclusão de storage.json para atualizar os escopos e executar novamente o aplicativo atualizado resultará em uma saída semelhante à seguinte, observando a adição do 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

Resumo

Nem todo mundo tem o conhecimento sobre machine learning para criar e treinar os próprios modelos de ML para analisar dados. A equipe do Google Cloud disponibilizou alguns dos modelos pré-treinados do Google para uso geral e os colocou por trás de APIs. Isso ajudou a democratizar a IA e o ML para todos.

Se você é um desenvolvedor e pode chamar uma API, use o machine learning. O Cloud Vision é apenas um dos serviços de API que você pode usar para analisar os dados. Saiba mais sobre outras pessoas. Agora, seu código precisa corresponder ao conteúdo que está no repositório em step3-vision/analyze_gsimg.py.

Agora você conseguiu arquivar os dados corporativos e analisá-los, mas o que está faltando é um resumo desse trabalho. Vamos organizar todos os resultados em um único relatório que você pode enviar para seu chefe. O que é mais apresentado para gerenciamento do que uma planilha?

Nenhuma importação adicional é necessária para a API Google Sheets. Além disso, a única nova informação necessária é o ID de arquivo de uma planilha existente já formatada e aguardando uma nova linha de dados, portanto, a constante SHEET. Recomendamos que você crie uma nova planilha semelhante a esta:

ca435d8aafd72ff4.png

O URL dessa planilha terá esta aparência: https://docs.google.com/spreadsheets/d/FILE_ID/edit. Pegue esse recurso FILE_ID e atribua-o como SHEET.

Também encontramos uma pequena função chamada k_ize(), que converte bytes em kilobytes, definindo-a como um lambda Python, já que é uma simples linha. Ambas integradas com as outras constantes são assim:

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

Como nos passos anteriores, precisamos de outro escopo de permissão, desta vez, leitura e gravação para a Sheets API. Agora, SCOPES são todos os quatro itens necessários:

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

Agora, crie um endpoint do serviço no Planilhas Google perto dos outros, para que ele fique assim:

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

A funcionalidade do sheet_append_row() é simples: escolha uma linha de dados e o código de uma planilha para depois adicionar essa linha a essa planilha:

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

A chamada de spreadsheets().values().append() exige o ID de arquivo do Planilhas, um intervalo de células, a forma como os dados devem ser inseridos e os próprios dados. O ID do arquivo é simples, o intervalo de células é fornecido na notação A1. Um intervalo de "Sheet1" significa toda a Planilha Google. Isso sinaliza à API para anexar a linha após todos os dados da planilha. Há duas opções de como os dados devem ser adicionados à planilha, "RAW" (insira os dados completos) ou "USER_ENTERED" (grave os dados como se um usuário o inseriu no teclado com o aplicativo Planilhas Google, preservando os recursos de formatação de célula).

Se a chamada for bem-sucedida, o valor de retorno não tem nada útil. Portanto, optamos por receber o número de células atualizadas pela solicitação da API. Veja abaixo o código que chama essa função:

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

O arquivo do Planilhas Google tem colunas que representam dados como qualquer "subdiretório" pai, o local do arquivo arquivado no Cloud Storage (bucket + nome do arquivo), o MIMEtype do arquivo, o tamanho do arquivo (originalmente em bytes, mas é convertido em kilobytes com k_ize() ) e a string de rótulos do Cloud Vision. Observe também que o local arquivado é um hiperlink. Seu gerente pode clicar para confirmar que o backup foi feito com segurança.

Ao adicionar o bloco de código acima logo depois de exibir os resultados do Cloud Vision, a parte principal que conduz o app estará concluída, embora estruturalmente um pouco complexo:

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)

Excluir storage.json pela última vez e executar novamente o aplicativo atualizado resultará em saída semelhante à seguinte, observando a adição do 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

Embora seja útil, a linha extra da resposta é visualizada analisando o arquivo do Planilhas Google com a última linha (linha 7 no exemplo abaixo) adicionada ao conjunto de dados existente.

a7f821fa497e6bbe.png

Resumo

Nas três primeiras etapas deste tutorial, você se conectou às APIs do G Suite e do GCP para mover dados e analisá-los, representando 80% de todo o trabalho. Porém, no final do dia, nada disso significa que você não pode apresentar o gerenciamento de tudo que fez. Para visualizar melhor os resultados, resumir todos os resultados em um relatório gerado fala os volumes.

Para aumentar ainda mais a utilidade da análise, além de escrever os resultados em uma planilha, uma melhoria possível seria indexar os cinco principais rótulos para cada imagem, de modo que um banco de dados interno fosse criado, permitindo que os funcionários autorizados busquem imagens por pesquisa mas isso é um exercício para os leitores.

No momento, nossos resultados estão em uma planilha e acessíveis ao gerenciamento. O código do seu aplicativo nesse estágio deve corresponder ao que está no repositório em step4-sheets/analyze_gsimg.py. A etapa final é limpar o código e transformá-lo em um script utilizável.

(opcional) O aplicativo funciona muito bem. Podemos melhorar isso? Sim, principalmente o aplicativo principal, que parece uma bagunça. Vamos colocar isso em uma função própria e deixá-la permitindo a entrada do usuário em vez de constantes fixas. Faremos isso com o módulo argparse. Além disso, vamos iniciar uma guia do navegador da Web para exibir a planilha depois de gravar a linha de dados nela. Isso é possível com o módulo webbrowser. Divida essas importações com as outras para que as importações principais fiquem assim:

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

Para poder usar esse código em outros aplicativos, precisamos suprimir a saída. Portanto, vamos adicionar uma sinalização DEBUG para que isso aconteça, adicionando esta linha ao final da seção de constantes próximas ao topo:

DEBUG = False

Agora, sobre o corpo principal. Como estávamos desenvolvendo esta amostra, você deve começar a se sentir "desconfortável" à medida que nosso código adiciona outro nível de aninhamento com cada serviço adicionado. Se você sentiu isso, não está sozinho, como isso aumenta a complexidade do código, conforme descrito nesta postagem do blog de testes do Google.

Seguindo essa prática recomendada, vamos reorganizar a parte principal do app em uma função e return em cada "ponto de interrupção" em vez de aninhar. Isso retorna None se qualquer etapa falhar e True se for bem-sucedida:

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

É mais simples e claro, deixando-a mais complicada para a cadeia de if-else, reduzindo a complexidade do código conforme descrito acima. A última peça do quebra-cabeça é criar um driver principal "real", permitindo a personalização do usuário e minimizando a saída, a menos que desejado:

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 todas as etapas forem concluídas, o script iniciará um navegador da Web na planilha especificada na qual a nova linha de dados foi adicionada.

Resumo

Não é necessário excluir storage.json porque não houve alteração no escopo. Execute novamente o aplicativo atualizado, revelando uma nova janela do navegador aberta na planilha modificada, menos linhas de saída e a emissão de uma opção -h mostra as opções aos usuários, incluindo -v para restaurar as linhas agora identificadas de saída. antes:

$ 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

As outras opções permitem que os usuários escolham vários nomes de arquivo do Drive, subdiretórios, nomes de bucket e do Cloud Storage, resultados principais "N" do Cloud Vision e IDs de arquivo do Planilhas Google. Com essas últimas atualizações, a versão final do seu código agora deve corresponder ao que está no repositório em final/analyze_gsimg.py, bem como aqui, em sua totalidade:

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

'''
analyze_gsimg.py - analyze G Suite image processing workflow

Download image from Google Drive, archive to Google Cloud Storage, send
to Google Cloud Vision for processing, add results row to Google Sheet.
'''

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

from googleapiclient import discovery, http
from httplib2 import Http
from oauth2client import file, client, tools

k_ize = lambda b: '%6.2fK' % (b/1000.) # bytes to kBs
FILE = 'YOUR_IMG_ON_DRIVE'
BUCKET = 'YOUR_BUCKET_NAME'
PARENT = ''     # YOUR IMG FILE PREFIX
SHEET = 'YOUR_SHEET_ID'
TOP = 5       # TOP # of VISION LABELS TO SAVE
DEBUG = False

# process credentials for OAuth2 tokens
SCOPES = (
    'https://www.googleapis.com/auth/drive.readonly',
    'https://www.googleapis.com/auth/devstorage.full_control',
    'https://www.googleapis.com/auth/cloud-vision',
    'https://www.googleapis.com/auth/spreadsheets',
)
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
    creds = tools.run_flow(flow, store)

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

def drive_get_img(fname):
    'download file from Drive and return file info & binary if found'

    # search for file on Google Drive
    rsp = DRIVE.files().list(q="name='%s'" % fname,
            fields='files(id,name,mimeType,modifiedTime)'
    ).execute().get('files', [])

    # download binary & return file info if found, else return None
    if rsp:
        target = rsp[0]  # use first matching file
        fileId = target['id']
        fname = target['name']
        mtype = target['mimeType']
        binary = DRIVE.files().get_media(fileId=fileId).execute()
        return fname, mtype, target['modifiedTime'], binary

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

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

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

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

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

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

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

def main(fname, bucket, sheet_id, folder, top, debug):
    '"main()" drives process from image download through report generation'

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

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

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

    # push results to Sheet, get cells-saved count
    fsize = k_ize(len(data))
    row = [folder,
            '=HYPERLINK("storage.cloud.google.com/%s/%s", "%s")' % (
            bucket, gcsname, fname), mtype, ftime, fsize, rsp
    ]
    rsp = sheet_append_row(sheet_id, row)
    if not rsp:
        return
    if debug:
        print('Added %d cells to Google Sheet' % rsp)
    return True

if __name__ == '__main__':
    # args: [-hv] [-i imgfile] [-b bucket] [-f folder] [-s Sheet ID] [-t top labels]
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", "--imgfile", action="store_true",
            default=FILE, help="image file filename")
    parser.add_argument("-b", "--bucket_id", action="store_true",
            default=BUCKET, help="Google Cloud Storage bucket name")
    parser.add_argument("-f", "--folder", action="store_true",
            default=PARENT, help="Google Cloud Storage image folder")
    parser.add_argument("-s", "--sheet_id", action="store_true",
            default=SHEET, help="Google Sheet Drive file ID (44-char str)")
    parser.add_argument("-t", "--viz_top", action="store_true",
            default=TOP, help="return top N (default %d) Vision API labels" % TOP)
    parser.add_argument("-v", "--verbose", action="store_true",
            default=DEBUG, help="verbose display output")
    args = parser.parse_args()

    print('Processing file %r... please wait' % args.imgfile)
    rsp = main(args.imgfile, args.bucket_id,
            args.sheet_id, args.folder, args.viz_top, args.verbose)
    if rsp:
        sheet_url = 'https://docs.google.com/spreadsheets/d/%s/edit' % args.sheet_id
        print('DONE: opening web browser to it, or see %s' % sheet_url)
        webbrowser.open(sheet_url, new=1, autoraise=True)
    else:
        print('ERROR: could not process %r' % args.imgfile)

Faremos o possível para manter o conteúdo deste tutorial atualizado, mas haverá momentos em que o repositório terá a versão mais recente do código.

Certamente havia muito aprendizado neste codelab, e você conquistou isso em um dos codelabs mais longos. Como resultado, você resolveu um possível cenário corporativo com cerca de 130 linhas de Python, aproveitando todo o Google Cloud (GCP + G Suite) e transferindo dados entre ele para criar uma solução funcional. Fique à vontade para explorar o repositório de código aberto (em inglês) para ver todas as versões desse app. Veja mais informações abaixo.

Limpeza

  1. O uso das APIs do GCP não é gratuito enquanto as APIs do G Suite são cobertas pela taxa de assinatura mensal do G Suite ou pela taxa mensal de zero como usuário do Gmail. Portanto, não há uma limpeza/desativação de API necessária para os usuários do G Suite No GCP, acesse o painel do Console do Cloud e verifique se há cobranças estimadas no "cartão" de faturamento.
  2. Para o Cloud Vision, o número permitido de chamadas de API é permitido por mês. Se você mantiver esses limites, não será necessário encerrar nada nem desativar/excluir seu projeto. Veja mais informações sobre o faturamento e a cota gratuita da API Vision na página de preços da API.
  3. Alguns usuários do Cloud Storage recebem uma quantidade gratuita de armazenamento por mês. Se as imagens arquivadas usando este codelab não fizerem com que você exceda essa cota, não haverá cobranças. Veja mais informações sobre o faturamento do GCS e a cota gratuita na página de preços. É possível visualizar e excluir facilmente blobs do navegador do Cloud Storage.
  4. O uso do Google Drive também pode ter uma cota de armazenamento. Se você a ultrapassar (ou estiver próximo a ele), considere a possibilidade de usar a ferramenta criada neste codelab para arquivar essas imagens no Cloud Storage para dar mais espaço no Google Drive. Veja mais informações sobre o armazenamento no Google Drive na página de preços apropriada para usuários do G Suite Basic ou do Gmail/consumidor.

Embora a maioria dos planos do G Suite Business e Enterprise tenham armazenamento ilimitado, suas pastas do Drive podem ficar desorganizadas e/ou pesadas, e o aplicativo que você criou neste tutorial é uma ótima forma de arquivar arquivos irrelevantes e limpar seu Google Drive.

Versões alternativas

final/analyze_gsimg.py é a "última" versão oficial em que você está trabalhando neste tutorial, mas não é o fim da história. Um problema com a versão final do aplicativo é que ele usa as bibliotecas de autenticação mais antigas que foram suspensas. Escolhemos esse caminho porque, no momento em que este artigo foi escrito, as bibliotecas de autenticação mais recentes não eram compatíveis com diversos elementos importantes: gerenciamento de armazenamento de tokens OAuth e segurança de threads.

Bibliotecas de autenticação atuais (mais recentes)

No entanto, em algum momento, as bibliotecas de autenticação mais antigas não serão mais compatíveis. Por isso, recomendamos que você revise as versões que usam as bibliotecas de autenticação mais recentes (atuais) na pasta alt do repositório, mesmo se elas não são threadsafe (mas você pode criar sua própria solução). Procure arquivos com *newauth* no nome.

Bibliotecas de cliente do produto do GCP

O Google Cloud recomenda que todos os desenvolvedores usem as bibliotecas de cliente dos produtos ao utilizar APIs do GCP. As APIs que não são do GCP não têm essas bibliotecas no momento. O uso das bibliotecas de plataforma de nível inferior possibilita um uso consistente da API e têm melhor legibilidade. Assim como na recomendação acima, versões alternativas que usam bibliotecas de cliente de produtos do GCP estão disponíveis na pasta alt do repositório para análise. Procure arquivos com *-gcp* no nome.

Autorização da conta de serviço

Ao trabalhar puramente na nuvem, geralmente não há dados de usuários (ou humanos) de usuários. Por isso, as contas de serviço e a autorização da conta de serviço são usadas principalmente com o GCP. No entanto, os documentos do G Suite geralmente são de propriedade de usuários (humanos). Por isso, este tutorial usa autorização de conta de usuário. Isso não significa que não será possível usar as APIs do G Suite com contas de serviço. Desde que essas contas tenham o nível de acesso apropriado, elas certamente poderão ser usadas em aplicativos. Assim como nas versões acima, as versões alternativas que usam a autorização da conta de serviço estão disponíveis na pasta alt do repositório para análise. Procure arquivos com *-svc* no nome.

Catálogo de versões alternativas

Veja abaixo todas as versões alternativas de final/analyze_gsimg.py, cada uma com uma ou mais das propriedades acima. No nome de arquivo de cada versão, procure...

  • "oldauth" para versões que usam as bibliotecas de autenticação mais antigas (além de final/analyze_gsimg.py)
  • "newauth" para aqueles que usam as bibliotecas de autenticação atuais/mais recentes
  • "gcp" para aqueles que usam bibliotecas de cliente de produto do GCP, ou seja, google-cloud-storage etc.
  • ".svc" para aqueles que usam uma conta de serviço ("conta svc") em vez de uma conta de usuário

Aqui estão todas as versões:

Filename

Descrição

final/analyze_gsimg.py

A amostra principal usa as bibliotecas de autenticação mais antigas

alt/analyze_gsimg-newauth.py

Igual a final/analyze_gsimg.py, mas usa as bibliotecas de autenticação mais recentes

alt/analyze_gsimg-oldauth-gcp.py

Igual a final/analyze_gsimg.py, mas usa as bibliotecas de cliente de produtos do GCP

alt/analyze_gsimg-newauth-gcp.py

Igual a alt/analyze_gsimg-newauth.py, mas usa as bibliotecas de cliente de produtos do GCP

alt/analyze_gsimg-oldauth-svc.py

Igual a final/analyze_gsimg.py, mas usa conta svc em vez de conta de usuário

alt/analyze_gsimg-newauth-svc.py

Igual a alt/analyze_gsimg-newauth.py, mas usa autenticação de conta svc em vez de conta de usuário

alt/analyze_gsimg-oldauth-svc-gcp.py

Igual a alt/analyze_gsimg-oldauth-svc.py, mas usa bibliotecas de cliente de produto do GCP e é igual a alt/analyze_gsimg-oldauth-gcp.py, mas usa autenticação de conta svc em vez de conta de usuário

alt/analyze_gsimg-newauth-svc-gcp.py

Igual a alt/analyze_gsimg-oldauth-svc-gcp.py, mas usa as bibliotecas de autenticação mais recentes

Com o final/analyze_gsimg.py original, você tem todas as combinações possíveis da solução final, independentemente do seu ambiente de desenvolvimento da API do Google, e pode escolher a mais adequada às suas necessidades. Veja também alt/README.md para uma explicação semelhante.

Estudo adicional

Veja abaixo algumas ideias de como esse exercício pode ser iniciado. O problema definido para a solução atual pode ser expandido, permitindo que você faça estas melhorias:

  1. (várias imagens em pastas) Em vez de processar uma imagem, digamos que você tenha ela nas pastas do Google Drive.
  2. (várias imagens em arquivos ZIP) Em vez de uma pasta de imagens, que tal os arquivos ZIP que contêm arquivos de imagem? Se estiver usando Python, considere o módulo zipfile.
  3. (analisar rótulos do Vision) Agrupe imagens semelhantes, comece procurando os rótulos mais comuns, os dois mais comuns e assim por diante.
  4. (criar gráficos) Acompanhamento 3, gerar gráficos com a API Sheets com base na análise e na categorização da API Vision
  5. (categorizar documentos) Em vez de analisar imagens com a API Cloud Vision, digamos que você tenha arquivos PDF para categorizar com a API Cloud Natural Language. Usando as soluções acima, esses PDFs podem estar em pastas do Drive ou em arquivos ZIP no Drive.
  6. (criar apresentações) Use a API Slides para gerar uma apresentação com o conteúdo do relatório do Planilhas Google. Para ter mais ideias, confira esta postagem do blog e este vídeo sobre como gerar slides de dados de planilha.
  7. (exportar como PDF) Exportar a planilha e/ou a apresentação de slides como PDF, no entanto, esse não é um recurso das APIs nem das Planilhas Google. Dica: API Google Drive. Crédito extra: combine os PDFs do Planilhas e do Apresentações em um PDF mestre com ferramentas como Ghostscript (Linux ou Windows) ou Combine PDF Pages.action (Mac OS X).

Saiba mais

Codelabs

Geral

G Suite

Google Cloud Platform (GCP)

Licença

Este conteúdo está sob a licença Atribuição 2.0 Genérica da Creative Commons.