wadebug/wa_actions/base.py (59 lines of code) (raw):

# Copyright (c) Facebook, Inc. and its affiliates. # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from __future__ import absolute_import, division, print_function, unicode_literals import traceback import pydash from six import with_metaclass from wadebug.wa_actions.common import common_results """ Register all WAActions classes available in a dict using a metaclasses. If we decide to support only python3.6+ it can be simplified """ registry = {} user_facing_registry = {} class WAActionAlreadyRegisteredError(Exception): pass def register_class(target_class): if target_class.user_facing_name in user_facing_registry: raise WAActionAlreadyRegisteredError( "{} already in use by class {}. " "Choose another user-facing name".format( target_class.user_facing_name, user_facing_registry[target_class.user_facing_name].__name__, ) ) registry[target_class.__name__] = target_class user_facing_registry[target_class.user_facing_name] = target_class class MetaRegistry(type): """Metaclass to store WAActions when instantiating.""" def __new__(metacls, name, bases, class_dict): cls = type.__new__(metacls, name, bases, class_dict) if name != "WAAction" and name not in registry: register_class(cls) return cls class WAAction(with_metaclass(MetaRegistry)): # should be lowercase, no hypens, short and descriptive user_facing_name = "" # A one phrase description of your action short_description = "" # tuples of configuration dependencies of this action # e.g.: ('db.host', 'auth.token') config_dependencies = () def __str__(self): return "{s.user_facing_name}: {s.short_description}".format(s=self) @classmethod def run(cls, config, *args, **kwargs): invalid_dependencies = tuple( c for c in cls.config_dependencies if not pydash.objects.has(config, c) ) if invalid_dependencies: return common_results.missing_config(cls, invalid_dependencies) try: return cls._run(config, *args, **kwargs) except Exception as e: return common_results.wadebug_error(cls, e, traceback.format_exc()) @classmethod def _run(cls, config, *args, **kwargs): raise NotImplementedError("Action not implemented.") def get_all_actions(): from wadebug.wa_actions.implementations.dummy_action import ( DummyOKAction, DummyProblemAction, DummyWADebugErrorAction, ) blacklisted_actions = {DummyOKAction, DummyProblemAction, DummyWADebugErrorAction} ret = [v for v in registry.values() if v not in blacklisted_actions] return ret def get_action_by_classname(name): return registry[name] def get_action_by_name(name): return user_facing_registry[name]