'''
Meta class to auto register new classes
'''
from sqlalchemy.ext.declarative import declarative_base
from abc import ABCMeta
__author__ = 'Elisha Yadgaran'
[docs]class Registry(object):
'''
Importable class to maintain reference to the global registry
'''
def __init__(self):
self.registry = {}
[docs] def register(self, cls):
if cls.__name__ in self.registry:
raise ValueError('Cannot duplicate class in registry: {}'.format(cls.__name__))
self.registry[cls.__name__] = cls
[docs] def get_from_registry(self, class_name):
return self.registry.get(class_name)
[docs] def get(self, class_name):
return self.get_from_registry(class_name)
# Importable registry
# NEED to use consistent import pattern, otherwise will refer to different memory objects
# from meta_register import SIMPLEML_REGISTRY as s1 != from simpleml.persistables.meta_register import SIMPLEML_REGISTRY as s2
SIMPLEML_REGISTRY = Registry()
# Need to explicitly merge metaclasses to avoid conflicts
MetaBase = type(declarative_base())
# Instantiate specific persistable registries for easy lookup of object types
DATASET_REGISTRY = Registry()
PIPELINE_REGISTRY = Registry()
MODEL_REGISTRY = Registry()
METRIC_REGISTRY = Registry()
[docs]class DatasetRegistry(MetaRegistry):
def __new__(cls, clsname, bases, attrs):
newclass = super(DatasetRegistry, cls).__new__(cls, clsname, bases, attrs)
DATASET_REGISTRY.register(newclass)
return newclass
[docs]class PipelineRegistry(MetaRegistry):
def __new__(cls, clsname, bases, attrs):
newclass = super(PipelineRegistry, cls).__new__(cls, clsname, bases, attrs)
PIPELINE_REGISTRY.register(newclass)
return newclass
[docs]class ModelRegistry(MetaRegistry):
def __new__(cls, clsname, bases, attrs):
newclass = super(ModelRegistry, cls).__new__(cls, clsname, bases, attrs)
MODEL_REGISTRY.register(newclass)
return newclass
[docs]class MetricRegistry(MetaRegistry):
def __new__(cls, clsname, bases, attrs):
newclass = super(MetricRegistry, cls).__new__(cls, clsname, bases, attrs)
METRIC_REGISTRY.register(newclass)
return newclass
# Importable registry for all custom keras objects
# Keras has an annoying persistence pattern that only supports native class references
# Custom class objects need to be passed in at load time
KERAS_REGISTRY = Registry()
[docs]class KerasRegistry(ABCMeta):
def __new__(cls, clsname, bases, attrs):
newclass = super(KerasRegistry, cls).__new__(cls, clsname, bases, attrs)
KERAS_REGISTRY.register(newclass)
return newclass