aiogram/aiogram/dispatcher/fsm/storage/memory.py
Alex Root Junior 7776cf9cf6
Bot API 5.7 and some new features (#834)
* Update API, added some new features

* Fixed unknown chat_action value

* Separate events from dispatcher messages

* Disabled cache for I18n LazyProxy

* Rework events isolation

* Added chat member status changed filter, update Bot API 5.7, other small changes

* Improve exceptions in chat member status filter

* Fixed tests, covered flags and events isolation modules

* Try to fix flake8 unused type ignore

* Fixed linter error

* Cover chat member updated filter

* Cover chat action sender

* Added docs for chat action util

* Try to fix tests for python <= 3.9

* Fixed headers

* Added docs for flags functionality

* Added docs for chat_member_updated filter

* Added change notes

* Update dependencies and fix mypy checks

* Bump version
2022-02-19 01:45:59 +02:00

75 lines
2.2 KiB
Python

from asyncio import Lock
from collections import defaultdict
from contextlib import asynccontextmanager
from dataclasses import dataclass, field
from typing import Any, AsyncGenerator, DefaultDict, Dict, Hashable, Optional
from aiogram import Bot
from aiogram.dispatcher.fsm.state import State
from aiogram.dispatcher.fsm.storage.base import (
BaseEventIsolation,
BaseStorage,
StateType,
StorageKey,
)
@dataclass
class MemoryStorageRecord:
data: Dict[str, Any] = field(default_factory=dict)
state: Optional[str] = None
class MemoryStorage(BaseStorage):
"""
Default FSM storage, stores all data in :class:`dict` and loss everything on shutdown
.. warning::
Is not recommended using in production in due to you will lose all data
when your bot restarts
"""
def __init__(self) -> None:
self.storage: DefaultDict[StorageKey, MemoryStorageRecord] = defaultdict(
MemoryStorageRecord
)
async def close(self) -> None:
pass
async def set_state(self, bot: Bot, key: StorageKey, state: StateType = None) -> None:
self.storage[key].state = state.state if isinstance(state, State) else state
async def get_state(self, bot: Bot, key: StorageKey) -> Optional[str]:
return self.storage[key].state
async def set_data(self, bot: Bot, key: StorageKey, data: Dict[str, Any]) -> None:
self.storage[key].data = data.copy()
async def get_data(self, bot: Bot, key: StorageKey) -> Dict[str, Any]:
return self.storage[key].data.copy()
class DisabledEventIsolation(BaseEventIsolation):
@asynccontextmanager
async def lock(self, bot: Bot, key: StorageKey) -> AsyncGenerator[None, None]:
yield
async def close(self) -> None:
pass
class SimpleEventIsolation(BaseEventIsolation):
def __init__(self) -> None:
# TODO: Unused locks cleaner is needed
self._locks: DefaultDict[Hashable, Lock] = defaultdict(Lock)
@asynccontextmanager
async def lock(self, bot: Bot, key: StorageKey) -> AsyncGenerator[None, None]:
lock = self._locks[key]
async with lock:
yield
async def close(self) -> None:
self._locks.clear()