♻️(backend) refactor analytics backend from Protocol to abstract class

Switch the analytics backend interface from a typing Protocol to an
abstract base class, so the contract that backends must implement
is explicit and enforced at instantiation time.
This commit is contained in:
lebaudantoine
2026-07-07 11:20:12 +02:00
committed by aleb_the_flash
parent 3c0ba03976
commit b00c4e5d6d
3 changed files with 10 additions and 9 deletions
+1
View File
@@ -14,6 +14,7 @@ and this project adheres to
- ⬆️(dependencies) update python dependencies
- 💥(summary) remove v1 related code #1362
- ✨(meet) use compatible with summary v2 #1362
- ♻️(backend) refactor analytics backend from Protocol to abstract class
### Fixed
+7 -8
View File
@@ -1,12 +1,13 @@
"""Analytics backend protocol and default no-op implementation."""
from typing import Any, Protocol
from abc import ABC, abstractmethod
from typing import Any
from ..models import User
from .events import AnalyticsEvent
class AnalyticsBackend(Protocol):
class AnalyticsBackend(ABC):
"""
Interface every analytics backend must implement.
@@ -17,11 +18,11 @@ class AnalyticsBackend(Protocol):
ANALYTICS_BACKEND_SETTINGS = {"api_key": "...", "host": "..."}
"""
def __init__(self, **kwargs: Any) -> None: ...
@abstractmethod
def identify(self, user: User, properties: dict[str, Any] | None = None) -> None:
"""Associate traits (email, name, ...) with an identified user."""
@abstractmethod
def capture(
self,
user: User,
@@ -30,16 +31,14 @@ class AnalyticsBackend(Protocol):
) -> None:
"""Record an event performed by an identified user."""
@abstractmethod
def shutdown(self) -> None:
"""Flush pending events. Called on process exit."""
class NoOpAnalytics:
class NoOpAnalytics(AnalyticsBackend):
"""Default backend: silently discards everything."""
def __init__(self, **kwargs: Any) -> None:
"""No-op: accepts and ignores any backend settings kwargs."""
def identify(self, user: User, properties=None) -> None:
"""No-op: discards identify calls."""
+2 -1
View File
@@ -6,12 +6,13 @@ from typing import Any
from posthog import Posthog
from ..models import User
from . import AnalyticsBackend
from .events import AnalyticsEvent
logger = logging.getLogger(__name__)
class PostHogAnalytics:
class PostHogAnalytics(AnalyticsBackend):
"""Send events to PostHog, keyed on the user's primary key (UUID)."""
def __init__(