Pass context to resolve methods

Also had to add a few deps to tox.ini to make tests run/pass
This commit is contained in:
Daniel Farrell 2016-05-17 17:23:30 -04:00
parent 398088a0c4
commit d3a573cc8a
37 changed files with 75 additions and 75 deletions

View File

@ -36,10 +36,10 @@ class Query(graphene.ObjectType):
ping = graphene.String(description='Ping someone',
to=graphene.String())
def resolve_hello(self, args, info):
def resolve_hello(self, args, context, info):
return 'World'
def resolve_ping(self, args, info):
def resolve_ping(self, args, context, info):
return 'Pinging {}'.format(args.get('to'))
schema = graphene.Schema(query=Query)

View File

@ -46,10 +46,10 @@ Here is one example for get you started:
ping = graphene.String(description='Ping someone',
to=graphene.String())
def resolve_hello(self, args, info):
def resolve_hello(self, args, context, info):
return 'World'
def resolve_ping(self, args, info):
def resolve_ping(self, args, context, info):
return 'Pinging {}'.format(args.get('to'))
schema = graphene.Schema(query=Query)

View File

@ -51,15 +51,12 @@ class Query(ObjectType):
class Meta:
abstract = True
def resolve_all_posts(self, args, info):
def resolve_all_posts(self, args, context, info):
return Post.objects.filter(published=True)
```
## User-based Queryset Filtering
If you are using `graphql-django-view` you can access Django's request object
via `info.request_context`.
```python
from graphene import ObjectType
from graphene.contrib.django.filter import DjangoFilterConnectionField
@ -71,11 +68,11 @@ class Query(ObjectType):
class Meta:
abstract = True
def resolve_my_posts(self, args, info):
if not info.request_context.user.is_authenticated():
def resolve_my_posts(self, args, context, info):
if not context.user.is_authenticated():
return []
else:
return Post.objects.filter(owner=info.request_context.user)
return Post.objects.filter(owner=context.user)
```
If you're using your own view, passing the request context into the schema is
@ -100,13 +97,13 @@ class PostNode(DjangoNode):
only_fields = ('title', 'content')
@classmethod
def get_node(Cls, id, info):
def get_node(Cls, id, context, info):
try:
post = Cls._meta.model.objects.get(id=id)
except Cls._meta.model.DoesNotExist:
return None
if post.published or info.request_context.user is post.owner:
if post.published or context.user is post.owner:
return Cls(instance)
else:
return None

View File

@ -22,7 +22,7 @@ class CreatePerson(graphene.Mutation):
person = graphene.Field('Person')
@classmethod
def mutate(cls, instance, args, info):
def mutate(cls, instance, args, context, info):
person = Person(name=args.get('name'))
ok = True
return CreatePerson(person=person, ok=ok)

View File

@ -23,7 +23,7 @@ class Person(graphene.ObjectType):
last_name = graphene.String()
full_name = graphene.String()
def resolve_full_name(self, args, info):
def resolve_full_name(self, args, context, info):
return '{} {}'.format(self.first_name, self.last_name)
```

View File

@ -33,7 +33,7 @@ import graphene
class Query(graphene.ObjectType):
hello = graphene.String()
def resolve_hello(self, args, info):
def resolve_hello(self, args, context, info):
return 'World'
schema = graphene.Schema(query=Query)

View File

@ -19,7 +19,7 @@ class Ship(relay.Node):
name = graphene.String(description='The name of the ship.')
@classmethod
def get_node(cls, id, info):
def get_node(cls, id, context, info):
return get_ship(id)
```
@ -39,7 +39,7 @@ class Faction(graphene.ObjectType):
name = graphene.String()
ships = relay.ConnectionField(Ship)
def resolve_ships(self, args, info):
def resolve_ships(self, args, context, info):
return []
```
@ -69,7 +69,7 @@ class IntroduceShip(relay.ClientIDMutation):
faction = graphene.Field(Faction)
@classmethod
def mutate_and_get_payload(cls, input, info):
def mutate_and_get_payload(cls, input, context, info):
ship_name = input.get('ship_name')
faction_id = input.get('faction_id')
ship = create_ship(ship_name, faction_id)

View File

@ -4,10 +4,10 @@ class Query(graphene.ObjectType):
hello = graphene.String()
ping = graphene.String(to=graphene.String())
def resolve_hello(self, args, info):
def resolve_hello(self, args, context, info):
return 'World'
def resolve_ping(self, args, info):
def resolve_ping(self, args, context, info):
return 'Pinging {}'.format(args.get('to'))
schema = graphene.Schema(query=Query)

View File

@ -6,7 +6,7 @@ class Ship(relay.Node):
name = graphene.String(description='The name of the ship.')
@classmethod
def get_node(cls, id, info):
def get_node(cls, id, context, info):
return get_ship(id)
class Faction(relay.Node):
@ -21,7 +21,7 @@ class Faction(relay.Node):
return [get_ship(ship_id) for ship_id in self.ships]
@classmethod
def get_node(cls, id, info):
def get_node(cls, id, context, info):
return get_faction(id)
class IntroduceShip(relay.ClientIDMutation):
@ -33,7 +33,7 @@ class IntroduceShip(relay.ClientIDMutation):
faction = graphene.Field(Faction)
@classmethod
def mutate_and_get_payload(cls, input, info):
def mutate_and_get_payload(cls, input, context, info):
ship_name = input.get('ship_name')
faction_id = input.get('faction_id')
ship = create_ship(ship_name, faction_id)

View File

@ -21,7 +21,7 @@ TEAS = [
class Store(graphene.ObjectType):
teas = graphene.List(Tea, order_by=graphene.String())
def resolve_teas(self, args, info):
def resolve_teas(self, args, context, info):
order_by = args.get("order_by")
if order_by == "steepingTime":
return sorted(self.teas, key=lambda tea: tea.steeping_time)
@ -32,7 +32,7 @@ class Store(graphene.ObjectType):
class Query(graphene.ObjectType):
store = graphene.Field(Store)
def resolve_store(self, args, info):
def resolve_store(self, args, context, info):
return Store(teas=TEAS)
schema = graphene.Schema(query=Query)

View File

@ -13,7 +13,7 @@ class Address(graphene.ObjectType):
class Query(graphene.ObjectType):
address = graphene.Field(Address, geo=graphene.Argument(GeoInput))
def resolve_address(self, args, info):
def resolve_address(self, args, context, info):
geo = args.get('geo')
return Address(latlng="({},{})".format(geo.get('lat'), geo.get('lng')))

View File

@ -11,7 +11,7 @@ class Query(graphene.ObjectType):
patron = graphene.Field(Patron)
def resolve_patron(self, args, info):
def resolve_patron(self, args, context, info):
return Patron(id=1, name='Demo')
schema = graphene.Schema(query=Query)

View File

@ -17,7 +17,7 @@ class Ship(DjangoNode):
model = ShipModel
@classmethod
def get_node(cls, id, info):
def get_node(cls, id, context, info):
return Ship(get_ship(id))
@ -33,7 +33,7 @@ class Faction(DjangoNode):
model = FactionModel
@classmethod
def get_node(cls, id, info):
def get_node(cls, id, context, info):
return Faction(get_faction(id))
@ -47,7 +47,7 @@ class IntroduceShip(relay.ClientIDMutation):
faction = graphene.Field(Faction)
@classmethod
def mutate_and_get_payload(cls, input, info):
def mutate_and_get_payload(cls, input, context, info):
ship_name = input.get('ship_name')
faction_id = input.get('faction_id')
ship = create_ship(ship_name, faction_id)

View File

@ -11,7 +11,7 @@ class Ship(relay.Node):
name = graphene.String(description='The name of the ship.')
@classmethod
def get_node(cls, id, info):
def get_node(cls, id, context, info):
return get_ship(id)
@ -27,7 +27,7 @@ class Faction(relay.Node):
return [get_ship(ship_id) for ship_id in self.ships]
@classmethod
def get_node(cls, id, info):
def get_node(cls, id, context, info):
return get_faction(id)
@ -41,7 +41,7 @@ class IntroduceShip(relay.ClientIDMutation):
faction = graphene.Field(Faction)
@classmethod
def mutate_and_get_payload(cls, input, info):
def mutate_and_get_payload(cls, input, context, info):
ship_name = input.get('ship_name')
faction_id = input.get('faction_id')
ship = create_ship(ship_name, faction_id)

View File

@ -33,7 +33,7 @@ class WrapRoot(object):
def _root(self, value):
self._wrapped_root = value
def resolve_debug(self, args, info):
def resolve_debug(self, args, context, info):
return self._wrapped_root.debug()

View File

@ -24,13 +24,13 @@ class DjangoConnectionField(ConnectionField):
else:
return self.model._default_manager
def get_queryset(self, resolved_qs, args, info):
def get_queryset(self, resolved_qs, args, context, info):
return resolved_qs
def from_list(self, connection_type, resolved, args, info):
def from_list(self, connection_type, resolved, args, context, info):
resolved_qs = maybe_queryset(resolved)
qs = self.get_queryset(resolved_qs, args, info)
return super(DjangoConnectionField, self).from_list(connection_type, qs, args, info)
qs = self.get_queryset(resolved_qs, args, context, info)
return super(DjangoConnectionField, self).from_list(connection_type, qs, args, context, info)
class ConnectionOrListField(Field):

View File

@ -21,7 +21,7 @@ class DjangoFilterConnectionField(DjangoConnectionField):
kwargs['args'].update(**self.filtering_args)
super(DjangoFilterConnectionField, self).__init__(type, *args, **kwargs)
def get_queryset(self, qs, args, info):
def get_queryset(self, qs, args, context, info):
filterset_class = self.filterset_class
filter_kwargs = self.get_filter_kwargs(args)
order = self.get_order(args)

View File

@ -124,7 +124,7 @@ def test_should_node():
model = Reporter
@classmethod
def get_node(cls, id, info):
def get_node(cls, id, context, info):
return ReporterNode(Reporter(id=2, first_name='Cookie Monster'))
def resolve_articles(self, *args, **kwargs):
@ -136,7 +136,7 @@ def test_should_node():
model = Article
@classmethod
def get_node(cls, id, info):
def get_node(cls, id, context, info):
return ArticleNode(Article(id=1, headline='Article node', pub_date=datetime.date(2002, 3, 11)))
class Query(graphene.ObjectType):

View File

@ -33,7 +33,7 @@ class Human(DjangoNode):
class Query(graphene.ObjectType):
human = graphene.Field(Human)
def resolve_human(self, args, info):
def resolve_human(self, args, context, info):
return Human()

View File

@ -21,11 +21,11 @@ class SQLAlchemyConnectionField(ConnectionField):
def model(self):
return self.type._meta.model
def from_list(self, connection_type, resolved, args, info):
def from_list(self, connection_type, resolved, args, context, info):
if resolved is DefaultQuery:
resolved = get_query(self.model, info)
query = maybe_query(resolved)
return super(SQLAlchemyConnectionField, self).from_list(connection_type, query, args, info)
return super(SQLAlchemyConnectionField, self).from_list(connection_type, query, args, context, info)
class ConnectionOrListField(Field):

View File

@ -99,7 +99,7 @@ def test_should_node(session):
model = Reporter
@classmethod
def get_node(cls, id, info):
def get_node(cls, id, context, info):
return Reporter(id=2, first_name='Cookie Monster')
def resolve_articles(self, *args, **kwargs):
@ -111,7 +111,7 @@ def test_should_node(session):
model = Article
# @classmethod
# def get_node(cls, id, info):
# def get_node(cls, id, context, info):
# return Article(id=1, headline='Article node')
class Query(graphene.ObjectType):

View File

@ -10,7 +10,7 @@ def test_get_session():
class Query(ObjectType):
x = String()
def resolve_x(self, args, info):
def resolve_x(self, args, context, info):
return get_session(info)
query = '''

View File

@ -104,5 +104,5 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta, FieldsClassType)):
)
@classmethod
def wrap(cls, instance, args, info):
def wrap(cls, instance, args, context, info):
return cls(_root=instance)

View File

@ -16,7 +16,7 @@ class ChangeNumber(graphene.Mutation):
result = graphene.String()
@classmethod
def mutate(cls, instance, args, info):
def mutate(cls, instance, args, context, info):
global my_id
my_id = args.get('to', my_id + 1)
return ChangeNumber(result=my_id)

View File

@ -15,7 +15,7 @@ class Character(Interface):
class Pet(ObjectType):
type = String()
def resolve_type(self, args, info):
def resolve_type(self, args, context, info):
return 'Dog'

View File

@ -8,7 +8,7 @@ class Query(graphene.ObjectType):
class Subscription(graphene.ObjectType):
subscribe_to_foo = graphene.Boolean(id=graphene.Int())
def resolve_subscribe_to_foo(self, args, info):
def resolve_subscribe_to_foo(self, args, context, info):
return args.get('id') == 1

View File

@ -79,7 +79,7 @@ class Field(NamedType, OrderedType):
if hasattr(self.object_type, resolve_fn_name):
return getattr(self.object_type, resolve_fn_name)
def default_getter(instance, args, info):
def default_getter(instance, args, context, info):
value = getattr(instance, self.source or self.attname, self.default)
return maybe_func(value)
return default_getter

View File

@ -132,7 +132,7 @@ def test_inputfield_internal_type():
def test_field_resolve_argument():
def resolver(instance, args, info):
def resolver(instance, args, context, info):
return args.get('first_name')
field = Field(String(), first_name=String(), description='My argument', resolver=resolver)
@ -149,7 +149,7 @@ def test_field_resolve_vars():
class Query(ObjectType):
hello = String(first_name=String())
def resolve_hello(self, args, info):
def resolve_hello(self, args, context, info):
return 'Hello ' + args.get('first_name')
schema = Schema(query=Query)
@ -196,8 +196,8 @@ def test_field_resolve_object():
att = field
att_func = field_func
assert field.resolver(Root, {}, None) is True
assert field.resolver(Root, {}, None) is True
assert field.resolver(Root, {}, None, None) is True
assert field.resolver(Root, {}, None, None) is True
def test_field_resolve_source_object():
@ -215,5 +215,5 @@ def test_field_resolve_source_object():
att = field
att_func = field_func
assert field.resolver(Root, {}, None) is True
assert field.resolver(Root, {}, None) is True
assert field.resolver(Root, {}, None, None) is True
assert field.resolver(Root, {}, None, None) is True

View File

@ -26,16 +26,16 @@ class ConnectionField(Field):
self.connection_type = connection_type
self.edge_type = edge_type
def resolver(self, instance, args, info):
def resolver(self, instance, args, context, info):
schema = info.schema.graphene_schema
connection_type = self.get_type(schema)
resolved = super(ConnectionField, self).resolver(instance, args, info)
resolved = super(ConnectionField, self).resolver(instance, args, context, info)
if isinstance(resolved, connection_type):
return resolved
return self.from_list(connection_type, resolved, args, info)
return self.from_list(connection_type, resolved, args, context, info)
def from_list(self, connection_type, resolved, args, info):
return connection_type.from_list(resolved, args, info)
def from_list(self, connection_type, resolved, args, context, info):
return connection_type.from_list(resolved, args, context, info)
def get_connection_type(self, node):
connection_type = self.connection_type or node.get_connection_type()
@ -96,5 +96,5 @@ class GlobalIDField(Field):
def __init__(self, *args, **kwargs):
super(GlobalIDField, self).__init__(NonNull(ID()), *args, **kwargs)
def resolver(self, instance, args, info):
def resolver(self, instance, args, context, info):
return instance.to_global_id()

View File

@ -19,7 +19,7 @@ class ChangeNumber(relay.ClientIDMutation):
result = graphene.String()
@classmethod
def mutate_and_get_payload(cls, input, info):
def mutate_and_get_payload(cls, input, context, info):
global my_id
my_id = input.get('to', my_id + 1)
return ChangeNumber(result=my_id)

View File

@ -16,7 +16,7 @@ class MyNode(relay.Node):
name = graphene.String()
@classmethod
def get_node(cls, id, info):
def get_node(cls, id, context, info):
return MyNode(id=id, name='mo')
@ -37,7 +37,7 @@ class Query(graphene.ObjectType):
all_my_nodes = relay.ConnectionField(
MyNode, connection_type=MyConnection, customArg=graphene.String())
def resolve_all_my_nodes(self, args, info):
def resolve_all_my_nodes(self, args, context, info):
custom_arg = args.get('customArg')
assert custom_arg == "1"
return [MyNode(name='my')]

View File

@ -11,7 +11,7 @@ class OtherNode(relay.Node):
name = graphene.String()
@classmethod
def get_node(cls, id, info):
def get_node(cls, id, context, info):
pass

View File

@ -87,7 +87,7 @@ class Connection(ObjectType):
{'edge_type': edge_type, 'edges': edges})
@classmethod
def from_list(cls, iterable, args, info):
def from_list(cls, iterable, args, context, info):
assert isinstance(
iterable, Iterable), 'Resolved value from the connection field have to be iterable'
connection = connection_from_list(
@ -192,9 +192,9 @@ class ClientIDMutation(six.with_metaclass(RelayMutationMeta, Mutation)):
abstract = True
@classmethod
def mutate(cls, instance, args, info):
def mutate(cls, instance, args, context, info):
input = args.get('input')
payload = cls.mutate_and_get_payload(input, info)
payload = cls.mutate_and_get_payload(input, context, info)
client_mutation_id = input.get('clientMutationId') or input.get('client_mutation_id')
setattr(payload, 'clientMutationId', client_mutation_id)
return payload

View File

@ -3,6 +3,6 @@ from functools import wraps
def resolve_only_args(func):
@wraps(func)
def inner(self, args, info):
def inner(self, args, context, info):
return func(self, **args)
return inner

View File

@ -9,4 +9,4 @@ def test_resolve_only_args():
my_data = {'one': 1, 'two': 2}
wrapped = resolve_only_args(resolver)
assert wrapped(None, my_data, None) == my_data
assert wrapped(None, my_data, None, None) == my_data

View File

@ -16,5 +16,5 @@ def wrap_resolver_function(func):
if has_context(func):
return func(self, args, context, info)
# For old compatibility
return func(self, args, info)
return func(self, args, context, info)
return inner

View File

@ -14,6 +14,9 @@ deps=
blinker
singledispatch
mock
iso8601
sqlalchemy
sqlalchemy_utils
setenv =
PYTHONPATH = .:{envdir}
commands=