Closed deknowny closed 3 years ago
Хочу пару копеек вставить, как я это вижу сам:
Логи Не вижу смысла логировать annotype/reaction/validator (скорее это полезно будет в процессе разработки самого фреймворка, но в мастере-ветке такому место не нужно), имхо достаточно объединить longpoll.log и api.log в один лог-файл,
Нейминг Точно стоит поменять rexp на regexp/regex, VkErr на VKApiError (тут и Error прописан, и без сокращений). Насчет Reaction и Signal спорно, кажется, что с ними проблем нет, Handler будет немного лишним. Насчет Uploader классов ниже
Про аннотации.
Смысл их был изначально в том, что у нас уже есть factory-классы, которые возвращают типы. Стандартные типы уже будут в модуле (vq.Word например), но при этом для того, что-бы собрать тип с валидацией, нужно собрать инстанс с аргументами.
Например:
def foo(username: vq.Word): ....
# Но для типа с условиями
def bar(username: vq.WordType(min_=4): ...
Нагромождении не вижу особо, когда методы будут выглядить примерно так:
# ....
@vq.Reaction("messages_new")
def some(
user: vq.UserMention,
age: vq.IntBuilder(min=18, max=1337),
work_list: typing.List[vq.Word] # / vq.List(vq.Word) / vq.List[vq.Word],
note: vq.String,
): pass
Для этого всего у нас уже готовы инструменты - на крайняк, можно не лезть с созданием реальных типов, а сделать просто обертку под это все дело (хотя очень не хочу, есть желание это все чтоб еще Mypy воспринимал адекватно) Как это будет выглядить внутри файлов с определениями типов:
class SomeTypeBuilder(AnnoType):
def __init__(validate_param_one=None, validate_param_two=None):
pass
DefaultType = SomeTypeBuilder()
Просто есть желание писать максимально близко к питоновским аннотациям, без постоянных созданий инстансов.
Через декораторы такое себе - будет как раз-таки нагромождение, когда декораторов больше трех на одну функцию имхо читать уже неудобно.
- **Насчет поддержки разных api и ее разных версии.**
Понятно, что здесь действительно нужно делать прослойку для чуть более удобного взаимодействия, но у меня два вопроса:
1) Мы будем запрещать поднимать бота одновременно на longpoll api и на callback api, например? Если нет, как будем проверять совместимости запросов, как будем логировать и др?
2) Где ты видишь вообще в архитектуре, в каком месте стоит делать обработку? Будет ли она для каждого api своя? Где будем учитывать разные версии? Насколько потенциально сложно будет это обрабатывать?
- **Насчет фотографий.**
Я вот что предлагаю сделать вообще:
1) Написать маленьких методов на поэтапную загрузку картинки (с указанием, куда пикчу загружаем, и т.д.)
2) Написать сверху пару методов, которые будут делать это внутри себя, но уже сами укажут типы и т.д.
3) В самом классе Message (ну и в подобных, где есть взаимодействие с пикчами) сделать метод, который будет создавать внутри себя объект Photo и работать уже с ним, сделать менее явным крч, вот.
Так будет и спрятанно, и выглядеть аккуратно, при этом сам разработчик при необходимости вытащит все, что ему нужно (понятно через документацию)
- **Тестирование бота**
Давай разделим сразу 2 вещи:
1) Тестировать клиентскую логику
Это лучше оставить самому клиенту, можно дать пример в документации, но очень хочется, чтобы была возможность работы со всем этим как в django (т.е. дать обертку для взаимодействиями с реакциями/сигналами/валидаторами и др), минимально mock'ать объекты, благо такая возможность есть вроде как.
Дать инструменты, а там хоть unittest пусть использует, хоть pytest, все что угодно. Правда сразу нужно контролировать запуск тестов и обычный запуск, но в целом проблема решается проверкой на импорте, да.
Делать сверху свою логику - плохая идея - долго, муторно, сложность с поддержкой, вот это все. Лучше пусть сам клиент делает так, как нужно, да.
2) Тестировать самого бота (наша уже задача)
Предлагаю порефакторить все проблемные места (вчера мы с тобой обговорили), залить все туда юнит тестами, потом повесить на сам репозиторий пайплайн вместе с интеграционнами тестами. Кажется, что так будет лучше и проще всего, есче будем мониторить вк группу/чат и здесь issue (как проект, надеюсь, увеличится, будем просить сюда писать, да).
- **Зависимости.**
Предлагаю просто хранить два файла с зависимостями: requirements.txt и requirements-dev.txt (ну или poetry, без разницы), их будет достаточно. Главное, чтоб ставилось проще некуда, поэтому лучше держать стандартный (дедовский) метод.
Со всем остальным более
Кстати, предлагаю нарисовать архитектуру всего проекта, чтоб быстрее можно было бы освоиться будущим контрибьютерам, вот.
Структура проекта бота
Я не очень в курсе, как обычно содежат логи, поэтому если есть какое-то решение лучше -- без проблем добавим его. Конфиги по своей структуре тоже под вопросом.
Нейминг
Reaction
->EventHandler
(EventsHandler
?)Signal
->SignalHandler
Photo
->PhotoUploader
(Делать отдельный класс для работы с полями пришедшего объекта от вк)Doc
->DocumentUploader
rexp
. Можетregex
?VkErr
->APIError
/VKAPIError
/VkApiError
Изменения
BuildType
,WordType
и все..Type
. Честно, не вижу смысла в замене круглых скобок на квадратных и введении более "композиционного" стиля. Да, подвязатьtyping.List
и билдиновский лист и что-то подобное не только для листа это круто, но я думаю это можно сделать не ввязывая Type'ы для более детальной настройки. Однако, у меня есть одна мысль на этот счет. Я думаю, ты видел, как описывается терминальный инструмент черезclick
-- все флаги через декораторы, а дальше это уже падает в аргументы. И нагромождений нет, и расписать можно. Может, вот такие "детальные" настройки, по типу количества элементов выносить в декоратор? Но декораторы уже забиты под валидаторы...Мы как-то уже обсуждали гибкость аннотипов и пришли к тому, что нужно лишь несколько типов:
Возможно, мы что-то упустили, но команды бота -- это не bash, поэтому нужна ли им такая гибкость с билд типами и расширенными типами, или же можно просто обойтись аннотациями, какие они есть сейчас? (Я согласен на изменения логики внутри, меня не выткает именно использвоание)
Сейчас событие (
vq.tools.event.Event
) -- это просто унаследованный отAttrMap
класс. Поскольку для v1.0 планируется добавление новых механик получения событий (в частности и возможность юзер ботов), было бы неплохо добавить общие методы по получение каких-то "межсобытийных" полей. Например, для сообщества (лп или кб событие) текст сообщения с версией5.103
и выше будетevent.object.message.text
, для ниже5.103
event.object.text
, для пользователя вообщеevent[5]
. Поэтому для получения текста можно добавить метод, например,get_text()
, который бы рассматривал каждый кейс и получал текст сообщения в зависимости от события. И так сpeer_id
,from_id
(здесь уже придется делать API запрос для юзерского лп) и другими полями. Для некоторых кейсов это даст универсальность написания ботов, которые будут совместимы как и с аккаунтом пользователя, так и сообщества, причем под апи разных версий. Как бы это странно не было, но юзер боты действительно пользуются популярностью, поэтому постараться сделать для них почти одинаковый интерфейс очень хорошая мысль.Скорее всего
bot
будет переделан сclick
наcleo
, имхо, стиль гораздо удобнееУбрать
ReactionList
иSignalsList
вообще, а всю логику перенести вBot
. Лишнее нагромождение.Нужна ли поддержка своего стиля написания бота? Я боюсь, что если пользователю один раз показать, как делать бота в 1 файле -- он и будет делать его в 1 файле, вообще забивая на рефакторинг (что сейчас происходит в vk_api, vk.py, vkbottle, vkwave и во всех библиотеках)
Сущесвтует несколько оберток для вк апишных объектов (структура пользователя, структура фотографии, документа...). Все они немного похожи, поэтому, возможно, стоит задать им общий интерфейc.
Сейчас мне не очень нравится то, как выглядит загрузка фотографий и документов. Не только изнутри, но и внешне. Сама загрузка через апи (сырая) происходит в 3 этапа
2ой пункт полностью автоматизированный. Для 1ого и 3ьего можно передать некоторые параметры при запросе. Из этого можно составить примерную схему всей загрузки (уже используемую)
Либо объеденить 2ой и третий и запрашивать словарь парамтеров (если такое надо) на каждый из способов. Что-то в этом роде
Можно не мучать точки и передать путь загрузки на 2ом этапе,
Либо разбить на 3 этапа (можно оставить поддержку 2х способов)
Должен ли
photo
сам стать объектом (используя мутабельность) -- или он вернет уже другой объект? Наверно, это две разные вещи, поэтому переменные нужно будет перебиндитьВ новой версии доки (стиль сайта будет тот же, старая уедет в отдельный раздел) хотелось бы четко разделить документацию от туториала. Я посмотрел инструменты, которые могут по сурсам сделать .md странички как документацию, но ничего толкового не нашел (не отрицаю, что плохо искал).
Возможно, это тема уже нового проектаХачю пользователскую доку к боту на mkdocs material, как и дока vkquick
Как проекту бота работать с зависимостями? Просто вести requirements.txt или же вносить poetry? Или это уже забота пользвоателя?
Касательно того, как могут проходить тестирования. Сначала тесты нужно забилдить (построются файлы по сурсам). После чего можно будет эмулировать вызовы (используя параметрайз, естесна), куда будет "инъекцироваться" свое собственное собранное событие, идентичное вкшному (о нем чуть ниже). В ответ на эмуляцию вызова будет прилетать объект, описывающий вообще все, что приключилось внутри.
И где-то в тестах ты эмулируешь вызов с разными собыйтиями, на что получаешь такую схему:
Как добавлять свои
actions
? Либо оборачивать нужный класс/функцию специальной оберткой, либо хз. Честно. Но если придумать, как создавать свои штукенции дляactions
, можно будет обеспечить шедевральную тестируемость, полностью совместимую с возможностями питеста.Откуда брать события, которыми эмулируется вызов? Было бы круто, если бы vkquick сам записывал все события вызова команды, а потом сам предлагал на выбор какое-либо из них, а там уже, если надо, поля можно будет поменять под свои данные.