Skip to content
This repository was archived by the owner on Sep 6, 2022. It is now read-only.

Commit bd12301

Browse files
authored
Merge pull request #30 from graphql-python/2.0
Adapt code to Graphene 2.0
2 parents 70479ee + e877bc9 commit bd12301

15 files changed

+215
-150
lines changed

README.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ A Google AppEngine integration library for `Graphene <http://graphene-python.org
2020

2121
Upgrade Notes
2222
-------------
23-
If you're upgrading from an older version (pre 1.0 version) please check out the `Graphene Upgrade Guide <https://github.com/graphql-python/graphene/blob/master/UPGRADE-v1.0.md>`
23+
If you're upgrading from an older version (pre 2.0 version)
24+
please check out the `Graphene Upgrade Guide <https://github.com/graphql-python/graphene/blob/master/UPGRADE-v2.0.md>`__.
2425

2526

2627
Installation

examples/starwars/schema.py

+6-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from google.appengine.ext import ndb
22

33
import graphene
4-
from graphene import relay, resolve_only_args
4+
from graphene import relay
55
from graphene_gae import NdbObjectType, NdbConnectionField
66

77
from .data import create_ship
@@ -30,7 +30,7 @@ class Meta:
3030

3131
ships = NdbConnectionField(Ship)
3232

33-
def resolve_ships(self, *_):
33+
def resolve_ships(self, info, **args):
3434
return ShipModel.query().filter(ShipModel.faction_key == self.key)
3535

3636

@@ -43,9 +43,7 @@ class Input:
4343
faction = graphene.Field(Faction)
4444

4545
@classmethod
46-
def mutate_and_get_payload(cls, input, context, info):
47-
ship_name = input.get('ship_name')
48-
faction_id = input.get('faction_id')
46+
def mutate_and_get_payload(cls, root, info, ship_name, faction_id, client_mutation_id=None):
4947
faction_key = ndb.Key(FactionModel, faction_id)
5048
ship = create_ship(ship_name, faction_key)
5149
faction = faction_key.get()
@@ -58,16 +56,13 @@ class Query(graphene.ObjectType):
5856
node = relay.Node.Field()
5957
ships = NdbConnectionField(Ship)
6058

61-
@resolve_only_args
62-
def resolve_ships(self):
59+
def resolve_ships(self, info, **args):
6360
return ShipModel.query()
6461

65-
@resolve_only_args
66-
def resolve_rebels(self):
62+
def resolve_rebels(self, info):
6763
return FactionModel.get_by_id("rebels")
6864

69-
@resolve_only_args
70-
def resolve_empire(self):
65+
def resolve_empire(self, info):
7166
return FactionModel.get_by_id("empire")
7267

7368

graphene_gae/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
)
1010

1111
__author__ = 'Eran Kampf'
12-
__version__ = '1.0.7'
12+
__version__ = '2.0.dev2017073101'
1313

1414
__all__ = [
1515
NdbObjectType,

graphene_gae/ndb/converter.py

+15-16
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def rreplace(s, old, new, occurrence):
2323
return new.join(li)
2424

2525

26-
def convert_ndb_scalar_property(graphene_type, ndb_prop, **kwargs):
26+
def convert_ndb_scalar_property(graphene_type, ndb_prop, registry=None, **kwargs):
2727
kwargs['description'] = "%s %s property" % (ndb_prop._name, graphene_type)
2828
_type = graphene_type
2929

@@ -36,31 +36,31 @@ def convert_ndb_scalar_property(graphene_type, ndb_prop, **kwargs):
3636
return Field(_type, **kwargs)
3737

3838

39-
def convert_ndb_string_property(ndb_prop):
39+
def convert_ndb_string_property(ndb_prop, registry=None):
4040
return convert_ndb_scalar_property(String, ndb_prop)
4141

4242

43-
def convert_ndb_boolean_property(ndb_prop):
43+
def convert_ndb_boolean_property(ndb_prop, registry=None):
4444
return convert_ndb_scalar_property(Boolean, ndb_prop)
4545

4646

47-
def convert_ndb_int_property(ndb_prop):
47+
def convert_ndb_int_property(ndb_prop, registry=None):
4848
return convert_ndb_scalar_property(Int, ndb_prop)
4949

5050

51-
def convert_ndb_float_property(ndb_prop):
51+
def convert_ndb_float_property(ndb_prop, registry=None):
5252
return convert_ndb_scalar_property(Float, ndb_prop)
5353

5454

55-
def convert_ndb_json_property(ndb_prop):
55+
def convert_ndb_json_property(ndb_prop, registry=None):
5656
return Field(JSONString, description=ndb_prop._name)
5757

5858

59-
def convert_ndb_datetime_property(ndb_prop):
59+
def convert_ndb_datetime_property(ndb_prop, registry=None):
6060
return Field(DateTime, description=ndb_prop._name)
6161

6262

63-
def convert_ndb_key_propety(ndb_key_prop):
63+
def convert_ndb_key_propety(ndb_key_prop, registry=None):
6464
"""
6565
Two conventions for handling KeyProperties:
6666
#1.
@@ -94,20 +94,19 @@ def convert_ndb_key_propety(ndb_key_prop):
9494
resolved_prop_name = name
9595

9696
return [
97-
ConversionResult(name=string_prop_name, field=DynamicNdbKeyStringField(ndb_key_prop)),
98-
ConversionResult(name=resolved_prop_name, field=DynamicNdbKeyReferenceField(ndb_key_prop))
97+
ConversionResult(name=string_prop_name, field=DynamicNdbKeyStringField(ndb_key_prop, registry=registry)),
98+
ConversionResult(name=resolved_prop_name, field=DynamicNdbKeyReferenceField(ndb_key_prop, registry=registry))
9999
]
100100

101101

102-
def convert_local_structured_property(ndb_structured_property):
102+
def convert_local_structured_property(ndb_structured_property, registry=None):
103103
is_required = ndb_structured_property._required
104104
is_repeated = ndb_structured_property._repeated
105105
model = ndb_structured_property._modelclass
106106
name = ndb_structured_property._code_name
107107

108108
def dynamic_type():
109-
from .types import NdbObjectTypeMeta
110-
_type = NdbObjectTypeMeta.REGISTRY.get(model.__name__)
109+
_type = registry.get_type_for_model(model)
111110
if not _type:
112111
return None
113112

@@ -123,7 +122,7 @@ def dynamic_type():
123122
return ConversionResult(name=name, field=field)
124123

125124

126-
def convert_computed_property(ndb_computed_prop):
125+
def convert_computed_property(ndb_computed_prop, registry=None):
127126
return convert_ndb_scalar_property(String, ndb_computed_prop)
128127

129128

@@ -143,12 +142,12 @@ def convert_computed_property(ndb_computed_prop):
143142
}
144143

145144

146-
def convert_ndb_property(prop):
145+
def convert_ndb_property(prop, registry=None):
147146
converter_func = converters.get(type(prop))
148147
if not converter_func:
149148
raise Exception("Don't know how to convert NDB field %s (%s)" % (prop._code_name, prop))
150149

151-
field = converter_func(prop)
150+
field = converter_func(prop, registry)
152151
if not field:
153152
raise Exception("Failed to convert NDB propeerty to a GraphQL field %s (%s)" % (prop._code_name, prop))
154153

graphene_gae/ndb/fields.py

+38-19
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@
77

88
from graphql_relay import to_global_id
99
from graphql_relay.connection.connectiontypes import Edge
10-
from graphene import relay, Argument, Boolean, Int, String, Field, List, NonNull, Dynamic
11-
from graphene.relay.connection import PageInfo
10+
from graphene import Argument, Boolean, Int, String, Field, List, NonNull, Dynamic
11+
from graphene.relay import Connection
12+
from graphene.relay.connection import PageInfo, ConnectionField
13+
14+
15+
from .registry import get_global_registry
1216

1317

1418
__author__ = 'ekampf'
@@ -49,7 +53,7 @@ def connection_from_ndb_query(query, args=None, connection_type=None, edge_type=
4953
so pagination will only work if the array is static.
5054
'''
5155
args = args or {}
52-
connection_type = connection_type or relay.Connection
56+
connection_type = connection_type or Connection
5357
edge_type = edge_type or Edge
5458
pageinfo_type = pageinfo_type or PageInfo
5559

@@ -91,7 +95,7 @@ def connection_from_ndb_query(query, args=None, connection_type=None, edge_type=
9195
)
9296

9397

94-
class NdbConnectionField(relay.ConnectionField):
98+
class NdbConnectionField(ConnectionField):
9599
def __init__(self, type, transform_edges=None, *args, **kwargs):
96100
super(NdbConnectionField, self).__init__(
97101
type,
@@ -104,13 +108,23 @@ def __init__(self, type, transform_edges=None, *args, **kwargs):
104108

105109
self.transform_edges = transform_edges
106110

111+
@property
112+
def type(self):
113+
from .types import NdbObjectType
114+
_type = super(ConnectionField, self).type
115+
assert issubclass(_type, NdbObjectType), (
116+
"NdbConnectionField only accepts NdbObjectType types"
117+
)
118+
assert _type._meta.connection, "The type {} doesn't have a connection".format(_type.__name__)
119+
return _type._meta.connection
120+
107121
@property
108122
def model(self):
109123
return self.type._meta.node._meta.model
110124

111125
@staticmethod
112-
def connection_resolver(resolver, connection, model, transform_edges, root, args, context, info):
113-
ndb_query = resolver(root, args, context, info)
126+
def connection_resolver(resolver, connection, model, transform_edges, root, info, **args):
127+
ndb_query = resolver(root, info, **args)
114128
if ndb_query is None:
115129
ndb_query = model.query()
116130

@@ -121,26 +135,29 @@ def connection_resolver(resolver, connection, model, transform_edges, root, args
121135
edge_type=connection.Edge,
122136
pageinfo_type=PageInfo,
123137
transform_edges=transform_edges,
124-
context=context
138+
context=info.context
125139
)
126140

127141
def get_resolver(self, parent_resolver):
128-
return partial(self.connection_resolver, parent_resolver, self.type, self.model, self.transform_edges)
142+
return partial(
143+
self.connection_resolver, parent_resolver, self.type, self.model, self.transform_edges
144+
)
129145

130146

131147
class DynamicNdbKeyStringField(Dynamic):
132-
def __init__(self, ndb_key_prop, *args, **kwargs):
148+
def __init__(self, ndb_key_prop, registry=None, *args, **kwargs):
133149
kind = ndb_key_prop._kind
150+
if not registry:
151+
registry = get_global_registry()
134152

135153
def get_type():
136-
from .types import NdbObjectTypeMeta
137154
kind_name = kind if isinstance(kind, six.string_types) else kind.__name__
138155

139-
if not NdbObjectTypeMeta.REGISTRY.get(kind_name):
156+
_type = registry.get_type_for_model_name(kind_name)
157+
if not _type:
140158
return None
141159

142-
global_type_name = NdbObjectTypeMeta.REGISTRY[kind_name].__name__
143-
return NdbKeyStringField(ndb_key_prop, global_type_name)
160+
return NdbKeyStringField(ndb_key_prop, _type._meta.name)
144161

145162
super(DynamicNdbKeyStringField, self).__init__(
146163
get_type,
@@ -149,13 +166,15 @@ def get_type():
149166

150167

151168
class DynamicNdbKeyReferenceField(Dynamic):
152-
def __init__(self, ndb_key_prop, *args, **kwargs):
169+
def __init__(self, ndb_key_prop, registry=None, *args, **kwargs):
153170
kind = ndb_key_prop._kind
171+
if not registry:
172+
registry = get_global_registry()
154173

155174
def get_type():
156-
from .types import NdbObjectTypeMeta
157175
kind_name = kind if isinstance(kind, six.string_types) else kind.__name__
158-
_type = NdbObjectTypeMeta.REGISTRY.get(kind_name)
176+
177+
_type = registry.get_type_for_model_name(kind_name)
159178
if not _type:
160179
return None
161180

@@ -187,8 +206,8 @@ def __init__(self, ndb_key_prop, graphql_type_name, *args, **kwargs):
187206

188207
super(NdbKeyStringField, self).__init__(_type, *args, **kwargs)
189208

190-
def resolve_key_to_string(self, entity, args, context, info):
191-
is_global_id = not args.get('ndb', False)
209+
def resolve_key_to_string(self, entity, info, ndb=False):
210+
is_global_id = not ndb
192211
key_value = self.__ndb_key_prop._get_user_value(entity)
193212
if not key_value:
194213
return None
@@ -218,7 +237,7 @@ def __init__(self, ndb_key_prop, graphql_type, *args, **kwargs):
218237

219238
super(NdbKeyReferenceField, self).__init__(_type, *args, **kwargs)
220239

221-
def resolve_key_reference(self, entity, args, context, info):
240+
def resolve_key_reference(self, entity, info):
222241
key_value = self.__ndb_key_prop._get_user_value(entity)
223242
if not key_value:
224243
return None

graphene_gae/ndb/registry.py

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
class Registry(object):
2+
3+
def __init__(self):
4+
self._registry = {}
5+
6+
def register(self, cls):
7+
from .types import NdbObjectType
8+
assert issubclass(cls, NdbObjectType), (
9+
'Only classes of type NdbObjectType can be registered, ',
10+
'received "{}"'
11+
).format(cls.__name__)
12+
assert cls._meta.registry == self, 'Registry for a Model have to match.'
13+
self._registry[cls._meta.model] = cls
14+
15+
def get_type_for_model(self, model):
16+
return self._registry.get(model)
17+
18+
def get_type_for_model_name(self, model_name):
19+
for ndb_model, type in self._registry.items():
20+
if ndb_model.__name__ == model_name:
21+
return type
22+
23+
24+
registry = None
25+
26+
27+
def get_global_registry():
28+
global registry
29+
if not registry:
30+
registry = Registry()
31+
return registry
32+
33+
34+
def reset_global_registry():
35+
global registry
36+
registry = None

0 commit comments

Comments
 (0)