Skip to content

Commit

Permalink
Closes #18211: Enable dynamic registration of request processors (#18212
Browse files Browse the repository at this point in the history
)

* Closes #18211: Enable dynamic registration of request processors

* Tweak syntax
  • Loading branch information
jeremystretch authored Dec 12, 2024
1 parent dbaa9c1 commit 8e427e5
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 3 deletions.
4 changes: 4 additions & 0 deletions docs/development/application-registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ This key lists all models which have been registered in NetBox which are not des

This store maintains all registered items for plugins, such as navigation menus, template extensions, etc.

### `request_processors`

A list of context managers to invoke when processing a request e.g. in middleware or when executing a background job. Request processors can be registered with the `@register_request_processor` decorator.

### `search`

A dictionary mapping each model (identified by its app and label) to its search index class, if one has been registered for it.
Expand Down
2 changes: 2 additions & 0 deletions netbox/netbox/context_managers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from contextlib import contextmanager

from netbox.context import current_request, events_queue
from netbox.utils import register_request_processor
from extras.events import flush_events


@register_request_processor
@contextmanager
def event_tracking(request):
"""
Expand Down
10 changes: 7 additions & 3 deletions netbox/netbox/middleware.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from contextlib import ExitStack

import logging
import uuid

Expand All @@ -10,7 +12,7 @@
from django.http import Http404, HttpResponseRedirect

from netbox.config import clear_config, get_config
from netbox.context_managers import event_tracking
from netbox.registry import registry
from netbox.views import handler_500
from utilities.api import is_api_request
from utilities.error_handlers import handle_rest_api_exception
Expand All @@ -32,8 +34,10 @@ def __call__(self, request):
# Assign a random unique ID to the request. This will be used for change logging.
request.id = uuid.uuid4()

# Enable the event_tracking context manager and process the request.
with event_tracking(request):
# Apply all registered request processors
with ExitStack() as stack:
for request_processor in registry['request_processors']:
stack.enter_context(request_processor(request))
response = self.get_response(request)

# Check if language cookie should be renewed
Expand Down
1 change: 1 addition & 0 deletions netbox/netbox/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def __delitem__(self, key):
'model_features': dict(),
'models': collections.defaultdict(set),
'plugins': dict(),
'request_processors': list(),
'search': dict(),
'tables': collections.defaultdict(dict),
'views': collections.defaultdict(dict),
Expand Down
10 changes: 10 additions & 0 deletions netbox/netbox/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
__all__ = (
'get_data_backend_choices',
'register_data_backend',
'register_request_processor',
)


Expand All @@ -24,3 +25,12 @@ def _wrapper(cls):
return cls

return _wrapper


def register_request_processor(func):
"""
Decorator for registering a request processor.
"""
registry['request_processors'].append(func)

return func

0 comments on commit 8e427e5

Please sign in to comment.