Разверните базовую версию "Google Translate" приложение на платформе приложений Python 2

1. Обзор

Эта серия практических занятий (самостоятельное обучение) призвана помочь разработчикам понять различные варианты развертывания своих приложений. В этом практическом занятии вы узнаете, как использовать API Google Cloud Translation с Python и запускать приложения локально или развертывать их на облачной платформе бессерверных вычислений (App Engine, Cloud Functions или Cloud Run). Пример приложения, представленный в репозитории этого руководства , можно развернуть (как минимум) восемью различными способами с минимальными изменениями конфигурации:

  1. Локальный Flask-сервер (Python 2)
  2. Локальный Flask-сервер (Python 3)
  3. App Engine (Python 2)
  4. App Engine (Python 3)
  5. Облачные функции (Python 3)
  6. Cloud Run (Python 2 через Docker)
  7. Cloud Run (Python 3 через Docker)
  8. Cloud Run (Python 3 через Cloud Buildpacks)

Данный практический урок посвящен развертыванию этого приложения на платформах, выделенных жирным шрифтом выше.

Вы узнаете, как

Что вам понадобится

  • Проект Google Cloud с активной учетной записью Cloud Billing.
  • Для локального запуска требуется установленный Flask, либо облачная бессерверная вычислительная платформа с поддержкой облачных развертываний.
  • Базовые навыки работы с Python.
  • Практические навыки работы с основными командами операционной системы.

Опрос

Как вы будете использовать этот учебный материал?

Прочитайте текст и выполните упражнения. Читайте только это

Как бы вы оценили свой опыт работы с Python?

Новичок Средний Профессионал

Как бы вы оценили свой опыт использования сервисов Google Cloud?

Новичок Средний Профессионал

2. Настройка и требования

Настройка среды для самостоятельного обучения

  1. Войдите в консоль Google Cloud и создайте новый проект или используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • Название проекта — это отображаемое имя участников данного проекта. Это строка символов, не используемая API Google, и вы можете изменить её в любое время.
  • Идентификатор проекта должен быть уникальным для всех проектов Google Cloud и неизменяемым (его нельзя изменить после установки). Консоль Cloud автоматически генерирует уникальную строку; обычно вам неважно, какая она. В большинстве практических заданий вам потребуется указать идентификатор проекта (обычно он обозначается как PROJECT_ID ), поэтому, если он вам не нравится, сгенерируйте другой случайный идентификатор или попробуйте свой собственный и посмотрите, доступен ли он. Затем он "замораживается" после создания проекта.
  • Существует третье значение — номер проекта , который используется некоторыми API. Подробнее обо всех трех значениях можно узнать в документации .
  1. Далее вам потребуется включить оплату в консоли Cloud, чтобы использовать ресурсы/API Cloud. Выполнение этого практического задания не должно стоить дорого, если вообще что-либо. Чтобы отключить ресурсы и избежать дополнительных расходов после завершения этого урока, следуйте инструкциям по «очистке», приведенным в конце практического задания. Новые пользователи Google Cloud имеют право на бесплатную пробную версию стоимостью 300 долларов США .

3. Включите API перевода.

Для нашего тестового приложения вам потребуется включить API облачного перевода и службу App Engine , используя аналогичные инструкции, приведенные ниже.

Включение облачных API

Введение

Независимо от того, какой API Google вы хотите использовать в своем приложении, его необходимо включить . В следующем примере показаны два способа включения API Cloud Vision . После того, как вы научитесь включать один API Cloud Vision, вы сможете включать и другие API, поскольку процесс аналогичен.

Вариант 1: Через Cloud Shell или интерфейс командной строки.

Хотя включение API из Cloud Console более распространено, некоторые разработчики предпочитают делать все из командной строки. Для этого необходимо найти «имя сервиса» API. Оно выглядит как URL: SERVICE_NAME . Эти .googleapis.com можно найти в таблице поддерживаемых продуктов , или же их можно получить программным путем с помощью Google Discovery API .

Вооружившись этой информацией, с помощью Cloud Shell (или вашей локальной среды разработки с установленным инструментом командной строки gcloud ) вы можете включить API следующим образом:

gcloud services enable SERVICE_NAME.googleapis.com

Например, эта команда включает API Cloud Vision:

gcloud services enable vision.googleapis.com

Эта команда включает App Engine:

gcloud services enable appengine.googleapis.com

Вы также можете включить несколько API одним запросом. Например, эта команда в командной строке включает Cloud Run, Cloud Artifact Registry и Cloud Translation API:

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

Вариант 2: Из облачной консоли

Вы также можете включить Vision API в API Manager. В консоли Cloud перейдите в API Manager и выберите Library .

