-
Notifications
You must be signed in to change notification settings - Fork 116
Expand file tree
/
Copy pathredis_asyncio.py
More file actions
54 lines (42 loc) · 1.69 KB
/
Copy pathredis_asyncio.py
File metadata and controls
54 lines (42 loc) · 1.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
"""redis.asyncio adapter for the Redis storage driver client."""
from __future__ import annotations
import math
from datetime import timedelta
from typing import TYPE_CHECKING
from external_storage_redis._client import RedisStorageDriverClient
if TYPE_CHECKING:
from redis.asyncio.client import Redis
class _RedisAsyncioStorageDriverClient(RedisStorageDriverClient):
"""Adapter that wraps a ``redis.asyncio.Redis`` client.
The wrapped client must be configured for binary-safe reads and writes,
which means ``decode_responses`` must remain disabled.
"""
def __init__(self, client: Redis) -> None:
"""Wrap a ``redis.asyncio.Redis`` client."""
self._client = client
async def get(self, *, key: str) -> bytes | None:
"""Fetch raw bytes for *key* from Redis."""
value = await self._client.get(key)
if value is None:
return None
if not isinstance(value, bytes):
raise TypeError(
"redis.asyncio client must be configured with decode_responses=False"
)
return value
async def set_if_absent(
self,
*,
key: str,
data: bytes,
ttl: timedelta | None = None,
) -> bool:
"""Atomically set *key* only when it is absent."""
ttl_ms = None
if ttl is not None:
ttl_ms = max(1, math.ceil(ttl.total_seconds() * 1000))
result = await self._client.set(key, data, px=ttl_ms, nx=True)
return bool(result)
def new_redis_asyncio_client(client: Redis) -> RedisStorageDriverClient:
"""Create a driver client from a ``redis.asyncio.Redis`` instance."""
return _RedisAsyncioStorageDriverClient(client)