Coverage for src/blob_dict/dict/valkey.py: 0%
49 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-03-27 22:31 -0700
« prev ^ index » next coverage.py v7.7.1, created at 2025-03-27 22:31 -0700
1from collections.abc import Iterator
2from datetime import timedelta
3from typing import Any, cast, override
5from valkey import Valkey
7from ..blob import BytesBlob, StrBlob
8from . import BlobDictBase
11class ValkeyBlobDict(BlobDictBase):
12 def __init__(
13 self,
14 *,
15 ttl: timedelta | None = None,
16 str_blob_only: bool = False,
17 ) -> None:
18 super().__init__()
20 self.__r: Valkey = Valkey(
21 decode_responses=True,
22 )
24 self.__ttl_ms: int | None = int(ttl.total_seconds() * 1_000) if ttl else None
26 self.__str_blob_only: bool = str_blob_only
28 @override
29 def __len__(self) -> int:
30 return cast("int", self.__r.dbsize())
32 @override
33 def __contains__(self, key: str) -> bool:
34 return cast("int", self.__r.exists(key)) == 1
36 @override
37 def get(self, key: str, default: BytesBlob | None = None) -> BytesBlob | None:
38 response: Any = self.__r.get(key)
39 if not response:
40 return default
42 s: str = cast("str", response)
43 return (
44 StrBlob(s) if self.__str_blob_only
45 else BytesBlob.from_b64_str(s)
46 )
48 @override
49 def __iter__(self) -> Iterator[str]:
50 for key in self.__r.scan_iter(_type="STRING"):
51 yield cast("str", key)
53 @override
54 def clear(self) -> None:
55 self.__r.flushdb()
57 @override
58 def pop(self, key: str, default: BytesBlob | None = None) -> BytesBlob | None:
59 if response := self.get(key):
60 self.__r.delete(key)
61 return response
63 return default
65 @override
66 def __delitem__(self, key: str) -> None:
67 number_deleted: int = cast("int", self.__r.delete(key))
68 if number_deleted == 0:
69 raise KeyError
71 __BAD_BLOB_CLASS_ERROR_MESSAGE: str = "Must specify blob of type `StrBlob`"
73 @override
74 def __setitem__(self, key: str, blob: BytesBlob) -> None:
75 if self.__str_blob_only and not isinstance(blob, StrBlob):
76 raise TypeError(self.__BAD_BLOB_CLASS_ERROR_MESSAGE)
78 self.__r.set(
79 key,
80 (
81 cast("StrBlob", blob).as_str() if self.__str_blob_only
82 else blob.as_b64_str()
83 ),
84 px=self.__ttl_ms,
85 )