fb0f1d315f122d4a.png

Если вы хотите включить API Cloud Vision, начните вводить "vision" в строку поиска, и появятся все, что соответствует вашему предыдущему вводу:

2275786a24f8f204.png

Выберите API, который хотите включить, и нажмите «Включить» :

2556f923b628e31.png

Расходы

Хотя многие API Google можно использовать бесплатно, использование продуктов и API Google Cloud не является бесплатным. При включении API Cloud вас могут попросить указать активный платежный аккаунт. Однако важно отметить, что некоторые продукты Google Cloud имеют тарифный план «Всегда бесплатно» (ежедневно/ежемесячно), превышение которого необходимо для начисления платы; в противном случае с вашей кредитной карты (или указанного платежного инструмента) плата списываться не будет.

Перед включением любого API пользователям следует ознакомиться с информацией о ценах, особенно с наличием бесплатного тарифа и, если таковой имеется, то с его условиями. Если вы включаете API Cloud Vision, вам следует проверить страницу с информацией о ценах . У Cloud Vision есть бесплатная квота, и пока вы в целом не превышаете ее лимиты (в течение каждого месяца), с вас не должно взиматься никакая плата.

Цены и бесплатные тарифные планы различаются в зависимости от используемого API Google. Примеры:

Разные продукты Google оплачиваются по-разному, поэтому обязательно обратитесь к документации вашего API для получения этой информации.

Краткое содержание

Теперь, когда вы знаете, как включить API Google в целом, перейдите в Менеджер API и включите как Cloud Translation API, так и службу App Engine (если вы еще этого не сделали). Первый — потому что наше приложение будет его использовать, а второй — потому что вы развертываете приложение App Engine. Если вы предпочитаете сделать это из командной строки, выполните следующую команду:

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

Хотя ежемесячная квота не указана на общей странице сводки тарифов «Всегда бесплатно» , на странице ценообразования API для перевода указано, что все пользователи получают фиксированное количество переведенных символов в месяц. Если вы не превышаете этот порог, с вас не должно взиматься никакая плата за использование API. Если возникнут какие-либо другие платежи, связанные с Google Cloud, они будут рассмотрены в конце в разделе «Очистка».

4. Получите пример кода приложения.

Клонируйте код из репозитория локально или в Cloud Shell (используя команду git clone ), либо загрузите ZIP-файл, нажав на зеленую кнопку «Код» , как показано на следующем скриншоте:

5cd6110c4414cf65.png

Теперь, когда у вас есть все необходимое, создайте полную копию папки для выполнения этого конкретного руководства, поскольку, скорее всего, потребуется удалить или изменить файлы. Если вы хотите выполнить другое развертывание, вы можете начать заново, скопировав оригинал, чтобы вам не пришлось клонировать или скачивать его снова.

5. Обзор демонстрационного приложения

Пример приложения — это простая версия Google Translate , которая предлагает пользователям ввести текст на английском языке и получить его эквивалентный перевод на испанский. Теперь откройте файл main.py , чтобы увидеть, как он работает. Если опустить закомментированные строки о лицензировании, он выглядит так вверху и внизу:

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. Импортированные модули добавляют функциональность Flask, модуль google.auth и клиентскую библиотеку Cloud Translation API.
  2. Глобальные переменные представляют собой приложение Flask, идентификатор проекта Cloud, клиент API перевода, родительский «путь» для вызовов API перевода, а также исходный и целевой языки. В данном случае это английский ( en ) и испанский ( es ), но вы можете изменить эти значения на другие коды языков, поддерживаемые API перевода Cloud .
  3. Большой блок if внизу используется в руководстве по локальному запуску этого приложения — он использует сервер разработки Flask для обслуживания нашего приложения. Этот раздел также присутствует в руководствах по развертыванию в Cloud Run на случай, если веб-сервер не включен в контейнер. Вам будет предложено включить включение сервера в контейнер, но если вы это пропустите, код приложения будет использовать сервер разработки Flask. (Это не проблема для App Engine или Cloud Functions, поскольку это платформы с исходным кодом, то есть Google Cloud предоставляет и запускает веб-сервер по умолчанию.)

Наконец, в середине файла main.py находится сердце приложения — функция 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)

