ПР. Навык Алисы
Кратко:
- Создана функция my-first-function для обработки запросов от Алисы.
- Функция будет использоваться для создания навыка Попугай.
- Создана новая функция parrot с использованием команды yc serverless function create.
- Новая версия функции будет загружать новый файл в Object Storage.
- Для создания новой версии функции необходимы переменные окружения.
- Вызов функции и ее тестирование перед созданием связки с Алисой.
- Создание навыка в диалоге Алисы с использованием функции parrot.
Практическая работа. Навык Алисы
В предыдущих практических работах вы создали сервисный аккаунт с именем
service-account-for-cf
, добавили ему роли editor
и storage.editor
и создали ключ доступа.Также вы создали бакет в Object Storage с именем
bucket-for-trigger
, триггер my-first-trigger
для его обработки и вызываемую им функцию my-trigger-function
.Ещё была создана функция
my-first-function
, её использовали для того, чтобы запустить цепочку событий. Публичный вызов этой функции приводил к созданию нового объекта в бакете в Object Storage. Это запускало вызов триггера my-first-trigger
, который стартовал функцию my-trigger-function
. В итоге последняя функция записывала в логи содержание переменной event
.Если вы удалили бакет и сервисный аккаунт, необходимо вернуться к предыдущим урокам и повторить их создание.
Шаг 1. Создание функции
На предыдущем уроке мы создали функцию с именем
my-first-function
. Поменяем её исходный код так, чтобы обрабатывать запросы от Алисы.На основе функции будет создан навык Попугай, который повторяет все, что ему написал или сказал пользователь.
Функция parrot
Создадим новую функцию с именем
parrot
с помощью команды:
yc serverless function create \
--name parrot \
--description "function for Alice"
По умолчанию функция не является публичной.
Загрузка кода новой версии
Функция имеет зависимости, которые описаны в файле
requirements.txt
, а это значит, что для загрузки функции в облако необходимо заархивировать файлы parrot.py
и requirements.txt
и получить файл parrot.zip
.Содержание функции
parrot.py
:
import os
import datetime
import boto3
import pytz
ACCESS_KEY = os.getenv("ACCESS_KEY")
SECRET_KEY = os.getenv("SECRET_KEY")
BUCKET_NAME = os.getenv("BUCKET_NAME")
TIME_ZONE = os.getenv("TIME_ZONE", "Europe/Moscow")
TEMP_FILENAME = "/tmp/temp_file"
TEXT_FOR_TEMP_FILE = "This is text file"
def write_temp_file(text_for_s3):
TEXT_FOR_TEMP_FILE = text_for_s3
temp_file = open(TEMP_FILENAME, 'w')
temp_file.write(TEXT_FOR_TEMP_FILE)
temp_file.close()
print("\U0001f680 Temp file is written")
def get_now_datetime_str():
now = datetime.datetime.now(pytz.timezone(TIME_ZONE))
return now.strftime('%Y-%m-%d__%H-%M-%S')
def get_s3_instance():
session = boto3.session.Session()
return session.client(
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY,
service_name='s3',
endpoint_url='https://storage.yandexcloud.net'
)
def upload_dump_to_s3():
print("\U0001F4C2 Starting upload to Object Storage")
get_s3_instance().upload_file(
Filename=TEMP_FILENAME,
Bucket=BUCKET_NAME,
Key=f'file-{get_now_datetime_str()}.txt'
)
print("\U0001f680 Uploaded")
def remove_temp_files():
os.remove(TEMP_FILENAME)
print("\U0001F44D That's all!")
def handler(event, context):
"""
Entry-point for Serverless Function.
:param event: request payload.
:param context: information about current execution context.
:return: response to be serialized as JSON.
"""
text = 'Hello! I\'ll repeat anything you say to me.'
if 'request' in event and \
'original_utterance' in event['request'] \
and len(event['request']['original_utterance']) > 0:
text = event['request']['original_utterance']
write_temp_file(text)
upload_dump_to_s3()
remove_temp_files()
return {
'version': event['version'],
'session': event['session'],
'response': {
# Respond with the original request or welcome the user if this is the beginning of the dialog and the request has not yet been made.
'text': text,
# Don't finish the session after this response.
'end_session': 'false'
},
}
Содержание файла зависимостей
requirements.txt
:
boto3==1.13.10
botocore==1.16.10
python-dateutil==2.8.1
pytz==2020.1
Находясь в каталоге с файлом
parrot.zip
, вызовите приведенную ниже команду. Это позволит вам загрузить код функции в облако и создать её версию:
yc serverless function version create \
--function-name=parrot \
--memory=256m \
--execution-timeout=5s \
--runtime=python37 \
--entrypoint=parrot.handler \
--service-account-id $SERVICE_ACCOUNT_ID \
--source-path parrot.zip
Шаг 2. Создание новой версии функции
Новая версия функции при вызове будет загружать в Object Storage новый файл. Для создания этой новой версии функции необходимы переменные.
Если переменные среды не сохранились, то в консоли управления можно посмотреть имя бакета, а
ACCESS_KEY
и SECRET_KEY
скопировать из предыдущей функции my-first-function
:
echo "export ACCESS_KEY=<ACCESS_KEY>" >> ~/.bashrc && . ~/.bashrc
echo "export SECRET_KEY=<SECRET_KEY>" >> ~/.bashrc && . ~/.bashrc
echo "export BUCKET_NAME=bucket-for-trigger" >> ~/.bashrc && . ~/.bashrc
Определим идентификатор (
ID
) последней загруженной версии функции:
yc serverless function version list --function-name parrot
Создадим новую версию функции, задав переменные окружения. Для этого выставим значение параметра
source-version-id
равное полученному идентификатору версии функции (ID
) в следующей команде:
yc serverless function version create \
--function-name parrot \
--memory 256m \
--execution-timeout 5s \
--runtime python37 \
--entrypoint parrot.handler \
--service-account-id $SERVICE_ACCOUNT_ID \
--source-version-id <идентификатор_версии_функции> \
--environment ACCESS_KEY=$ACCESS_KEY \
--environment SECRET_KEY=$SECRET_KEY \
--environment BUCKET_NAME=$BUCKET_NAME
Успешное выполнение команды приведёт к созданию версии функции.
Шаг 3. Вызов функции и её тестирование
По умолчанию функция создаётся непубличной. Чтобы сделать функцию
parrot
публичной, вызовите следующую команду:
yc serverless function allow-unauthenticated-invoke parrot
Протестируйте функцию
parrot
, чтобы проверить правильность кода перед созданием связки с Алисой. В консоли управления на странице сервиса Cloud Functions выберите созданную функцию и перейдите на вкладку Тестирование. В поле Шаблон данных данных укажите Навык Алисы
и нажмите кнопку Запустить тест.
В блоке Результат тестирования убедитесь, что функция выполнена и приведен ответ.

Перейдите по ссылке https://dialogs.yandex.ru/developer/ и создайте новый диалог Алисы (подробности о создании навыков вы можете узнать из документации):
-
Нажмите кнопку Создать диалог. Выберите тип диалога Навык в Алисе, у вас откроется форма на вкладке Настройки.
-
Заполните имя навыка, оно должно состоять минимум из двух слов, например
My parrot
. -
В блоке Backend выберите вариант Функция в Яндекс.Облаке и в выпадающем списке выберите созданную вами функцию
parrot
. -
В блоке Тип доступа в выпадающем списке выберите Приватный.
-
В блоке Публикация в каталоге выберите Примеры запросов, например
Запусти навык - My parrot
, Имя разработчика, Категорию, Описание и Иконку. -
Нажмите кнопку Сохранить и перейдите на вкладку Тестирование.
Если вы сделали всё правильно, то на экране появится приветствие навыка. Далее навык будет повторять всё, что вы ему напишете. При этом фразы, которые вы отправите Алисе, будут сохраняться в новом файле в бакете. Вы можете это проверить в консоли управления.