2024-05-14 13:25:13 +10:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
from contextlib import suppress
|
2024-07-01 00:10:17 +10:00
|
|
|
from typing import Any, Generic, Optional, TypeVar
|
2024-05-14 13:25:13 +10:00
|
|
|
|
|
|
|
from aiocache import Cache
|
2024-07-01 00:10:17 +10:00
|
|
|
from aiocache.serializers import BaseSerializer
|
|
|
|
from pydantic.type_adapter import TypeAdapter
|
2024-06-22 18:19:39 +10:00
|
|
|
from yarl import URL
|
2024-05-14 13:25:13 +10:00
|
|
|
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
|
|
with suppress(ImportError):
|
|
|
|
import ormsgpack
|
|
|
|
|
|
|
|
|
2024-07-01 00:10:17 +10:00
|
|
|
class OrmsgpackSerializer(BaseSerializer, Generic[T]):
|
2024-05-14 13:25:13 +10:00
|
|
|
DEFAULT_ENCODING = None
|
|
|
|
|
2024-07-01 00:10:17 +10:00
|
|
|
def __init__(self, schema: TypeAdapter[T]):
|
|
|
|
super().__init__()
|
|
|
|
self.schema = schema
|
|
|
|
|
|
|
|
def dumps(self, value: T) -> bytes:
|
|
|
|
return ormsgpack.packb(self.schema.dump_python(value))
|
2024-05-14 13:25:13 +10:00
|
|
|
|
2024-07-01 00:10:17 +10:00
|
|
|
def loads(self, value: Optional[bytes]) -> T | None:
|
2024-05-14 13:25:13 +10:00
|
|
|
if value is None:
|
|
|
|
return None
|
2024-07-01 00:10:17 +10:00
|
|
|
data = ormsgpack.unpackb(value)
|
|
|
|
return self.schema.validate_python(data)
|
2024-05-14 13:25:13 +10:00
|
|
|
|
|
|
|
|
2024-07-01 00:10:17 +10:00
|
|
|
def make_cache(schema: TypeAdapter[T], url: URL, namespace: str = "") -> Cache[T]:
|
2024-06-22 18:19:39 +10:00
|
|
|
backend = Cache.get_scheme_class(url.scheme)
|
2024-05-14 13:25:13 +10:00
|
|
|
if backend == Cache.MEMORY:
|
|
|
|
return Cache(backend)
|
2024-07-01 00:10:17 +10:00
|
|
|
|
2024-06-22 18:19:39 +10:00
|
|
|
kwargs: dict[str, Any] = dict(url.query)
|
2024-05-14 13:25:13 +10:00
|
|
|
|
2024-06-22 18:19:39 +10:00
|
|
|
if url.path:
|
|
|
|
kwargs.update(backend.parse_uri_path(url.path))
|
2024-05-14 13:25:13 +10:00
|
|
|
|
2024-06-22 18:19:39 +10:00
|
|
|
if url.host:
|
|
|
|
kwargs["endpoint"] = url.host
|
2024-05-14 13:25:13 +10:00
|
|
|
|
2024-06-22 18:19:39 +10:00
|
|
|
if url.port:
|
|
|
|
kwargs["port"] = url.port
|
2024-05-14 13:25:13 +10:00
|
|
|
|
2024-06-22 18:19:39 +10:00
|
|
|
if url.password:
|
|
|
|
kwargs["password"] = url.password
|
2024-05-14 13:25:13 +10:00
|
|
|
|
2024-05-14 14:07:25 +10:00
|
|
|
namespace = ":".join(s for s in [kwargs.pop("namespace", ""), namespace] if s)
|
2024-05-14 13:25:13 +10:00
|
|
|
|
2024-07-01 00:10:17 +10:00
|
|
|
serializer = OrmsgpackSerializer(schema)
|
2024-05-14 13:25:13 +10:00
|
|
|
|
2024-07-01 00:10:17 +10:00
|
|
|
return Cache(backend, serializer=serializer, namespace=namespace, **kwargs)
|