Merge branch 'refs/heads/master' into features/django-debug-optimize

This commit is contained in:
Syrus Akbary 2015-12-09 20:18:38 -08:00
commit 345fb40a5e
4 changed files with 60 additions and 39 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:
@ -128,24 +119,9 @@ class Schema(object):
return self._types_names return self._types_names
def execute(self, request='', root=None, args=None, **kwargs): def execute(self, request='', root=None, args=None, **kwargs):
executor = kwargs kwargs = dict(kwargs, request=request, root=root, args=args, schema=self.schema)
executor['root'] = root with self.plugins.context_execution(**kwargs) as execute_kwargs:
executor['args'] = args return self.executor.execute(**execute_kwargs)
executor['schema'] = self.schema
executor['request'] = request
contexts = []
for plugin in self.plugins:
if not hasattr(plugin, 'context_execution'):
continue
context = plugin.context_execution(executor)
executor = context.__enter__()
contexts.append((context, executor))
result = self.executor.execute(
**executor
)
for context, value in contexts[::-1]:
context.__exit__(None, None, None)
return result
def introspect(self): def introspect(self):
return self.execute(introspection_query).data return self.execute(introspection_query).data

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,53 @@
from contextlib import contextmanager
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
@contextmanager
def context_execution(self, **executor):
contexts = []
functions = self.get_plugin_functions('context_execution')
for f in functions:
context = f(executor)
executor = context.__enter__()
contexts.append((context, executor))
yield executor
for context, value in contexts[::-1]:
context.__exit__(None, None, None)

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)