refactor: form-core wiring, JWT sessions, slowapi, packaging, frontend rewrite, test declutter

This commit is contained in:
Jonas Miederer 2026-09-28 18:03:07 +02:00
parent 06ab25fb47
commit 03af41e837
74 changed files with 6089 additions and 5183 deletions

View file

@ -2,12 +2,19 @@
Consolidates base_url stripping, header building, per-request client
construction, and HTTPError → domain-error mapping. Subclasses only
declare their error types and endpoint calls.
declare their error types and endpoint calls. Transport-level failures
(connect/timeout, never 4xx) retry with exponential backoff via tenacity.
"""
from __future__ import annotations
import httpx
from tenacity import (
retry,
retry_if_exception_type,
stop_after_attempt,
wait_exponential,
)
class BaseApiClient:
@ -25,3 +32,13 @@ class BaseApiClient:
return httpx.AsyncClient(
base_url=self.base_url, timeout=self.timeout, headers=self._headers()
)
def transport_retry(func): # type: ignore[no-untyped-def]
"""Retry transport errors 3x with backoff; HTTP status errors pass through."""
return retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=0.5, max=4),
retry=retry_if_exception_type((httpx.TransportError, httpx.TimeoutException)),
reraise=True,
)(func)