forked from preply/graphene-federation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
entity.py
66 lines (46 loc) · 1.85 KB
/
entity.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
from graphene import List, Union
from graphene.utils.str_converters import to_snake_case
import graphene
from .types import _Any
custom_entities = {}
def register_entity(typename, Type):
custom_entities[typename] = Type
def get_entity_cls():
class _Entity(Union):
class Meta:
types = tuple(custom_entities.values())
return _Entity
def get_entity_query(auto_camelcase):
if not custom_entities:
return
class EntityQuery:
entities = graphene.List(get_entity_cls(), name="_entities", representations=List(_Any))
def resolve_entities(parent, info, representations):
entities = []
for representation in representations:
model = custom_entities[representation["__typename"]]
model_aguments = representation.copy()
model_aguments.pop("__typename")
# todo use schema to identify correct mapping for field names
if auto_camelcase:
model_aguments = {to_snake_case(k): v for k, v in model_aguments.items()}
model_instance = model(**model_aguments)
try:
resolver = getattr(
model, "_%s__resolve_reference" % representation["__typename"])
except AttributeError:
pass
else:
model_instance = resolver(model_instance, info)
entities.append(model_instance)
return entities
return EntityQuery
def key(fields: str):
def decorator(Type):
register_entity(Type.__name__, Type)
existing = getattr(Type, "_sdl", "")
key_sdl = f'@key(fields: "{fields}")'
updated = f"{key_sdl} {existing}" if existing else key_sdl
setattr(Type, '_sdl', updated)
return Type
return decorator