Implante uma versão básica do "Google Tradutor" App Engine em Python 2

1. Visão geral

Esta série de codelabs (tutoriais práticos e individualizados) tem como objetivo ajudar os desenvolvedores a entender as várias opções disponíveis ao implantar aplicativos. Neste codelab, você vai aprender a usar a API Google Cloud Translation com Python e a executar localmente ou implantar em uma plataforma de computação sem servidor do Cloud (App Engine, Cloud Functions ou Cloud Run). O app de exemplo encontrado no repositório deste tutorial pode ser implantado (pelo menos) oito maneiras diferentes, com apenas pequenas mudanças na configuração:

  1. Servidor Flask local (Python 2)
  2. Servidor Flask local (Python 3)
  3. App Engine (Python 2)
  4. App Engine (Python 3)
  5. Cloud Functions (Python 3)
  6. Cloud Run (Python 2 via Docker)
  7. Cloud Run (Python 3 via Docker)
  8. Cloud Run (Python 3 via Cloud Buildpacks)

Este codelab se concentra na implantação do app nas plataformas em negrito acima.

Você aprenderá como realizar as seguintes tarefas:

O que é necessário

  • Um projeto do Google Cloud com uma conta ativa do Cloud Billing
  • Flask instalado para execução local ou uma plataforma de computação sem servidor na nuvem ativada para implantações baseadas na nuvem.
  • Habilidades básicas em Python
  • Conhecimento prático de comandos básicos do sistema operacional

Pesquisa

Como você usará este tutorial?

Ler e fazer os exercícios Somente leitura

Como você classificaria sua experiência com Python?

Iniciante Intermediário Proficiente

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

Iniciante Intermediário Proficiente

2. Configuração e requisitos

Configuração de ambiente autoguiada

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

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • O Nome do projeto é o nome de exibição para os participantes do projeto. Ele é uma string de caracteres que não é usada pelas APIs do Google e pode ser atualizada a qualquer momento.
  • O ID do projeto precisa ser exclusivo em todos os projetos do Google Cloud e não pode ser alterado após a definição. O Console do Cloud gera automaticamente uma string única, geralmente não importa o que seja. Na maioria dos codelabs, você precisará fazer referência ao ID do projeto, que geralmente é identificado como PROJECT_ID. Então, se você não gostar dele, gere outro ID aleatório ou crie um próprio e veja se ele está disponível. Em seguida, ele fica "congelado" depois que o projeto é criado.
  • Há um terceiro valor, um Número de projeto, que algumas APIs usam. Saiba mais sobre esses três valores na documentação.
  1. Em seguida, você precisará ativar o faturamento no Console do Cloud para usar os recursos/APIs do Cloud. A execução deste codelab não será muito cara, se tiver algum custo. Para encerrar os recursos e não gerar cobranças além deste tutorial, siga as instruções de "limpeza" encontradas no final do codelab. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.

3. Ativar a API Translation

Para nosso app de exemplo, você ativará a API Cloud Translation e o serviço do App Engine usando instruções semelhantes às fornecidas abaixo.

Como ativar as APIs do Cloud

Introdução

Seja qual for a API do Google que você quer usar no aplicativo, ela precisa estar ativada. No exemplo a seguir, mostramos duas maneiras de ativar a API Cloud Vision. Depois de aprender a ativar uma API do Cloud, você poderá ativar outras APIs, porque o processo é semelhante.

Opção 1: no Cloud Shell ou na interface de linha de comando

Embora ativar APIs do console do Cloud seja mais comum, alguns desenvolvedores preferem fazer tudo na linha de comando. Para isso, é preciso procurar o "nome do serviço" de uma API. Ele parece um URL: SERVICE_NAME.googleapis.com. Você pode encontrá-los no gráfico de produtos compatíveis ou consultar programaticamente com a API Google Discovery.

Com essas informações, usando o Cloud Shell ou um ambiente de desenvolvimento local com a ferramenta de linha de comando gcloud instalada, você pode ativar uma API da seguinte maneira:

gcloud services enable SERVICE_NAME.googleapis.com

Por exemplo, este comando ativa a API Cloud Vision:

gcloud services enable vision.googleapis.com

Este comando ativa o App Engine:

gcloud services enable appengine.googleapis.com

Você também pode ativar várias APIs com uma solicitação. Por exemplo, a linha de comando a seguir ativa o Cloud Run, o Cloud Artifact Registry e a API Cloud Translation:

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

Opção 2: no Console do Cloud

