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. Не очень хорошо, но для моих целей подходило.
![](https://habrastorage.org/r/w1560/webt/9q/vi/g9/9qvig9z9hvajclwsadsvgb_dv-a.png)
Но если все тестировать на боевом сервере, то и логи надо как-то удобно смотреть. Потому для загрузки и отображения логов было добавлена отдельная команда.
Увы, если логи просто отобразить, то ориентироваться в них довольно сложно.
Пришлось немного подшаманить с командой (чтобы unicode-строки отображались корректно — но и то, работает это не всегда), с самим кодом (чтобы JSON выводить в читаемом виде):
и создать отдельный файл синтаксиса, чтобы подсвечивать ошибки в логе.
![](https://habrastorage.org/r/w1560/webt/el/zx/0o/elzx0oiiiakha5kwr_lmpz4y4ni.png)
Отдельная удобная фича — Sublime Text умеет подсвечивать и саму строку, если нашла ее в коде.
Итого получилось следующее —
Редактировать код Функций в Яндекс.Облаке стало гораздо приятнее.
P.S. Мой навык — игра Угадай язык.
Решил и я принять в нем участие. Ранее навыки для Алисы я уже делал, но хостил их все на 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. Не очень хорошо, но для моих целей подходило.
![](https://habrastorage.org/webt/9q/vi/g9/9qvig9z9hvajclwsadsvgb_dv-a.png)
Но если все тестировать на боевом сервере, то и логи надо как-то удобно смотреть. Потому для загрузки и отображения логов было добавлена отдельная команда.
Увы, если логи просто отобразить, то ориентироваться в них довольно сложно.
Пришлось немного подшаманить с командой (чтобы unicode-строки отображались корректно — но и то, работает это не всегда), с самим кодом (чтобы JSON выводить в читаемом виде):
logging.getLogger().setLevel(logging.DEBUG)
logging.debug('REQUEST: ')
for line in json.dumps(event['request'], indent=4).split('\n'):
logging.debug(line)
и создать отдельный файл синтаксиса, чтобы подсвечивать ошибки в логе.
![](https://habrastorage.org/webt/el/zx/0o/elzx0oiiiakha5kwr_lmpz4y4ni.png)
Отдельная удобная фича — 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. Мой навык — игра Угадай язык.