Яндекс.Функции, Sublime Text и навыки для Алисы

от автора

27 июня Яндекс проводил онлайн-хакатон по разработке навыков для Алисы.

Решил и я принять в нем участие. Ранее навыки для Алисы я уже делал, но хостил их все на Google App Engine. Тут же я решил изучить что-то новое в рамках Хакатон. Яндекс активно продвигает свои Функции в Яндекс.Облаке для разработки навыков. Для навыков они бесплатны (правда, бесплатно не всё).

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

Решил я попробовать навык в Яндекс.Облаке разместить. К тому же, решил я, навык должен быть простым — чтобы за день в рамках Хакатона успеть сделать. Тут Функции в Облаке очень подходят — к сторонним сервисам обращаться не надо (они в функциях платные), данные можно хранить в самом навыке, внешняя БД не нужна.

Раньше я старался делать полезные навыки — чтобы оплатить парковку голосом, например (в Яндекс.Навигаторе) или узнать, когда автобус/троллейбус/трамвай придет на ближайшую остановку. Это требовало интеграций со сторонними сервисами, долгой разработки, а Яндексу, судя по премии Алисы, больше игровые-развлекательные навыки по душе. Потому в этот раз я решил делать игру.

Для работы с Функциями предлагается либо все делать локально, а потом файлы в Функции загружать, либо же редактировать файлы в онлайн-редакторе. Онлайн-редакторы я люблю ;), потому сначала попробовал воспользоваться им. Однако после двух-трех-четырех правок и сохранения новых версий, от этой идеи решил отказаться — уж очень неудобно, что нажав на Сохранить, тебя редиректит на другой экран. Итого каждая правка — это куча лишних кликов.

С командой строкой жить чуть проще. Но файлы нужно каждый раз нужно в zip добавлять, а лишь потом в Облако грузить. Руками — неудобно.

Так уж сложилось, что моя IDE — это Sublime Text 3. Недавно Google отказался от Google App Engine Launcher и с ним остался единственный вариант — загрузка файлов через командную строку. Тогда-то я и узнал о существовании build systems в Sublime Text — нажимаешь Ctrl/Cmd+B и Sublime выполняет нужную тебе команду. Для GAE я тогда сделал набор команд, решил, что и тут что-то подобное нужно.

Сначала была сделана функциональность просто для загрузки файлов.
Для GAE я делал так, чтобы передаваемые параметры (а именно — название проекта) читалось из файла проекта Sublime Text. Тут же для экономии времени название функции, точка входа и остальные параметры просто зашиты в build system. Не очень хорошо, но для моих целей подходило.

Но если все тестировать на боевом сервере, то и логи надо как-то удобно смотреть. Потому для загрузки и отображения логов было добавлена отдельная команда.

Увы, если логи просто отобразить, то ориентироваться в них довольно сложно.
Пришлось немного подшаманить с командой (чтобы unicode-строки отображались корректно — но и то, работает это не всегда), с самим кодом (чтобы JSON выводить в читаемом виде):

    logging.getLogger().setLevel(logging.DEBUG)     logging.debug('REQUEST: ')     for line in json.dumps(event['request'], indent=4).split('\n'):         logging.debug(line) 

и создать отдельный файл синтаксиса, чтобы подсвечивать ошибки в логе.

Отдельная удобная фича — Sublime Text умеет подсвечивать и саму строку, если нашла ее в коде.

Итого получилось следующее —

Файл Yandex Cloud.sublime-build

// Install Yandex CLI - https://cloud.yandex.ru/docs/cli/quickstart#install // // http://www.sublimetext.com/docs/3/build_systems.html // https://cloud.yandex.ru/docs/functions/operations/function/version-manage#version-create {     "file_patterns": ["*.py"],     "syntax": "Packages/User/YCLog.sublime-syntax",     "file_regex": "File \\\"/function/code/(...*?)\\\", line ([0-9]*)",      "variants":         [             {                 "name": "Upload",                 "shell_cmd": "zip -u -0 yc_upload.zip *.py && yc serverless function version create --function-name=my-function-name --runtime=python27 --entrypoint=main.handler --memory=128m --execution-timeout=2s --source-path=yc_upload.zip",             },             {                 "name": "Logs",                 "shell_cmd": "printf '%b\n' \"\\$(yc serverless function logs alice-guess-the-language)\""             }         ] }

Файл YCLog.sublime-syntax

%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
name: YC Log
file_extensions: [log]
scope: source.example-c
contexts:
main:
# Request identifiers
- match: '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (START|END|REPORT) RequestID: .*'
scope: storage.type.string.c

# Dates
- match: '\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}'
scope: comment.line.c

- match: '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{2,3}Z [0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}'
scope: comment.line.c

# Log level
- match: '\[(INFO|DEBUG)\]'
scope: comment.line.example-c

# Log level
- match: '\[(ERROR|WARNING)\]'
scope: keyword.control.flow.break.c

# Strings begin and end with quotes, and use backslashes as an escape
# character
- match: '"'
scope: punctuation.definition.string.begin.c
push: double_quoted_string

double_quoted_string:
- meta_scope: string.quoted.double.example-c
- match: '\\.'
scope: constant.character.escape.example-c
- match: '"'
scope: punctuation.definition.string.end.example-c
pop: true

Редактировать код Функций в Яндекс.Облаке стало гораздо приятнее.

P.S. Мой навык — игра Угадай язык.

ссылка на оригинал статьи https://habr.com/ru/post/509670/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *