Rename kaya.session_redis → kaya.session.redis

- Move src/kaya/session_redis/ → src/kaya/session/redis/
- Update pyproject.toml version_file path
- Update all import references (tests, READMEs, root README)
This commit is contained in:
2026-07-23 16:02:56 +00:00
parent 01a54e3fb5
commit 08370c4963
7 changed files with 4 additions and 4 deletions
@@ -0,0 +1,57 @@
import pickle
from typing import Any, Callable, Optional, cast
from redis.asyncio import Redis
from kaya.session import Session, SessionStore
class RedisSessionStore(SessionStore):
"""Redis-backed session store.
Suitable for multi-process and multi-host deployments: session data is
shared between all application instances connected to the same Redis
server.
Server-side expiry is delegated to Redis key TTLs. When ``max_age`` is
provided, active sessions slide the expiry window on each access.
Session data is serialized with ``pickle`` by default, so arbitrary
Python objects can be stored. Custom serializers can be plugged in via
the ``dumps``/``loads`` arguments. Only connect this store to a trusted
Redis server, as pickle deserialization of untrusted data is unsafe.
"""
def __init__(
self,
client: Redis,
prefix: str = "kaya:session:",
dumps: Callable[[dict[str, Any]], bytes] = pickle.dumps,
loads: Callable[[bytes], dict[str, Any]] = pickle.loads,
) -> None:
self._client = client
self._prefix = prefix
self._dumps = dumps
self._loads = loads
def _key(self, session_id: str) -> str:
return f"{self._prefix}{session_id}"
async def load(self, session_id: str, max_age: Optional[int] = None) -> Optional[Session]:
key = self._key(session_id)
payload = await self._client.get(key)
if payload is None:
return None
if max_age is not None:
await self._client.expire(key, max_age)
data = self._loads(cast(bytes, payload))
return Session(session_id, data)
async def save(self, session_id: str, session: Session, max_age: Optional[int] = None) -> None:
payload = self._dumps(dict(session))
await self._client.set(self._key(session_id), payload, ex=max_age)
async def delete(self, session_id: str) -> None:
await self._client.delete(self._key(session_id))