# aiogram-mediagroup-handle
**aiogram plugin for handling media groups**
This library supports **aiogram v3 and above**.
## Overview
`aiogram-mediagroup-handle` leverages the `aiogram.Dispatcher.storage` to collect and store
media files in FSM data by `media_group_id`.
FSMStorage ensures data consistency and, combined with data serialization, allows any of
the known storage strategies to be used (not just in-memory).
`aiogram-mediagroup-handle` comes with some utilities:
- **MediaGroupFilter** – A filter to detect media groups.
- **MediaGroup** – A lightweight dataclass object (the actual media group intake) accessible in
FSMStorage data dictionary by `media_group_id`.
### MediaGroup Dataclass reference
```python
from dataclasses import dataclass, field
import typing as t
from aiogram.types import PhotoSize, Audio, Document, Video
from aiogram.enums import ContentType
MediaGroupType = list[InputMediaAudio | InputMediaDocument | InputMediaPhoto | InputMediaVideo]
MediaType = list[PhotoSize] | Audio | Document | Video
@dataclass(slots=True, kw_only=True, frozen=True)
class MediaGroup:
"""Lightweight media group representation."""
caption: t.Optional[str] = None
photos: list[list[PhotoSize]] = field(default_factory=list)
audio: list[Audio] = field(default_factory=list)
documents: list[Document] = field(default_factory=list)
video: list[Video] = field(default_factory=list)
def get_media(self) -> t.Iterator[MediaType]:
"""Return media group iterator"""
...
def as_input_media(self) -> MediaGroupType:
"""Return media group for sending via aiogram.Bot"""
...
@property
def content_type(self) -> ContentType:
"""Return media group content type"""
...
```
## Usage
### Registering the Observer
```python
import aiogram
from aiogram_mediagroup_handle import MediaGroupObserver
dp = aiogram.Dispatcher(...)
observer = MediaGroupObserver()
observer.register(dp)
```
### Handling Media Groups
```python
from aiogram import Router
from aiogram.types import Message
from aiogram.fsm.context import FSMContext
from aiogram_mediagroup_handle import MediaGroupFilter, MediaGroup
router = Router()
@router.message(MediaGroupFilter())
async def media_group_handler(message: Message, state: FSMContext):
data = await state.get_data()
media_data: MediaGroup = data[message.media_group_id]
# Process the media group data here...
# f.e. answer with media
await message.answer_media_group(media=media_data.as_input_media())
```
## Installation
```sh
pip install aiogram-mediagroup-handle
```
## License
[MIT License](LICENSE)
Raw data
{
"_id": null,
"home_page": null,
"name": "aiogram-mediagroup-handle",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "aiogram, album, media group, storage",
"author": null,
"author_email": "andrei-samofalov <andrei.e.samofalov@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/a4/02/9c4621de0aea8366fa40363ca9a2b582456c4e773e42c5118296c73e4966/aiogram_mediagroup_handle-0.1.3.tar.gz",
"platform": null,
"description": "# aiogram-mediagroup-handle\n\n**aiogram plugin for handling media groups**\n\nThis library supports **aiogram v3 and above**.\n\n## Overview\n\n`aiogram-mediagroup-handle` leverages the `aiogram.Dispatcher.storage` to collect and store \nmedia files in FSM data by `media_group_id`.\n\nFSMStorage ensures data consistency and, combined with data serialization, allows any of \nthe known storage strategies to be used (not just in-memory).\n\n`aiogram-mediagroup-handle` comes with some utilities:\n- **MediaGroupFilter** \u2013 A filter to detect media groups.\n- **MediaGroup** \u2013 A lightweight dataclass object (the actual media group intake) accessible in \nFSMStorage data dictionary by `media_group_id`.\n\n### MediaGroup Dataclass reference\n```python\nfrom dataclasses import dataclass, field\nimport typing as t\nfrom aiogram.types import PhotoSize, Audio, Document, Video\nfrom aiogram.enums import ContentType\n\nMediaGroupType = list[InputMediaAudio | InputMediaDocument | InputMediaPhoto | InputMediaVideo]\nMediaType = list[PhotoSize] | Audio | Document | Video\n\n@dataclass(slots=True, kw_only=True, frozen=True)\nclass MediaGroup:\n \"\"\"Lightweight media group representation.\"\"\"\n caption: t.Optional[str] = None\n photos: list[list[PhotoSize]] = field(default_factory=list)\n audio: list[Audio] = field(default_factory=list)\n documents: list[Document] = field(default_factory=list)\n video: list[Video] = field(default_factory=list)\n \n def get_media(self) -> t.Iterator[MediaType]:\n \"\"\"Return media group iterator\"\"\"\n ...\n \n def as_input_media(self) -> MediaGroupType:\n \"\"\"Return media group for sending via aiogram.Bot\"\"\"\n ...\n \n @property\n def content_type(self) -> ContentType:\n \"\"\"Return media group content type\"\"\"\n ...\n\n```\n\n## Usage\n\n### Registering the Observer\n```python\nimport aiogram\nfrom aiogram_mediagroup_handle import MediaGroupObserver\n\ndp = aiogram.Dispatcher(...)\nobserver = MediaGroupObserver()\nobserver.register(dp)\n```\n\n### Handling Media Groups\n```python\nfrom aiogram import Router\nfrom aiogram.types import Message\nfrom aiogram.fsm.context import FSMContext\nfrom aiogram_mediagroup_handle import MediaGroupFilter, MediaGroup\n\nrouter = Router()\n\n@router.message(MediaGroupFilter())\nasync def media_group_handler(message: Message, state: FSMContext):\n data = await state.get_data()\n media_data: MediaGroup = data[message.media_group_id]\n # Process the media group data here...\n \n # f.e. answer with media\n await message.answer_media_group(media=media_data.as_input_media())\n```\n\n## Installation\n```sh\npip install aiogram-mediagroup-handle\n```\n\n## License\n[MIT License](LICENSE)\n\n",
"bugtrack_url": null,
"license": null,
"summary": "aiogram media group observer",
"version": "0.1.3",
"project_urls": {
"Repository": "https://github.com/andrei-samofalov/aiogram-mediagroup"
},
"split_keywords": [
"aiogram",
" album",
" media group",
" storage"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "68493e791f50ebb704f1fa147abd57a78ea3e9b5c95e700c7b5f35fb5384164a",
"md5": "cba7739ad5df76f6b9a511c0d67473ac",
"sha256": "e4b9a010c5b9a7378397d9a7366c74b791a968e986e8a0f76714798919dccc1c"
},
"downloads": -1,
"filename": "aiogram_mediagroup_handle-0.1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "cba7739ad5df76f6b9a511c0d67473ac",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 8072,
"upload_time": "2025-02-21T16:56:09",
"upload_time_iso_8601": "2025-02-21T16:56:09.435483Z",
"url": "https://files.pythonhosted.org/packages/68/49/3e791f50ebb704f1fa147abd57a78ea3e9b5c95e700c7b5f35fb5384164a/aiogram_mediagroup_handle-0.1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a4029c4621de0aea8366fa40363ca9a2b582456c4e773e42c5118296c73e4966",
"md5": "f1946a2002a58cb50145ce2c02eab437",
"sha256": "0edc83010bc783c20bc411cc1733b6be53c43da347b204428939822fc6dd507a"
},
"downloads": -1,
"filename": "aiogram_mediagroup_handle-0.1.3.tar.gz",
"has_sig": false,
"md5_digest": "f1946a2002a58cb50145ce2c02eab437",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 45253,
"upload_time": "2025-02-21T16:56:10",
"upload_time_iso_8601": "2025-02-21T16:56:10.929250Z",
"url": "https://files.pythonhosted.org/packages/a4/02/9c4621de0aea8366fa40363ca9a2b582456c4e773e42c5118296c73e4966/aiogram_mediagroup_handle-0.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-21 16:56:10",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "andrei-samofalov",
"github_project": "aiogram-mediagroup",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "aiogram-mediagroup-handle"
}