Também é possível ativar a API Vision no Gerenciador de APIs. No console do Cloud, acesse Gerenciador de APIs e selecione Biblioteca.

fb0f1d315f122d4a.png

Se você quiser ativar a API Cloud Vision, digite "vision" na barra de pesquisa, e tudo o que corresponde ao que você digitou até agora aparecerá:

2275786a24f8f204.png

Selecione a API que você quer ativar e clique em Ativar:

2556f923b628e31.png

Custo

Embora muitas APIs do Google possam ser usadas sem taxas, o uso de produtos e serviços do Google Cloud as APIs não são sem custo financeiro. Ao ativar as APIs do Cloud, talvez você precise criar uma conta de faturamento ativa. No entanto, é importante observar que alguns produtos do Google Cloud têm a opção "Sempre sem custo financeiro" nível (diário/mensal), que você precisa exceder para gerar cobranças de faturamento. Caso contrário, o cartão de crédito (ou a forma de faturamento especificada) não será cobrado.

Os usuários devem consultar as informações de preço de qualquer API antes de ativar, especialmente observando se ela tem um nível sem custo financeiro e, em caso afirmativo, qual é. Se você estiver ativando a API Cloud Vision, verifique a página de informações de preços. O Cloud Vision tem uma cota sem custo financeiro e, desde que você fique dentro dos limites agregados (em cada mês), não haverá cobranças.

Os preços e os níveis sem custo financeiro variam entre as APIs do Google. Exemplos:

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 você sabe como ativar as APIs do Google em geral, acesse o Gerenciador de APIs e ative a API Cloud Translation e o serviço do App Engine (caso ainda não tenha feito isso). A primeira opção será usada pelo nosso aplicativo, e a segunda, porque você está implantando um aplicativo do App Engine. Se preferir fazer isso pela linha de comando, use este comando:

gcloud services enable appengine.googleapis.com translate.googleapis.com

Embora a cota mensal não esteja listada na lista geral "Sempre sem custo financeiro", página de resumo do nível, a página de preços da API Translation informa que todos os usuários recebem uma quantidade fixa de caracteres traduzidos por mês. Você não receberá cobranças da API se ficar abaixo desse limite. Se houver outras cobranças relacionadas ao Google Cloud, elas serão abordadas no final da seção "Limpeza" nesta seção.

4. Fazer o download do código do app de exemplo

Clone o código no repositório localmente ou no Cloud Shell (usando o comando git clone) ou faça o download do arquivo ZIP pelo botão verde Code, conforme mostrado na captura de tela a seguir:

5cd6110c4414cf65.png

Agora que você tem tudo, crie uma cópia completa da pasta para realizar este tutorial específico, porque isso provavelmente envolverá a exclusão ou a alteração dos arquivos. Se você quiser fazer uma implantação diferente, comece de novo copiando o original para não precisar cloná-lo ou fazer o download dele novamente.

5. Tour do app de exemplo

O app de exemplo é uma derivação simples do Google Tradutor que solicita que os usuários insiram um texto em inglês e recebam a tradução equivalente desse texto em espanhol. Agora abra o arquivo main.py para conferir como ele funciona. Omitindo as linhas comentadas sobre licenciamento, o código fica assim nas partes de cima e de baixo:

from flask import Flask, render_template, request
import google.auth
from google.cloud import translate

app = Flask(__name__)
_, PROJECT_ID = google.auth.default()
TRANSLATE = translate.TranslationServiceClient()
PARENT = 'projects/{}'.format(PROJECT_ID)
SOURCE, TARGET = ('en', 'English'), ('es', 'Spanish')

# . . . [translate() function definition] . . .

if __name__ == '__main__':
    import os
    app.run(debug=True, threaded=True, host='0.0.0.0',
            port=int(os.environ.get('PORT', 8080)))
  1. As importações trazem a funcionalidade Flask, o módulo google.auth e a biblioteca de cliente da API Cloud Translation.
  2. As variáveis globais representam o app Flask, o ID do projeto do Cloud, o cliente da API Translation e o "caminho do local" pai. para chamadas da API Translation e os idiomas de origem e de destino. Neste caso, são inglês (en) e espanhol (es), mas fique à vontade para alterar esses valores para outros códigos de idioma compatíveis com a API Cloud Translation.
  3. O grande bloco if na parte inferior é usado no tutorial para executar este aplicativo localmente. Ele utiliza o servidor de desenvolvimento Flask para exibir nosso aplicativo. Esta seção também inclui os tutoriais de implantação do Cloud Run caso o servidor da Web não esteja empacotado no contêiner. Você precisa ativar o agrupamento do servidor no contêiner, mas caso ignore, o código do app voltará a usar o servidor de desenvolvimento Flask. Não é um problema com o App Engine ou o Cloud Functions, porque essas são plataformas baseadas em origem, o que significa que o Google Cloud fornece e executa um servidor da Web padrão.

Por fim, no meio de main.py está o coração do aplicativo, a função translate():

@app.route('/', methods=['GET', 'POST'])
def translate(gcf_request=None):
    """
    main handler - show form and possibly previous translation
    """

    # Flask Request object passed in for Cloud Functions
    # (use gcf_request for GCF but flask.request otherwise)
    local_request = gcf_request if gcf_request else request

    # reset all variables (GET)
    text = translated = None

    # if there is data to process (POST)
    if local_request.method == 'POST':
        text = local_request.form['text']
        data = {
            'contents': [text],
            'parent': PARENT,
            'target_language_code': TARGET[0],
        }
        # handle older call for backwards-compatibility
        try:
            rsp = TRANSLATE.translate_text(request=data)
        except TypeError:
            rsp = TRANSLATE.translate_text(**data)
        translated = rsp.translations[0].translated_text

    # create context & render template
    context = {
        'orig':  {'text': text, 'lc': SOURCE},
        'trans': {'text': translated, 'lc': TARGET},
    }
    return render_template('index.html', **context)

A função principal recebe a entrada do usuário e chama a API Translation para fazer o trabalho pesado. Vamos ver os detalhes:

  1. Verifique se as solicitações vêm do Cloud Functions usando a variável local_request. O Cloud Functions envia um objeto de solicitação Flask próprio, enquanto todos os outros (executados localmente ou implantando no App Engine ou no Cloud Run) recebem o objeto da solicitação diretamente do Flask.
  2. Redefina as variáveis básicas do formulário. Isso serve principalmente para solicitações GET, já que as solicitações POST terão dados que as substituirão.
  3. No caso de um POST, use o texto para tradução e crie uma estrutura JSON que represente o requisito de metadados da API. Em seguida, chame a API, voltando para uma versão anterior se o usuário estiver usando uma biblioteca mais antiga.
  4. Seja qual for o caso, formate os resultados reais (POST) ou nenhum dado (GET) no contexto do modelo e renderize.

A parte visual do aplicativo está no arquivo de modelo index.html. Ele mostra todos os resultados traduzidos anteriormente (em branco), seguidos pelo formulário que solicita algo para tradução:

<!doctype html>
<html><head><title>My Google Translate 1990s</title><body>
<h2>My Google Translate (1990s edition)</h2>

{% if trans['text'] %}
    <h4>Previous translation</h4>
    <li><b>Original</b>:   {{ orig['text'] }}  (<i>{{ orig['lc'][0] }}</i>)</li>
    <li><b>Translated</b>: {{ trans['text'] }} (<i>{{ trans['lc'][0] }}</i>)</li>
{% endif %}

<h4>Enter <i>{{ orig['lc'][1] }}</i> text to translate to <i>{{ trans['lc'][1] }}</i>:</h4>
<form method="POST"><input name="text"><input type="submit"></form>
</body></html>

6. Instalar pacotes/dependências locais (na lib)

Conforme mencionado anteriormente, o app de exemplo usa o microframework da Web Flask e a biblioteca de cliente da API Google Cloud Translation para Python. Instale e atualize o pip e este par de pacotes com este comando pip (ou pip3):

pip install -t lib -r requirements.txt

Depois de executar o comentário acima, você verá a saída da instalação, que pode ser semelhante a esta:

$ pip install -t lib -r requirements.txt
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
Collecting flask>=1.1.2
  Using cached Flask-1.1.4-py2.py3-none-any.whl (94 kB)
Collecting google-cloud-translate>=2.0.1
  Using cached google_cloud_translate-2.0.2-py2.py3-none-any.whl (91 kB)
Collecting click<8.0,>=5.1
  Using cached click-7.1.2-py2.py3-none-any.whl (82 kB)
Collecting Jinja2<3.0,>=2.10.1
  Using cached Jinja2-2.11.3-py2.py3-none-any.whl (125 kB)
Collecting Werkzeug<2.0,>=0.15
  Using cached Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)
Collecting itsdangerous<2.0,>=0.24
  Using cached itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
Collecting google-api-core[grpc]<2.0.0dev,>=1.15.0
  Downloading google_api_core-1.29.0-py2.py3-none-any.whl (93 kB)
     |████████████████████████████████| 93 kB 2.1 MB/s
Collecting google-cloud-core<2.0dev,>=1.1.0
  Using cached google_cloud_core-1.6.0-py2.py3-none-any.whl (28 kB)
Collecting MarkupSafe>=0.23
  Using cached MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl (17 kB)
Collecting protobuf>=3.12.0
  Downloading protobuf-3.17.2-cp27-cp27m-macosx_10_9_x86_64.whl (958 kB)
     |████████████████████████████████| 958 kB 21.6 MB/s
Collecting futures>=3.2.0; python_version < "3.2"
  Using cached futures-3.3.0-py2-none-any.whl (16 kB)
Collecting six>=1.13.0
  Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Collecting packaging>=14.3
  Using cached packaging-20.9-py2.py3-none-any.whl (40 kB)
Collecting googleapis-common-protos<2.0dev,>=1.6.0
  Using cached googleapis_common_protos-1.52.0-py2.py3-none-any.whl (100 kB)
Collecting requests<3.0.0dev,>=2.18.0
  Using cached requests-2.25.1-py2.py3-none-any.whl (61 kB)
Collecting google-auth<2.0dev,>=1.25.0
  Using cached google_auth-1.30.1-py2.py3-none-any.whl (146 kB)
Collecting pytz
  Using cached pytz-2021.1-py2.py3-none-any.whl (510 kB)
Collecting setuptools>=40.3.0
  Using cached setuptools-44.1.1-py2.py3-none-any.whl (583 kB)
Collecting grpcio<2.0dev,>=1.29.0; extra == "grpc"
  Using cached grpcio-1.38.0-cp27-cp27m-macosx_10_10_x86_64.whl (3.8 MB)
Collecting pyparsing>=2.0.2
  Using cached pyparsing-2.4.7-py2.py3-none-any.whl (67 kB)
Collecting chardet<5,>=3.0.2
  Using cached chardet-4.0.0-py2.py3-none-any.whl (178 kB)
Collecting urllib3<1.27,>=1.21.1
  Using cached urllib3-1.26.5-py2.py3-none-any.whl (138 kB)
Collecting idna<3,>=2.5
  Using cached idna-2.10-py2.py3-none-any.whl (58 kB)
Collecting certifi>=2017.4.17
  Downloading certifi-2021.5.30-py2.py3-none-any.whl (145 kB)
     |████████████████████████████████| 145 kB 61.1 MB/s
Collecting pyasn1-modules>=0.2.1
  Using cached pyasn1_modules-0.2.8-py2.py3-none-any.whl (155 kB)
Collecting rsa<4.6; python_version < "3.6"
  Using cached rsa-4.5-py2.py3-none-any.whl (36 kB)
Collecting cachetools<5.0,>=2.0.0
  Using cached cachetools-3.1.1-py2.py3-none-any.whl (11 kB)
Collecting enum34>=1.0.4; python_version < "3.4"
  Using cached enum34-1.1.10-py2-none-any.whl (11 kB)
Collecting pyasn1<0.5.0,>=0.4.6
  Using cached pyasn1-0.4.8-py2.py3-none-any.whl (77 kB)
Installing collected packages: click, MarkupSafe, Jinja2, Werkzeug, itsdangerous, flask, six, protobuf, futures, pyparsing, packaging, googleapis-common-protos, chardet, urllib3, idna, certifi, requests, pyasn1, pyasn1-modules, rsa, cachetools, setuptools, google-auth, pytz, enum34, grpcio, google-api-core, google-cloud-core, google-cloud-translate
ERROR: pip's legacy dependency resolver does not consider dependency conflicts when selecting packages. This behaviour is the source of the following dependency conflicts.
matplotlib 1.3.1 requires nose, which is not installed.
matplotlib 1.3.1 requires tornado, which is not installed.
Successfully installed Jinja2-2.11.3 MarkupSafe-1.1.1 Werkzeug-1.0.1 cachetools-3.1.1 certifi-2021.5.30 chardet-4.0.0 click-7.1.2 enum34-1.1.10 flask-1.1.4 futures-3.3.0 google-api-core-1.29.0 google-auth-1.30.1 google-cloud-core-1.6.0 google-cloud-translate-2.0.2 googleapis-common-protos-1.52.0 grpcio-1.38.0 idna-2.10 itsdangerous-1.1.0 packaging-20.9 protobuf-3.17.2 pyasn1-0.4.8 pyasn1-modules-0.2.8 pyparsing-2.4.7 pytz-2021.1 requests-2.25.1 rsa-4.5 setuptools-44.1.1 six-1.16.0 urllib3-1.26.5

