Improved plugin system

This commit is contained in:
Syrus Akbary 2015-12-09 19:22:54 -08:00
parent cd5d9b8eea
commit dca435a220
4 changed files with 44 additions and 21 deletions

View File

@ -10,7 +10,7 @@ from graphql.core.utils.schema_printer import print_schema
from graphene import signals from graphene import signals
from ..plugins import CamelCase, Plugin from ..plugins import CamelCase, PluginManager
from .classtypes.base import ClassType from .classtypes.base import ClassType
from .types.base import InstanceType from .types.base import InstanceType
@ -34,28 +34,19 @@ class Schema(object):
self.subscription = subscription self.subscription = subscription
self.name = name self.name = name
self.executor = executor self.executor = executor
self.plugins = []
plugins = plugins or [] plugins = plugins or []
if auto_camelcase: if auto_camelcase:
plugins.append(CamelCase()) plugins.append(CamelCase())
for plugin in plugins: self.plugins = PluginManager(self, plugins)
self.add_plugin(plugin)
signals.init_schema.send(self) signals.init_schema.send(self)
def __repr__(self): def __repr__(self):
return '<Schema: %s (%s)>' % (str(self.name), hash(self)) return '<Schema: %s (%s)>' % (str(self.name), hash(self))
def add_plugin(self, plugin): def __getattr__(self, name):
assert isinstance(plugin, Plugin), 'A plugin need to subclass graphene.Plugin and be instantiated' if name in self.plugins:
plugin.contribute_to_schema(self) return getattr(self.plugins, name)
self.plugins.append(plugin) return super(Schema, self).__getattr__(name)
def get_default_namedtype_name(self, value):
for plugin in self.plugins:
if not hasattr(plugin, 'get_default_namedtype_name'):
continue
value = plugin.get_default_namedtype_name(value)
return value
def T(self, _type): def T(self, _type):
if not _type: if not _type:

View File

@ -1,6 +1,6 @@
from .base import Plugin from .base import Plugin, PluginManager
from .camel_case import CamelCase from .camel_case import CamelCase
__all__ = [ __all__ = [
'Plugin', 'CamelCase' 'Plugin', 'PluginManager', 'CamelCase'
] ]

View File

@ -1,7 +1,40 @@
from functools import partial, reduce
class Plugin(object): class Plugin(object):
def contribute_to_schema(self, schema): def contribute_to_schema(self, schema):
self.schema = schema self.schema = schema
def transform_type(self, objecttype):
return objecttype def apply_function(a, b):
return b(a)
class PluginManager(object):
PLUGIN_FUNCTIONS = ('get_default_namedtype_name', )
def __init__(self, schema, plugins=[]):
self.schema = schema
self.plugins = []
for plugin in plugins:
self.add_plugin(plugin)
def add_plugin(self, plugin):
if hasattr(plugin, 'contribute_to_schema'):
plugin.contribute_to_schema(self.schema)
self.plugins.append(plugin)
def get_plugin_functions(self, function):
for plugin in self.plugins:
if not hasattr(plugin, function):
continue
yield getattr(plugin, function)
def __getattr__(self, name):
functions = self.get_plugin_functions(name)
return partial(reduce, apply_function, functions)
def __contains__(self, name):
return name in self.PLUGIN_FUNCTIONS

View File

@ -1,8 +1,7 @@
from ..utils import to_camel_case from ..utils import to_camel_case
from .base import Plugin
class CamelCase(Plugin): class CamelCase(object):
def get_default_namedtype_name(self, value): def get_default_namedtype_name(self, value):
return to_camel_case(value) return to_camel_case(value)