(marketing) create tooling to help backend initialization

Like we did for the malware_detection module, we want helpers allowing
use to instantiate a backend without knowing in the code how to do it,
just importing a module and the marketing service is ready to be used.
This commit is contained in:
Manuel Raynaud
2025-12-03 16:36:51 +01:00
parent d326b643e5
commit 48094c2eb8
6 changed files with 122 additions and 0 deletions

View File

@@ -1 +1,17 @@
"""Marketing module."""
from django.utils.functional import LazyObject
from .handler import MarketingHandler
class DefaultMarketing(LazyObject):
"""Lazy object to handle the marketing backend."""
def _setup(self):
"""Configure the marketing backend."""
self._wrapped = marketing_handler()
marketing_handler = MarketingHandler()
marketing = DefaultMarketing()

View File

@@ -0,0 +1,13 @@
"""Marketing exceptions module."""
class MarketingError(Exception):
"""Base exception for all marketing exceptions."""
class MarketingInvalidBackendError(MarketingError):
"""Exception raised when the backend is invalid."""
class ContactCreationError(MarketingError):
"""Exception raised when the contact creation fails."""

View File

@@ -0,0 +1,46 @@
"""marketing backendhandler."""
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.functional import cached_property
from django.utils.module_loading import import_string
from lasuite.marketing.exceptions import MarketingInvalidBackendError
class MarketingHandler:
"""Marketing handler managing the backend instantiation."""
def __init__(self, backend=None):
"""Initialize the marketing handler."""
# backend is an optional dict of marketing backend definitions
# (structured like settings.LASUITE_MARKETING).
self._backend = backend
self._marketing = None
@cached_property
def backend(self):
"""Put in cache the backend properties from the settings."""
if self._backend is None:
try:
self._backend = settings.LASUITE_MARKETING.copy()
except AttributeError as e:
raise ImproperlyConfigured("settings.LASUITE_MARKETING is not configured") from e
return self._backend
def __call__(self):
"""Create if not existing the backend and then return it."""
if self._marketing is None:
self._marketing = self.create_marketing(self.backend)
return self._marketing
def create_marketing(self, params):
"""Instantiate and configure the marketing backend."""
params = params.copy()
backend = params.pop("BACKEND")
parameters = params.pop("PARAMETERS", {})
try:
klass = import_string(backend)
except ImportError as e:
raise MarketingInvalidBackendError(f"Could not find backend {backend!r}: {e}") from e
return klass(**parameters)

View File

@@ -0,0 +1 @@
"""Marketing tests module."""

View File

@@ -0,0 +1,34 @@
"""Test the marketing handler."""
import pytest
from django.core.exceptions import ImproperlyConfigured
from lasuite.marketing.backends.dummy import DummyBackend
from lasuite.marketing.handler import MarketingHandler
def test_marketing_handler_from_settings(settings):
"""Test the marketing handler from the settings."""
settings.LASUITE_MARKETING = {
"BACKEND": "lasuite.marketing.backends.dummy.DummyBackend",
}
handler = MarketingHandler()
assert isinstance(handler(), DummyBackend)
def test_marketing_handler_from_backend():
"""Test the marketing handler from the backend."""
handler = MarketingHandler(
backend={
"BACKEND": "lasuite.marketing.backends.dummy.DummyBackend",
}
)
assert isinstance(handler(), DummyBackend)
def test_marketing_backend_no_config(settings):
"""Test the marketing handler when no config set should raise an error."""
settings.LASUITE_MARKETING = None
handler = MarketingHandler()
with pytest.raises(ImproperlyConfigured):
handler()

View File

@@ -0,0 +1,12 @@
"""Test the marketing lazy handler."""
from lasuite.marketing import marketing
from lasuite.marketing.backends.dummy import DummyBackend
def test_marketing_lazy_handler(settings):
"""Test the marketing lazy handler."""
settings.LASUITE_MARKETING = {
"BACKEND": "lasuite.marketing.backends.dummy.DummyBackend",
}
assert isinstance(marketing, DummyBackend)