Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading