Add config and client injection with test reorganization.
Code Quality Pipeline / code-quality (pull_request) Successful in 52s
PR Title Check / check-title (pull_request) Successful in 6s
Test Python Package / test (pull_request) Successful in 1m3s

Introduce typed config objects, optional adapter injection, and .env loading to simplify testing while preserving env-based defaults for production usage.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Brian Bjarke Jensen
2026-07-05 21:34:14 +02:00
co-authored by Cursor
parent 7ed1b34233
commit 5e32787b90
28 changed files with 645 additions and 377 deletions
+32 -13
View File
@@ -2,13 +2,11 @@
from __future__ import annotations
from typing import cast
import os
from python_utils import check_env
from python_repositories.adapters.connection_aware_adapter import (
ConnectionAwareAdapter,
)
from python_repositories.config import RedisConfig
from python_repositories.interfaces import JsonRepositoryInterface
try:
@@ -29,24 +27,48 @@ class RedisAdapter(JsonRepositoryInterface, ConnectionAwareAdapter):
encoding: str = "UTF-8"
connection_name: str = "Redis"
def __init__(self) -> None:
def __init__(
self,
*,
config: RedisConfig | None = None,
client: redis.Redis | None = None,
) -> None:
super().__init__()
check_env(self.uri_env_var_name)
self._client: redis.Redis | None = None
if client is not None and config is None:
raise ValueError("config is required when client is provided")
if config is None and client is None:
config = RedisConfig.from_env(self.uri_env_var_name)
assert config is not None
self._config = config
self._client_injected = client is not None
self._client: redis.Redis | None = client
self.path: str = RedisPath.root_path()
if self._client_injected:
self._invalidate_health_cache()
def _is_client_ready(self) -> bool:
return self._client is not None
def connect(self) -> None:
"""Connect to the Redis server."""
if self._client_injected:
if self._client is not None:
try:
if not self._client.ping():
raise ConnectionError(
f"Could not connect to Redis at {self._config.uri}"
)
except (redis.ConnectionError, redis.TimeoutError) as exc:
raise ConnectionError(
f"Could not connect to Redis at {self._config.uri}"
) from exc
self._invalidate_health_cache()
return
if self._client is not None:
self._client.close()
self._client = None
self._invalidate_health_cache()
# Prepare arguments
uri = str(os.getenv(self.uri_env_var_name))
# Connect client
uri = self._config.uri
try:
client = redis.Redis.from_url(
url=uri,
@@ -56,16 +78,13 @@ class RedisAdapter(JsonRepositoryInterface, ConnectionAwareAdapter):
raise ConnectionError(f"Could not connect to Redis at {uri}")
except (redis.ConnectionError, redis.TimeoutError) as exc:
raise ConnectionError(f"Could not connect to Redis at {uri}") from exc
# Persist client
self._client = client
self._invalidate_health_cache()
def disconnect(self) -> None:
"""Disconnect from the Redis server."""
# Close connection
if self._client is not None:
if self._client is not None and not self._client_injected:
self._client.close()
# Reset client
self._client = None
self._invalidate_health_cache()