Skip to main content

No project description provided

Project description

django_event_observer

django_event_observer is a fully-fledged Django application designed for observing and handling events within your project. It provides a flexible and extensible framework for subscribing to various event types and reacting to them accordingly.

Installation

Install the package using pip:

pip install django_event_observer

Configuration

After installation, add django_event_observer to the INSTALLED_APPS in your Django settings file:

INSTALLED_APPS = [ # ... 'django_event_observer', # ... ]

Default Settings

By default, the DJANGO_EVENT_OBSERVER settings are as follows:

from types import MappingProxyType

DJANGO_EVENT_OBSERVER = MappingProxyType( { "EVENT_MANAGER": "django_event_observer.event_manager.EventManager", "AUTO_OBSERVERS": [], } )

You can override the DJANGO_EVENT_OBSERVER variable in your project’s settings to specify a custom import path for the EventManager or to add automatic observers.

Customizing EventManager

If you need to use a custom EventManager, specify the import path in your settings:

DJANGO_EVENT_OBSERVER = { "EVENT_MANAGER": "my_app.event_manager.CustomEventManager", "AUTO_OBSERVERS": [], }

Automatic Observers

The AUTO_OBSERVERS parameter is a list of dictionaries, each describing an observer. These observers are classes inheriting from django_event_observer.observers.abstract.base.BaseAbstractObserver.

Syntax:

DJANGO_EVENT_OBSERVER = {
    "EVENT_MANAGER": "django_event_observer.event_manager.EventManager",
    "AUTO_OBSERVERS": [
        {
            "CLASS": "my_module.observers.MyObserver",
            "INIT_ARGS": ["arg1", "arg2"],
            "INIT_KWARGS": {"key1": "value1", "key2": "value2"},
            "EVENT_TYPES": ["event_type_1", "event_type_2"],
        },
        # Other observers...
    ],
}
•	"CLASS": A string with the import path to the observer class.
•	"INIT_ARGS": A list of positional arguments for class initialization.
•	"INIT_KWARGS": A dictionary of keyword arguments for class initialization.
•	"EVENT_TYPES": A list of strings representing event types that the observer should subscribe to.

##Usage

Creating a Custom Observer

To create a custom observer, inherit from BaseAbstractObserver and implement the update method:

my_module/observers.py

from django_event_observer.observers.abstract.base import BaseAbstractObserver
from django_event_observer.events.base import BaseEvent

class MyObserver(BaseAbstractObserver):
    def __init__(self, *args, **kwargs):
        super().__init__()
        # Additional initialization...

    def update(self, event: BaseEvent) -> None:
        # Logic to handle the event
        print(f"Received event: {event}")

Definition of BaseAbstractObserver:

django_event_observer/observers/abstract/base.py

from abc import ABC, abstractmethod from ...events.base import BaseEvent

class BaseAbstractObserver(ABC): @abstractmethod def update(self, event: BaseEvent) -> None: ...

Any custom observer must inherit from BaseAbstractObserver and implement the update method, which will be called when an event occurs.

Creating Custom Events

Events should inherit from BaseEvent and can use generics for typing event_data:

my_module/events.py

from django_event_observer.events.base import BaseEvent from typing import Generic, TypeVar

T = TypeVar('T')

class MyEvent(BaseEvent[T], Generic[T]): def init(self, event_type: str, event_data: T): super().init(event_type, event_data) # Additional initialization...

def __str__(self):
    return f"{self.event_type}: {self.event_data}"

Definition of BaseEvent:

django_event_observer/events/base.py

import typing from django.apps import apps

if typing.TYPE_CHECKING: from ..event_manager import EventManager

_EventDataT = typing.TypeVar("_EventDataT")

class BaseEvent(typing.Generic[_EventDataT]): def init(self, event_type: str, event_data: _EventDataT): self._event_manager = apps.get_app_config("django_event_observer").event_manager self.event_type = event_type self.event_data = event_data

def __call__(self):
    self.notify()

def notify(self):
    self._event_manager.notify(self)

def __str__(self):
    return f"{self.event_type}: {self.event_data}"

Accessing EventManager

To subscribe or unsubscribe an observer from specific event types, you need to access the initialized EventManager. It is recommended to do this using the Django applications registry:

from django.apps import apps

event_manager = apps.get_app_config("django_event_observer").event_manager

Subscribing to Events

To subscribe an observer to a specific event type:

from my_module.observers import MyObserver from django.apps import apps

Get the EventManager instance

event_manager = apps.get_app_config("django_event_observer").event_manager

Create an observer instance

observer = MyObserver()

Subscribe the observer to an event type

event_manager.subscribe("my_event_type", observer)

Unsubscribing from Events

To unsubscribe an observer from a specific event type:

Unsubscribe the observer from the event type

event_manager.unsubscribe("my_event_type", observer)

Sending Events

To send an event and notify all subscribed observers, create an event instance and call the notify method:

from my_module.events import MyEvent

Create an event instance

event = MyEvent(event_type="my_event_type", event_data={"key": "value"})

Notify observers

event.notify()

Or you can call the event instance as a function thanks to the call method:

Notify observers by calling the event

event()

You can also use the EventManager directly to notify:

Notify observers via EventManager

event_manager.notify(event)

Full Usage Example

observers.py

from django_event_observer.observers.abstract.base import BaseAbstractObserver from django_event_observer.events.base import BaseEvent

class MyObserver(BaseAbstractObserver): def update(self, event: BaseEvent) -> None: print(f"Observer received event: {event}")

events.py

from django_event_observer.events.base import BaseEvent

class UserRegisteredEvent(BaseEvent[dict]): def init(self, user_data: dict): super().init(event_type="user_registered", event_data=user_data)

def __str__(self):
    return f"UserRegisteredEvent: {self.event_data}"

main.py

from django.apps import apps from my_module.observers import MyObserver from my_module.events import UserRegisteredEvent

Get the EventManager instance

event_manager = apps.get_app_config("django_event_observer").event_manager

Create an observer instance

observer = MyObserver()

Subscribe the observer to the "user_registered" event

event_manager.subscribe("user_registered", observer)

Create a user registration event

user_data = {"username": "john_doe", "email": "john@example.com"} event = UserRegisteredEvent(user_data)

Notify observers

event.notify()

Or call the event as a function

event()

Unsubscribe the observer when no longer needed

event_manager.unsubscribe("user_registered", observer)

Internal Structure of EventManager

The standard EventManager looks like this:

django_event_observer/event_manager.py

from collections import defaultdict import typing from .observers.abstract.base import BaseAbstractObserver from .events.base import BaseEvent

_ObserversT = dict[str, list[BaseAbstractObserver]]

class EventManager: _subscriptions: typing.ClassVar[_ObserversT] = defaultdict(list)

def subscribe(self, event_type: str, observer: BaseAbstractObserver) -> None:
    self._subscriptions[event_type].append(observer)

def unsubscribe(self, event_type: str, observer: BaseAbstractObserver) -> None:
    self._subscriptions[event_type].remove(observer)

def notify(self, event: BaseEvent) -> None:
    for observer in self._subscriptions.get(event.event_type, []):
        observer.update(event)

Additional Information

•	Base Event Class: All events should inherit from django_event_observer.events.base.BaseEvent.
•	EventManager Methods:
•	subscribe(event_type: str, observer: BaseAbstractObserver): Subscribes an observer to an event type.
•	unsubscribe(event_type: str, observer: BaseAbstractObserver): Unsubscribes an observer from an event type.
•	notify(event: BaseEvent): Notifies all observers subscribed to event.event_type.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_event_observer-2024.11.8.tar.gz (9.3 kB view details)

Uploaded Source

Built Distribution

File details

Details for the file django_event_observer-2024.11.8.tar.gz.

File metadata

File hashes

Hashes for django_event_observer-2024.11.8.tar.gz
Algorithm Hash digest
SHA256 c8fd1b9f7ce1280a90ebd43950de0ef400b89b9430d5cec0ef4dfa0096065e57
MD5 aacc7331fe68126f65784cd5bd1b75f8
BLAKE2b-256 554b70077e97194ffc7514adc28b91752e4975346b223ec6cbce5c514fc06c38

See more details on using hashes here.

File details

Details for the file django_event_observer-2024.11.8-py3-none-any.whl.

File metadata

File hashes

Hashes for django_event_observer-2024.11.8-py3-none-any.whl
Algorithm Hash digest
SHA256 1120f95ec74314de09db5f006e24a5252793066ac5b2135e1d2936b612d60abf
MD5 3e4c9183ed4727e500f5ab8700b1e6d6
BLAKE2b-256 824a8e72d043b4bf83f1cea9e2e1d221e206cd8e0d4cb02cc05e12804b6f7fad

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page