Source code for pipeline.infrastructure.renderer.registry

"""
Created on 2 Nov 2018

@author: sjw
"""
import pipeline.infrastructure.logging as logging

LOG = logging.get_logger(__name__)


[docs]class RendererRegistry(object): def __init__(self): # holds registrations of renderers that should be used in all # situations, unless a context-specific registration takes precedence. self.default_map = {} # holds registrations of renderers that should be used in # context-specific situations self.custom_map = {} # holds functions that should be used to return a context-specific # key, which can be used to retrieve the correct renderer for that # context self.selector_fn_map = {}
[docs] def add_renderer(self, task_cls, renderer, key_fn=None, key=None): """ Register a renderer to be used to generate HTML for results from a given task. There are two modes of registration: 1. registration of a context-specific renderer 2. registration of a universal renderer, which wil be used if no context-specific renderer is found Context-specific renderers are registered by supplying key and key_fn arguments. key_fn should be a function that accepts a context and returns a key from it. This key is used to look up the renderer. Specifying a key value of 'X' says 'this renderer should be used for this task if this key_fn returns 'X' for this context'. :param task_cls: the target pipeline Task class :param renderer: the renderer to use for the task :param key: optional key to retrieve this renderer by :param key_fn: optional function that accepts a pipeline context and returns the renderer key :return: """ if key is not None and key_fn is None: msg = ('Renderer registration invalid for {!s}.\n' 'Must supply a renderer selector function when defining a renderer selector key'.format(task_cls)) LOG.error(msg) raise ValueError(msg) # Registering without a key says that the renderer is not context # dependent, and the same renderer should be returned for all context # values. if key is None: self.default_map[task_cls] = renderer else: # Registering with a key says that the renderer is context dependent, # and a function should be used to extract the key value from that # context if task_cls not in self.custom_map: self.custom_map[task_cls] = {} self.custom_map[task_cls][key] = renderer self.selector_fn_map[task_cls] = key_fn
[docs] def get_renderer(self, cls, context, result): """ Get the registered renderer for a class. The pipeline context argument may be passed to a registered function that returns the key for the given context. :param cls: the class to look up :param context: pipeline context :param result: pipeline task result :return: registered renderer class, or KeyError if no renderer was registered """ if cls in self.custom_map: select_fn = self.selector_fn_map[cls] key = select_fn(context, result) if key in self.custom_map[cls]: return self.custom_map[cls][key] # either not a specific renderer or key not found, so return universal # renderer for that task return self.default_map[cls]