forked from graphql-python/graphene-pydantic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdepartments.py
134 lines (104 loc) · 3.33 KB
/
departments.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import typing as T
import json
import uuid
import datetime
import decimal
import pydantic
import graphene
from graphene_pydantic import PydanticObjectType
class PersonModel(pydantic.BaseModel):
id: uuid.UUID
name: str
class SalaryModel(pydantic.BaseModel):
rating: str
amount: decimal.Decimal
class EmployeeModel(PersonModel):
hired_on: datetime.datetime = None
salary: T.Optional[SalaryModel]
class ManagerModel(EmployeeModel):
team_size: int
class DepartmentModel(pydantic.BaseModel):
id: uuid.UUID
name: str
# This will not work properly in Python 3.6. Since
# ManagerModel is a subclass of EmployeeModel, 3.6's
# typing implementation throws away the ManagerModel
# annotation.
employees: T.List[T.Union[ManagerModel, EmployeeModel]]
# Graphene mappings to the above models...
class Salary(PydanticObjectType):
class Meta:
model = SalaryModel
class Employee(PydanticObjectType):
class Meta:
model = EmployeeModel
# NOTE: This is necessary for the GraphQL Union to be resolved correctly,
# where DepartmentModel has a list of Managers / Employees
@classmethod
def is_type_of(cls, root, info):
return isinstance(root, (cls, EmployeeModel))
class Manager(PydanticObjectType):
class Meta:
model = ManagerModel
# NOTE: This is necessary for the GraphQL Union to be resolved correctly
# where DepartmentModel has a list of Managers / Employees
@classmethod
def is_type_of(cls, root, info):
return isinstance(root, (cls, ManagerModel))
class Department(PydanticObjectType):
class Meta:
model = DepartmentModel
class Query(graphene.ObjectType):
list_departments = graphene.List(Department)
def resolve_list_departments(self, info):
"""Dummy resolver that creates a tree of Pydantic objects"""
return [
DepartmentModel(
id=uuid.uuid4(),
name="Administration",
employees=[
ManagerModel(
id=uuid.uuid4(),
name="Jason",
salary=SalaryModel(rating="GS-11", amount=95000),
team_size=2,
),
EmployeeModel(
id=uuid.uuid4(),
name="Carmen",
salary=SalaryModel(rating="GS-9", amount=75000.23),
hired_on=datetime.datetime(2019, 1, 1, 15, 26),
),
EmployeeModel(id=uuid.uuid4(), name="Derek"),
],
)
]
if __name__ == "__main__":
schema = graphene.Schema(query=Query)
query = """
query {
listDepartments {
id,
name,
employees {
...on Employee {
id
name
hiredOn
salary { rating }
}
...on Manager {
name
salary {
rating
amount
}
teamSize
}
}
}
}
"""
result = schema.execute(query)
print(result.errors)
print(json.dumps(result.data, indent=2))