Немного оптимизировано и поправлен список зависимостей

This commit is contained in:
Денис Семёнов 2025-06-29 15:27:19 +03:00
parent c481e3e931
commit b5947e5f47
6 changed files with 96 additions and 88 deletions

View File

@ -1,68 +1,69 @@
from __future__ import annotations
from datetime import datetime
from typing import Any, Dict, List, TYPE_CHECKING, Optional
from .methods.download_media import DownloadMedia
from .methods.get_upload_url import GetUploadURL
from .methods.get_updates import GetUpdates
from .methods.remove_member_chat import RemoveMemberChat
from .methods.add_admin_chat import AddAdminChat
from .methods.add_members_chat import AddMembersChat
from .methods.get_members_chat import GetMembersChat
from .methods.remove_admin import RemoveAdmin
from .methods.get_list_admin_chat import GetListAdminChat
from .methods.delete_bot_from_chat import DeleteMeFromMessage
from .methods.get_me_from_chat import GetMeFromChat
from .methods.delete_pin_message import DeletePinMessage
from .methods.get_pinned_message import GetPinnedMessage
from .methods.pin_message import PinMessage
from .methods.delete_chat import DeleteChat
from .methods.send_action import SendAction
from .methods.edit_chat import EditChat
from .methods.get_chat_by_id import GetChatById
from .methods.get_chat_by_link import GetChatByLink
from .methods.send_callback import SendCallback
from .methods.get_video import GetVideo
from .methods.delete_message import DeleteMessage
from .methods.edit_message import EditMessage
from .methods.change_info import ChangeInfo
from .methods.get_me import GetMe
from .methods.get_messages import GetMessages
from .methods.get_chats import GetChats
from .methods.send_message import SendMessage
from typing import Any, Dict, List, Optional, TYPE_CHECKING
from .connection.base import BaseConnection
from .enums.parse_mode import ParseMode
from .enums.sender_action import SenderAction
from .enums.upload_type import UploadType
from .types.message import Message
from .types.attachments.attachment import Attachment
from .types.attachments.image import PhotoAttachmentRequestPayload
from .types.message import Messages, NewMessageLink
from .types.users import ChatAdmin, User
from .types.command import BotCommand
from .methods.add_admin_chat import AddAdminChat
from .methods.add_members_chat import AddMembersChat
from .methods.change_info import ChangeInfo
from .methods.delete_bot_from_chat import DeleteMeFromMessage
from .methods.delete_chat import DeleteChat
from .methods.delete_message import DeleteMessage
from .methods.delete_pin_message import DeletePinMessage
from .methods.download_media import DownloadMedia
from .methods.edit_chat import EditChat
from .methods.edit_message import EditMessage
from .methods.get_chat_by_id import GetChatById
from .methods.get_chat_by_link import GetChatByLink
from .methods.get_chats import GetChats
from .methods.get_list_admin_chat import GetListAdminChat
from .methods.get_me import GetMe
from .methods.get_me_from_chat import GetMeFromChat
from .methods.get_members_chat import GetMembersChat
from .methods.get_messages import GetMessages
from .methods.get_pinned_message import GetPinnedMessage
from .methods.get_updates import GetUpdates
from .methods.get_upload_url import GetUploadURL
from .methods.get_video import GetVideo
from .methods.pin_message import PinMessage
from .methods.remove_admin import RemoveAdmin
from .methods.remove_member_chat import RemoveMemberChat
from .methods.send_action import SendAction
from .methods.send_callback import SendCallback
from .methods.send_message import SendMessage
from .connection.base import BaseConnection
if TYPE_CHECKING:
from .types.attachments.attachment import Attachment
from .types.attachments.image import PhotoAttachmentRequestPayload
from .types.attachments.video import Video
from .types.chats import Chat, ChatMember, Chats
from .types.command import BotCommand
from .types.message import Message, Messages, NewMessageLink
from .types.updates import UpdateUnion
from .types.users import ChatAdmin, User
from .methods.types.added_admin_chat import AddedListAdminChat
from .methods.types.added_members_chat import AddedMembersChat
from .methods.types.deleted_bot_from_chat import DeletedBotFromChat
from .methods.types.deleted_chat import DeletedChat
from .methods.types.deleted_message import DeletedMessage
from .methods.types.deleted_pin_message import DeletedPinMessage
from .methods.types.edited_message import EditedMessage
from .methods.types.getted_list_admin_chat import GettedListAdminChat
from .methods.types.getted_members_chat import GettedMembersChat
from .methods.types.getted_pineed_message import GettedPin
from .methods.types.getted_upload_url import GettedUploadUrl
from .methods.types.pinned_message import PinnedMessage
from .methods.types.removed_admin import RemovedAdmin
from .methods.types.removed_member_chat import RemovedMemberChat
from .methods.types.sended_action import SendedAction
from .methods.types.sended_callback import SendedCallback
from .methods.types.sended_message import SendedMessage
from .types.attachments.video import Video
from .types.chats import Chat, ChatMember, Chats
from .types.updates import UpdateUnion
from .methods.types.added_admin_chat import AddedListAdminChat
from .methods.types.added_members_chat import AddedMembersChat
from .methods.types.deleted_bot_from_chat import DeletedBotFromChat
from .methods.types.deleted_chat import DeletedChat
from .methods.types.deleted_message import DeletedMessage
from .methods.types.deleted_pin_message import DeletedPinMessage
from .methods.types.edited_message import EditedMessage
from .methods.types.getted_list_admin_chat import GettedListAdminChat
from .methods.types.getted_members_chat import GettedMembersChat
from .methods.types.getted_pineed_message import GettedPin
from .methods.types.getted_upload_url import GettedUploadUrl
from .methods.types.pinned_message import PinnedMessage
from .methods.types.removed_admin import RemovedAdmin
from .methods.types.removed_member_chat import RemovedMemberChat
from .methods.types.sended_action import SendedAction
from .methods.types.sended_callback import SendedCallback
from .methods.types.sended_message import SendedMessage
class Bot(BaseConnection):
@ -102,6 +103,12 @@ class Bot(BaseConnection):
self.notify = notify
self.auto_requests = auto_requests
def _resolve_notify(self, notify: Optional[bool]) -> Optional[bool]:
return notify if notify is not None else self.notify
def _resolve_parse_mode(self, mode: Optional[ParseMode]) -> Optional[ParseMode]:
return mode if mode is not None else self.parse_mode
async def send_message(
self,
chat_id: int = None,
@ -133,10 +140,8 @@ class Bot(BaseConnection):
text=text,
attachments=attachments,
link=link,
notify=notify if notify \
else self.notify,
parse_mode=parse_mode if parse_mode \
else self.parse_mode
notify=self._resolve_notify(notify),
parse_mode=self._resolve_parse_mode(notify)
).request()
async def send_action(
@ -187,10 +192,8 @@ class Bot(BaseConnection):
text=text,
attachments=attachments,
link=link,
notify=notify if notify \
else self.notify,
parse_mode=parse_mode if parse_mode \
else self.parse_mode
notify=self._resolve_notify(notify),
parse_mode=self._resolve_parse_mode(notify)
).request()
async def delete_message(
@ -398,8 +401,7 @@ class Bot(BaseConnection):
icon=icon,
title=title,
pin=pin,
notify=notify if notify \
else self.notify,
notify=self._resolve_notify(notify),
).request()
async def get_video(
@ -422,7 +424,7 @@ class Bot(BaseConnection):
async def send_callback(
self,
callback_id: str,
message: 'Message' = None,
message: Message = None,
notification: str = None
) -> SendedCallback:
@ -462,8 +464,7 @@ class Bot(BaseConnection):
bot=self,
chat_id=chat_id,
message_id=message_id,
notify=notify if notify \
else self.notify,
notify=self._resolve_notify(notify),
).request()
async def delete_pin_message(

View File

@ -113,8 +113,8 @@ class BaseConnection:
:return: Сырой .text() ответ от сервера после загрузки файла
"""
with open(path, 'rb') as f:
file_data = f.read()
async with aiofiles.open(path, 'rb') as f:
file_data = await f.read()
basename = os.path.basename(path)
_, ext = os.path.splitext(basename)

View File

@ -1,3 +1,5 @@
import asyncio
from typing import Any, Callable, Dict, List
from fastapi import FastAPI, Request
@ -22,7 +24,8 @@ from .enums.update import UpdateType
from .loggers import logger_dp
app = FastAPI()
webhook_app = FastAPI()
CONNECTION_RETRY_DELAY = 30
class Dispatcher:
@ -39,8 +42,8 @@ class Dispatcher:
self.filters: List[MagicFilter] = []
self.middlewares: List[BaseMiddleware] = []
self.bot = None
self.on_started_func = None
self.bot: Bot = None
self.on_started_func: Callable = None
self.message_created = Event(update_type=UpdateType.MESSAGE_CREATED, router=self)
self.bot_added = Event(update_type=UpdateType.BOT_ADDED, router=self)
@ -230,7 +233,8 @@ class Dispatcher:
for event in processed_events:
await self.handle(event)
except ClientConnectorError:
logger_dp.error(f'Ошибка подключения: {e}')
logger_dp.error(f'Ошибка подключения, жду {CONNECTION_RETRY_DELAY} секунд')
await asyncio.sleep(CONNECTION_RETRY_DELAY)
except Exception as e:
logger_dp.error(f'Общая ошибка при обработке событий: {e}')
@ -246,7 +250,7 @@ class Dispatcher:
await self.__ready(bot)
@app.post('/')
@webhook_app.post('/')
async def _(request: Request):
try:
event_json = await request.json()
@ -262,7 +266,7 @@ class Dispatcher:
except Exception as e:
logger_dp.error(f"Ошибка при обработке события: {event_json['update_type']}: {e}")
config = Config(app=app, host=host, port=port, log_level="critical")
config = Config(app=webhook_app, host=host, port=port, log_level="critical")
server = Server(config)
await server.serve()

View File

@ -1,5 +1,4 @@
from __future__ import annotations
from typing import TYPE_CHECKING
from ..methods.types.sended_callback import SendedCallback
@ -37,7 +36,7 @@ class SendCallback(BaseConnection):
self,
bot: 'Bot',
callback_id: str,
message: 'Message' = None,
message: Message = None,
notification: str = None
):
self.bot = bot

View File

@ -23,10 +23,10 @@ from ..loggers import logger_bot
if TYPE_CHECKING:
from ..bot import Bot
class UploadResponse:
token: str = None
RETRY_DELAY = 2
ATTEMPTS_COUNT = 5
class SendMessage(BaseConnection):
@ -70,6 +70,9 @@ class SendMessage(BaseConnection):
att: InputMedia
):
# очень нестабильный метод независящий от модуля
# ждем обновлений MAX API
"""
Загружает файл вложения и формирует объект AttachmentUpload.
@ -140,11 +143,11 @@ class SendMessage(BaseConnection):
json['attachments'].append(att.model_dump())
if not self.link is None: json['link'] = self.link.model_dump()
if not self.notify is None: json['notify'] = self.notify
json['notify'] = self.notify
if not self.parse_mode is None: json['format'] = self.parse_mode.value
response = None
for attempt in range(5):
for attempt in range(ATTEMPTS_COUNT):
response = await super().request(
method=HTTPMethod.POST,
path=ApiPath.MESSAGES,
@ -155,8 +158,8 @@ class SendMessage(BaseConnection):
if isinstance(response, Error):
if response.raw.get('code') == 'attachment.not.ready':
logger_bot.info(f'Ошибка при отправке загруженного медиа, попытка {attempt+1}, жду 2 секунды')
await asyncio.sleep(2)
logger_bot.info(f'Ошибка при отправке загруженного медиа, попытка {attempt+1}, жду {RETRY_DELAY} секунды')
await asyncio.sleep(RETRY_DELAY)
continue
return response

View File

@ -18,6 +18,7 @@ dependencies = [
"magic_filter>=1.0.0",
"pydantic>=1.8.0",
"uvicorn>=0.15.0",
"aiofiles==24.1.0",
]
[project.urls]