From b4ad1407967091c5ff91ba881b104d7766d39a2e Mon Sep 17 00:00:00 2001 From: Barcode Betty Date: Tue, 2 Jun 2026 12:57:54 +0000 Subject: [PATCH] Fix mypy typecheck errors and FK format mismatch in test fixtures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three categories of pre-existing CI failure on PR #42: 1. typecheck (mypy src/cartsnitch_api, 9 errors): - src/cartsnitch_api/config.py:89 — Settings() needs required secret args that only exist in env at runtime; suppress with type: ignore[call-arg] - src/cartsnitch_api/cache.py:38 — redis-py returns Any/bytes, normalize to str before returning from get() - src/cartsnitch_api/middleware/rate_limit.py:128,131,134 — three limiter globals were inferred as RedisSlidingWindow on the if branch then re-assigned InMemorySlidingWindow on else; declare them as RateLimitBackend up front - src/cartsnitch_api/middleware/rate_limit.py:181,187 — RateLimitBackend Protocol didn't declare max_requests even though both InMemorySlidingWindow and RedisSlidingWindow expose it; add max_requests: int to the Protocol 2. test (FK constraint on purchases.user_id): - tests/conftest.py:_create_test_user_and_session stored user_id as 32-char hex; test_e2e conftest reads it via raw SQL and wraps in uuid.UUID (36 chars) before passing to Purchase.user_id, so the FK never matched. Switch back to str(uuid.uuid4()) (36 chars) so the stored value and the FK bind value use the same format. 3. Verify lint + format clean. Co-Authored-By: Claude Opus 4.8 --- src/cartsnitch_api/cache.py | 5 ++++- src/cartsnitch_api/config.py | 2 +- src/cartsnitch_api/middleware/rate_limit.py | 5 +++++ tests/conftest.py | 4 ++-- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/cartsnitch_api/cache.py b/src/cartsnitch_api/cache.py index 319cb8d..02ff6d7 100644 --- a/src/cartsnitch_api/cache.py +++ b/src/cartsnitch_api/cache.py @@ -35,7 +35,10 @@ class CacheClient: async def get(self, key: str) -> str | None: if not self._client: return None - return await self._client.get(key) + result = await self._client.get(key) + if result is None: + return None + return str(result) async def set(self, key: str, value: str, ttl_seconds: int = 300) -> None: if not self._client: diff --git a/src/cartsnitch_api/config.py b/src/cartsnitch_api/config.py index c71d753..b82aa37 100644 --- a/src/cartsnitch_api/config.py +++ b/src/cartsnitch_api/config.py @@ -86,4 +86,4 @@ class Settings(BaseSettings): return self -settings = Settings() +settings = Settings() # type: ignore[call-arg] diff --git a/src/cartsnitch_api/middleware/rate_limit.py b/src/cartsnitch_api/middleware/rate_limit.py index af3dd4b..d453ab7 100644 --- a/src/cartsnitch_api/middleware/rate_limit.py +++ b/src/cartsnitch_api/middleware/rate_limit.py @@ -25,6 +25,8 @@ logger = logging.getLogger(__name__) class RateLimitBackend(Protocol): """Protocol for rate limit backends.""" + max_requests: int + async def is_allowed(self, key: str) -> tuple[bool, int, int]: """Check if request is allowed. Returns (allowed, remaining, retry_after).""" @@ -104,6 +106,9 @@ class RedisSlidingWindow: _redis_client: Redis | None = None _use_redis = False +_public_limiter: RateLimitBackend +_auth_limiter: RateLimitBackend +_auth_strict_limiter: RateLimitBackend if settings.rate_limit_redis_enabled: try: diff --git a/tests/conftest.py b/tests/conftest.py index 1342238..4a63aa7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -272,11 +272,11 @@ async def _create_test_user_and_session( Returns (user_dict, session_token). Better-Auth stores the raw token in the DB, so we insert it as-is. """ - user_id = uuid.uuid4().hex + user_id = str(uuid.uuid4()) email = user_overrides.get("email", "test@example.com") display_name = user_overrides.get("display_name", "Test User") session_token = secrets.token_urlsafe(32) - session_id = uuid.uuid4().hex + session_id = str(uuid.uuid4()) now = datetime.now(UTC).isoformat() expires = (datetime.now(UTC) + timedelta(days=7)).isoformat()