Skip to content

feat: fetch для user и chat при auto_requests=False#101

Merged
love-apples merged 11 commits intomainfrom
feat/fetch-without-auto-requests
Apr 13, 2026
Merged

feat: fetch для user и chat при auto_requests=False#101
love-apples merged 11 commits intomainfrom
feat/fetch-without-auto-requests

Conversation

@love-apples
Copy link
Copy Markdown
Owner

Если бот создан с auto_requests=False, то event.chat и
event.from_user могут быть lazy ref. В этом режиме запрашиваем их
явно:

chat = await event.fetch_chat()
from_user = await event.fetch_from_user()

# или через сами ref-объекты
chat = await event.chat.fetch() if event.chat else None
from_user = await event.from_user.fetch() if event.from_user else None

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Pending LazyRef является falsy (bool = False), поэтому паттерн
`if event.chat` не вызовет fetch(). Исправлено на `is not None`.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@love-apples
Copy link
Copy Markdown
Owner Author

@Olegt0rr привет! Оцени, пожалуйста)

Copy link
Copy Markdown
Collaborator

@Olegt0rr Olegt0rr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Крутая и полезная идея, т.к. я как раз хочу с ростом нагрузки на мой проект перейти в режим отключения авто-реквестов и возникает много вопросов.

Есть несколько идей по оптимизации логики - написал точечно

Comment thread maxapi/types/updates/base_update.py Outdated
Comment thread maxapi/types/updates/base_update.py Outdated
Comment on lines +54 to +65
async def fetch_from_user(self) -> Any | None:
"""Явно получить from_user для события, если доступен lazy fetch."""

from_user = self.from_user
if from_user is None:
return None

fetch = getattr(from_user, "fetch", None)
if callable(fetch):
return await fetch()

return from_user
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Есть ощущение, что этак конструкция адекватна для любого LazyRef поля и можно ещё унифицировать, не создавая отдельный метод для каждого поля

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

PR добавляет явный механизм “ленивого” получения event.chat и event.from_user при bot.auto_requests=False, чтобы избежать скрытых API-запросов и при этом сохранить удобный способ догрузки данных по требованию.

Changes:

  • Добавлены lazy ref-объекты ChatRef/FromUserRef и общий .fetch() API для уже-разрешённых моделей через FetchableMixin.
  • enrich_event() теперь всегда инжектит bot, а при auto_requests=False прикрепляет lazy refs вместо сетевых запросов.
  • Добавлены/расширены тесты на поведение lazy refs и enrich_event(auto_requests=False), обновлена документация с примерами.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
maxapi/types/fetchable.py Новые LazyRef, ChatRef, FromUserRef и FetchableMixin для унифицированного fetch()
maxapi/utils/updates.py Логика attach lazy refs при auto_requests=False, рефакторинг извлечения chat_id/from_user
maxapi/types/updates/base_update.py Добавлены fetch_chat()/fetch_from_user() для явной догрузки
maxapi/types/users.py User теперь поддерживает fetch() через FetchableMixin
maxapi/types/chats.py Chat теперь поддерживает fetch() через FetchableMixin
maxapi/types/init.py Экспорт ChatRef/FromUserRef в публичный API types
maxapi/types/attachments/video.py Уточнение TYPE_CHECKING-аннотации bot
tests/test_fetchable_refs.py Новый тестовый набор для LazyRef и методов BaseUpdate.fetch_*
tests/test_enrich_event.py Новые интеграционные тесты для auto_requests=False и lazy refs
maxapi/bot.py Докстринг: описание поведения auto_requests=False
docs/examples.md Документация/примеры по явному fetch_* и .fetch()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread maxapi/bot.py Outdated
Comment thread docs/examples.md Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread maxapi/types/fetchable.py
Comment on lines +47 to +55
async def fetch(self) -> ResolvedValue | None:
"""Загрузить значение и закешировать результат."""

if self._resolved is _UNSET:
value = await self._fetcher()
self._resolved = value
self._setter(value)

return cast(ResolvedValue | None, self._resolved)
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LazyRef.fetch() is not concurrency-safe: if two coroutines call fetch() одновременно, оба могут увидеть _resolved == _UNSET и запустить fetcher дважды, а setter будет вызван два раза. Лучше защитить первую загрузку asyncio.Lock/Task-кэшированием (например, хранить _fetch_task и await его) чтобы гарантировать ровно один сетевой вызов и один setter.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@love-apples, вот это очень дельное замечание

Comment thread maxapi/bot.py Outdated
Copy link
Copy Markdown
Collaborator

@Olegt0rr Olegt0rr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Очень хорошие замечания написал Copilot (по поводу гонки с несколькими запросами - особенно)

@love-apples love-apples merged commit 58b6afc into main Apr 13, 2026
13 checks passed
@love-apples love-apples deleted the feat/fetch-without-auto-requests branch April 13, 2026 20:24
bish-x added a commit to bish-x/maxapi that referenced this pull request Apr 14, 2026
Подтянуты PR из upstream: love-apples#93 (FSM), love-apples#96 (download_file),
love-apples#101 (fetch user/chat), love-apples#105 (ClipboardButton), love-apples#109 (share payload),
love-apples#110 (webhook secret warning).

Конфликт в tests/test_types.py: принят upstream-стиль (явный
update_type, разнесённые assert). Сохранены доп. тесты
test_get_ids_ignores_inviter_id / test_get_ids_ignores_admin_id —
их purpose именно цель PR love-apples#94 (не путать inviter_id/admin_id с
user.user_id).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants