Две причины побудили меня написать эту статью и небольшой MVP.
-
Потребность в большем объеме сырых данных с наших рынков. Большую часть из них я могу получать посредством API. Такую возможность предоставляет и Московская биржа, и Т-Банк и Финам. Причем, речь идет не о разовой загрузке больших архивов, а скорей о регулярных задачах, которые должны выполняться с определенной периодичностью.
-
Ностальгия по ламповому TUI(Text User Interface). В этом направлении всегда было место для творчества в условиях ограничений в части отображения (картинки и графики особо не покажешь). Но есть и преимущество — консольное приложение в сравнении с GUI — не столь требовательно к ресурсам и по сути может работать везде, где есть текстовая консоль, ну а в случае моего MVP — еще и Python.
В статье описал личную историю вдохновления, ссылку на код проекта ну и небольшую инструкцию.
Все началось с того, что я случайно, открыл для себя фреймворк Textual (здесь можно посмотреть и документацию и примеры работ). Особенно вдохновил интерфейс Dolphie, вот он

Не знаю как вам, а мне очень понравилось. Что еще мне понравилось в Textual:
-
набор готовых виджетов, начиная от кнопок из списков, заканчивая datatable. И да, “Это Питон, детка!” — можно создавать свои виджеты, наследуя и дорабатывая имеющиеся
-
палитра команд и хоткеи
-
событийность и обмен сообщениями между компонентами
-
асинхронность под капотом. Ну к примеру посредством set_interval можно задавать периодичность фонового запуска какой-либо функции
-
CSS… да 🙂 О дивный новый мир 🙂 Сильно упрощенный, но удобно в части настройки компоновки визуальных элементов
-
реактивность. Ага прям как в js-фреймворках, но разработчики честно признаются, что лучше избегать этого механизма
-
“тематизация” — возможность выбора цветовой палитры на свой вкус
-
всплывающие сообщения (Notify), причем разной степени важности (Info/Warning/Critical)
-
и как вишенка на торте — вы можете использовать textual-serve. Это модуль поднимает небольшой веб-сервер и посредством xterm.js отображает ваше приложение в браузере. Выглядит также как и в консоли, наверняка удобно использовать, но не уверен в части безопасности
Использование
Ссылка на код проекта и инструкции по установке на github
Для демонстрации буду использовать собранный под Windows дистрибутив. Для этого заходим в папку dist и скачиваем архив archivist_0.0.1.zip Распаковываем, запускаем единственный файл archivist.exe.
Весь интерфейс англоязычный на самом деле из прагматичных соображений — предполагаю, что мой MVP будет запускаться на Linux системах, где русская кодировка может быть и не установлена.
Вот такой упрощенный внешний вид, с парочкой примеров задач.

Что мы здесь видим:
-
две задачки по загрузке итогов торгов акциями IBM
-
третья строка, с именем Example — шаблон задачи, который мы будем править
Но, первым делом надо зайти в настройки (нажав F3) и поменять значение параметра data_folder. По умолчанию стоит “.”, что говорит о том, что данные выгружаются в папку data в текущей папке проекта. Однако здесь есть ньюанс для собранных под Windows приложений Python — по сути это архивы, которые сначала распаковываются во временную папку и оттуда уже запускаются. Соответственно и папка data оказывается там же, что неудобно. Поэтому указываем свой путь для хранения данных, например как показано на рисунке

Обратите внимание, что значение указано в кавычках, и используется знак «\\» как разделитель. Это все особенности описания настроек в формате json. Далее нажимаем “Ctrl+s” для сохранения настроек. Автоматически произойдет переход на основной экран.
Обе задачки заведены для выполнения с интервалом каждые пять минут, но если мы хотим протестировать настройки, достаточно выбрать одну из задач и нажать F9. После нажатия произойдет выгрузка в файл в указанную в настройках папку. На данном примере — в папке data появиться папка IBM, внутри которой будет файл с указанным расширением (csv/json) и именем равным текущей дате.
Загрузка данных с Мосбиржи.
Давайте попробуем более интересную задачку. Вот ссылка на страницу итогов торгов по инструментам(да в браузере также открывается): https://iss.moex.com/iss/engines/stock/markets/shares/securities.json
Да, сервис московской биржи великолепен и мы можем забирать данные сразу в формате csv/json/html, но в контексте данного примера — попробуем забирать и главное разбирать именно json.
Вот так примерно выглядят данные

Давайте попробуем настроить новую задачку, которая будет забирать эти данные, и укладывать их в файл. Причем, что важно, мне не нужна секция metadata файла (шапка), я хочу складывать в файл, сразу содержимое секции securities/data. И чтобы все было сразу в формате csv.
На главном экране нажимаем F2 и переходим в режим редактирования задач. Мы можем поправить или существующую шаблонную задачку с именем Example, или добавить новую в текущий файл конфигурации. Добавляем следующий конфиг:
{ "name": "moex_securities", "request_method": "GET", "request_url": "https://iss.moex.com/iss/engines/stock/markets/shares/securities.json", "request_headers": "", "request_body": "{}", "comment": "shares -> securities", "interval": "5min", "file_save_mode": "rewrite", "file_format": "csv", "json_key": "securities/data"}
Не забываем про запятые между фигурными скобками. В итоге должно получиться примерно вот так:

Что важно здесь отметить:
-
file_save_mode: если хотит перезаписывать файл при очередном заборе данных — ставим режим rewrite, если дозаписывать — append
-
json_key: если мы забираем данные в формате json и нас интересует лишь значения конкретного ключа, тогда указываем их через слэш. В данном примере “securities/data”. Если хотим забирать вообще все — указываем пустую строку “”
-
file_format: указали вывод в csv (можем указать csv или json или html). И да, у меня конвертирование данных в формат csv сделан очень по деревянному (заменой символов), возможно исправлю со временем, но пока — как есть.
-
interval: 5min/10min/30min/60min/1day
Нажимаем “ctrl+s” для сохранения. Если вы все сделали правильно, то на главном экране появляется новая строка. Выбираем ее и тестируем получение данных, нажав F9. Заходим в нашу папку data, смотрим содержимое полученного файла.
Загрузка данных с Т-Банк
Здесь чуть сложнее. Данные забираются посредством POST-запросов, причем в хэдере (headers) должен быть указан ваш токен, который насколько я помню живет порядка 3 месяцев с момента генерации. Но порядок тот же.
Снова нажимаем F2, и вносим следующие настройки в конфигурацию:
{ "name": "tb_last_prices", "request_method": "POST", "request_url": "https://invest-public-api.tinkoff.ru/rest/tinkoff.public.invest.api.contract.v1.MarketDataService/GetLastPrices", "request_headers": { "Authorization": "Bearer ВАШ_ТОКЕН", "Content-Type": "application/json", "Accept": "application/json" }, "request_body": {}, "comment": "last_prices", "interval": "1min", "file_save_mode": "rewrite", "file_format": "json", "json_key": "lastPrices" }
Обратите внимание — помимо того, что request_method теперь принимает значение POST, также значения в полях request_headers и request_body обрамлено в фигурные скобки.
Сохраняемся (Ctrl+S) и тестируем (F9)
Итог
Хочу повторить, что “Архивист” является промежуточным продуктом моей работы. Будет ли он развиваться, или так и останется на уровне MVP — зависит от его востребованности как на github, так и здесь. Так что если вам понравилась реализация — напишите пожалуйста, плюс буду признателен за идеи по улучшению.
ссылка на оригинал статьи https://habr.com/ru/articles/1025980/