Основная функция принимает ввод пользователя и вызывает API перевода для выполнения основной работы. Давайте разберем это подробнее:

  1. Проверьте, поступают ли запросы от Cloud Functions, используя переменную local_request . Cloud Functions отправляет собственный объект запроса Flask, тогда как все остальные (работающие локально или развертываемые в App Engine или Cloud Run) получают объект запроса непосредственно от Flask.
  2. Сбросьте основные переменные формы. Это в первую очередь касается GET-запросов, поскольку в POST-запросах эти переменные будут заменены другими данными.
  3. Если это POST-запрос, получите текст для перевода и создайте JSON-структуру, представляющую требования к метаданным API. Затем вызовите API, используя в случае, если пользователь использует более старую библиотеку, предыдущую версию API.
  4. В любом случае, отформатируйте фактические результаты (POST) или отключите данные (GET) в контексте шаблона и выполните отрисовку.

Визуальная часть приложения находится в шаблоне файла index.html . Она отображает результаты предыдущего перевода (в противном случае — пустое поле), после чего следует форма с запросом на перевод:

<!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. Установите локальные пакеты/зависимости (в папку lib).

Как уже упоминалось, в примере приложения используется микровеб-фреймворк Flask и клиентская библиотека Google Cloud Translation API для Python. Установите и обновите pip , а также эти два пакета, с помощью следующей команды pip (или pip3 ):

pip install -t lib -r requirements.txt

После выполнения указанной выше команды вы увидите результат установки, который может выглядеть примерно так:

$ 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. Разверните сервис.

Чтобы развернуть службу перевода в Python 2 App Engine, выполните следующую команду:

gcloud app deploy

Результат должен выглядеть следующим образом и содержать подсказки для дальнейших действий:

$ 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

Теперь, когда ваше приложение доступно по всему миру, вы сможете получить к нему доступ по URL-адресу (содержащему идентификатор вашего проекта), указанному в результатах развертывания:

da28f951c33a2c3d.png

Переведите что-нибудь, чтобы увидеть, как это работает!

d911984d15dd5ef9.png

8. Заключение

Поздравляем! Вы научились включать API облачного перевода, получать необходимые учетные данные и развертывать простое веб-приложение в Python 2 App Engine! Подробнее об этом развертывании можно узнать из таблицы в репозитории .

Уборка

API облачного перевода позволяет бесплатно переводить фиксированное количество символов в месяц . App Engine также имеет бесплатную квоту , как и Cloud Functions и Cloud Run . За превышение квоты взимается плата. Если вы планируете перейти к следующему практическому занятию, вам не нужно закрывать приложение.

Однако, если вы пока не готовы перейти к следующему уроку или опасаетесь, что интернет обнаружит только что развернутое вами приложение, отключите приложение App Engine , удалите облачную функцию или отключите службу Cloud Run , чтобы избежать дополнительных расходов. Когда вы будете готовы перейти к следующему практическому занятию, вы можете снова включить её. С другой стороны, если вы не собираетесь продолжать работу над этим приложением или другими практическими занятиями и хотите полностью удалить всё, вы можете закрыть свой проект .

Кроме того, развертывание на бессерверной вычислительной платформе Google Cloud влечет за собой незначительные затраты на сборку и хранение . Cloud Build, как и Cloud Storage , имеет собственную бесплатную квоту. Для большей прозрачности Cloud Build создает образ вашего приложения, который затем хранится либо в Cloud Container Registry , либо в Artifact Registry , его преемнике. Хранение этого образа расходует часть этой квоты, как и исходящий трафик сети при передаче этого образа в сервис. Однако вы можете проживать в регионе, где нет такого бесплатного уровня, поэтому следите за использованием хранилища, чтобы минимизировать потенциальные затраты.

9. Дополнительные ресурсы

В следующих разделах вы найдете дополнительные материалы для чтения, а также рекомендуемые упражнения для закрепления знаний, полученных в ходе изучения этого руководства.

Дополнительное исследование

Теперь, когда у вас есть некоторый опыт работы с API перевода, давайте выполним несколько дополнительных упражнений для дальнейшего развития ваших навыков. Чтобы продолжить обучение, измените наше тестовое приложение следующим образом:

  1. Выполните все остальные задания этого практического руководства для локального запуска или развертывания на бессерверных вычислительных платформах Google Cloud (см. README репозитория ).
  2. Выполните это руководство, используя другой язык программирования.
  3. Измените это приложение, чтобы оно поддерживало другие исходные или целевые языки.
  4. Обновите это приложение, чтобы оно могло переводить текст на несколько языков; измените файл шаблона, чтобы в нем был выпадающий список поддерживаемых целевых языков.

Узнать больше

Google App Engine

Google Cloud Functions

Google Cloud Run

Google Cloud Buildpacks, Container Registry, Artifact Registry

Google Cloud Translation и Google ML Kit

Другие продукты/страницы Google Cloud

Python и Flask

Лицензия

Данный учебный материал распространяется под лицензией Creative Commons Attribution 2.0 Generic License, а исходный код в репозитории распространяется под лицензией Apache 2.0.