7. Implante o serviço

Para implantar o serviço de tradução no App Engine para Python 2, execute este comando:

gcloud app deploy

A saída será semelhante a esta e fornecerá alguns prompts para as próximas etapas:

$ gcloud app deploy
Services to deploy:

descriptor:      [/private/tmp/nebulous-serverless-python/app.yaml]
source:          [/private/tmp/nebulous-serverless-python]
target project:  [PROJECT_ID]
target service:  [default]
target version:  [20210422t161025]
target url:      [https://PROJECT_ID.appspot.com]


Do you want to continue (Y/n)?

Beginning deployment of service [default]...
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 1290 files to Google Cloud Storage                       ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.
Updating service [default]...done.
Setting traffic split for service [default]...done.
Deployed service [default] to [https://PROJECT_ID.appspot.com]

You can stream logs from the command line by running:
  $ gcloud app logs tail -s default

To view your application in the web browser run:
  $ gcloud app browse

Agora que o app está disponível globalmente, é possível acessá-lo no URL (contendo o ID do projeto) fornecido na saída da implantação:

da28f951c33a2c3d.png

Traduza alguma coisa para que ela funcione!

d911984d15dd5ef9.png

8. Conclusão

Parabéns! Você aprendeu a ativar a API Cloud Translation, conseguir as credenciais necessárias e implantar um app da Web simples no App Engine para Python 2. Saiba mais sobre essa implantação nesta tabela do repositório.

Limpar

Com a API Cloud Translation, é possível realizar uma quantidade fixa de caracteres traduzidos por mês sem custo financeiro. O App Engine também tem uma cota sem custo financeiro, assim como o Cloud Functions e o Cloud Run. Você receberá cobranças se uma delas for excedida. Se você pretende avançar para o próximo codelab, não é necessário encerrar o app.

No entanto, se você ainda não estiver pronto para o próximo tutorial ou estiver preocupado que a Internet descubra o app que acabou de implantar, desative o aplicativo do App Engine, exclua a função do Cloud ou desative o serviço do Cloud Run para evitar cobranças. Quando estiver pronto para passar para o próximo codelab, você poderá reativá-lo. Por outro lado, se você não for continuar com este app ou outros codelabs e quiser excluir tudo por completo, encerre seu projeto.

Além disso, a implantação em uma plataforma de computação sem servidor do Google Cloud gera menores custos de criação e armazenamento. O Cloud Build tem a própria cota sem custo financeiro, assim como o Cloud Storage. Para oferecer mais transparência, o Cloud Build cria a imagem do aplicativo, que é armazenada no Cloud Container Registry ou no Artifact Registry, o sucessor dele. O armazenamento dessa imagem usa parte dessa cota, assim como a saída de rede ao transferi-la para o serviço. No entanto, talvez você more em uma região que não tenha esse nível sem custo financeiro, portanto, esteja ciente do uso do armazenamento para minimizar os possíveis custos.

9. Outros recursos

Nas seções a seguir, você encontrará material de leitura adicional, bem como exercícios recomendados para aumentar seu conhecimento ao concluir este tutorial.

Estudo adicional

Agora que você tem alguma experiência com a API Translation, vamos fazer mais alguns exercícios para desenvolver suas habilidades. Para continuar seu programa de aprendizado, modifique nosso app de exemplo para fazer o seguinte:

  1. Conclua todas as outras edições deste codelab para execução local ou implantação em plataformas de computação sem servidor do Google Cloud (consulte o README do repo).
  2. Conclua este tutorial usando outra linguagem de programação.
  3. Altere este aplicativo para oferecer suporte a diferentes idiomas de origem ou de destino.
  4. Faça o upgrade deste aplicativo para traduzir textos para mais de um idioma. altere o arquivo de modelo para ter um menu suspenso de idiomas de destino compatíveis.

Saiba mais

Google App Engine

Google Cloud Functions

Google Cloud Run

Buildpacks do Google Cloud, Container Registry e Artifact Registry

Google Cloud Translation e Kit de ML do Google

Outros produtos/páginas do Google Cloud

Python e Flask

Licença

Este tutorial está sob a licença Atribuição 2.0 Genérica da Creative Commons, enquanto o código-fonte no repositório está licenciado sob a Apache 2.