1
1
from flask import Flask
2
- from flask_graphql import GraphQLView
3
- from graphene import ObjectType , Field , Float , ID , Int , String
4
- from graphene_federation import build_schema , extend , external , key , provides
2
+ from graphql_server .flask import GraphQLView
3
+ from graphene import ObjectType , Field , Float , ID , Int , String , List , NonNull
4
+ from graphene_federation import build_schema , extend , external , key , provides , requires
5
+
6
+ # -------- data --------
7
+
8
+ dimension = {
9
+ "size" : "small" ,
10
+ "weight" : 1 ,
11
+ "unit" : "kg" ,
12
+ }
13
+
14
+ user = {
15
+
16
+ "name" : "Jane Smith" ,
17
+ "total_products_created" : 1337 ,
18
+ }
19
+
20
+ deprecated_product = {
21
+ "sku" : "apollo-federation-v1" ,
22
+ "package" : "@apollo/federation-v1" ,
23
+ "reason" : "Migrate to Federation V2" ,
24
+ "created_by" : user ,
25
+ }
26
+
27
+ products_research = [
28
+ {
29
+ "study" : {
30
+ "case_number" : "1234" ,
31
+ "description" : "Federation Study" ,
32
+ },
33
+ "outcome" : None ,
34
+ },
35
+ {
36
+ "study" : {
37
+ "case_number" : "1235" ,
38
+ "description" : "Studio Study" ,
39
+ },
40
+ "outcome" : None ,
41
+ },
42
+ ]
43
+
44
+ products = [
45
+ {
46
+ "id" : "apollo-federation" ,
47
+ "sku" : "federation" ,
48
+ "package" : "@apollo/federation" ,
49
+ "variation" : {"id" : "OSS" },
50
+ "dimensions" : dimension ,
51
+ "research" : [products_research [0 ]],
52
+ "created_by" : user ,
53
+ "notes" : None ,
54
+ },
55
+ {
56
+ "id" : "apollo-studio" ,
57
+ "sku" : "studio" ,
58
+ "package" : "" ,
59
+ "variation" : {"id" : "platform" },
60
+ "dimensions" : dimension ,
61
+ "research" : [products_research [1 ]],
62
+ "created_by" : user ,
63
+ "notes" : None ,
64
+ },
65
+ ]
66
+
67
+
68
+ # -------- types --------
5
69
6
70
7
71
@extend (fields = 'email' )
8
72
class User (ObjectType ):
73
+ average_products_created_per_year = requires (field = Int (), fields = ["total_products_created" , "years_of_employment" ])
9
74
email = external (ID (required = True ))
10
- totalProductsCreated = external (Int ())
75
+ name = String ()
76
+ total_products_created = external (Int ())
77
+ years_of_employment = external (Int (required = True ))
78
+
79
+ def resolve_average_products_created_per_year (self , info , * args , ** kwargs ):
80
+ if self .total_products_created and self .years_of_employment :
81
+ return round (self .total_products_created / self .years_of_employment )
82
+
83
+ return None
84
+
85
+ def __resolve_reference (self , info , ** kwargs ):
86
+ if user ['email' ] == self .email :
87
+ total_products = user ['total_products_created' ]
88
+ if self .total_products_created :
89
+ total_products = self .total_products_created
90
+
91
+ return User (
92
+ email = self .email ,
93
+ name = user ['name' ],
94
+ total_products_created = total_products ,
95
+ years_of_employment = self .years_of_employment
96
+ )
11
97
12
- def resolve_total_products_created (parent , info , ** kwargs ):
13
- return 1337
98
+ return self
14
99
15
100
16
101
class ProductVariation (ObjectType ):
17
- id = ID (required = True )
102
+ id = ID (required = True )
18
103
19
104
20
105
class ProductDimension (ObjectType ):
21
106
size = String ()
22
107
weight = Float ()
108
+ unit = String ()
109
+
110
+
111
+ class CaseStudy (ObjectType ):
112
+ case_number = ID (required = True )
113
+ description = String ()
114
+
115
+
116
+ # @key(fields="study { caseNumber }")
117
+ class ProductResearch (ObjectType ):
118
+ study = Field (CaseStudy , required = True )
119
+ outcome = String ()
23
120
24
121
25
122
@key (fields = 'id' )
26
- @key (fields = 'sku package' )
27
- @key (fields = 'sku variation { id }' )
123
+ # @key(fields='sku package')
124
+ # @key(fields='sku variation { id }')
28
125
@provides
29
126
class Product (ObjectType ):
30
127
id = ID (required = True )
31
128
sku = String ()
32
129
package = String ()
33
130
variation = Field (ProductVariation )
34
131
dimensions = Field (ProductDimension )
35
- createdBy = provides (Field (User ), fields = 'totalProductsCreated' )
36
-
37
- def resolve_variation (self , info , ** kwargs ):
38
- print (self )
39
- return get_product_variation (self )
40
-
41
- def resolve_dimensions (self , info , ** kwargs ):
42
- return {'size' : 'small' , 'weight' : 1.0 }
43
-
44
- def resolve_created_by (self , info , ** kwargs ):
45
- {
'email' :
'[email protected] ' ,
'totalProductsCreated' :
1337 }
132
+ created_by = provides (Field (User ), fields = 'total_products_created' )
133
+ notes = String ()
134
+ research = List (NonNull (ProductResearch ), required = True )
46
135
47
136
def __resolve_reference (self , info , ** kwargs ):
48
137
if self .id :
@@ -53,60 +142,60 @@ def __resolve_reference(self, info, **kwargs):
53
142
return Product (** get_product_by_sku_and_variation (self .sku , self .variation ))
54
143
55
144
145
+ # @key(fields="sku package")
146
+ class DeprecatedProduct (ObjectType ):
147
+ sku = String (required = True )
148
+ package = String (required = True )
149
+ reason = String ()
150
+ createdBy = Field (User )
151
+
152
+
56
153
class Query (ObjectType ):
57
154
product = Field (Product , id = ID (required = True ))
155
+ deprecated_product = Field (DeprecatedProduct , sku = String (required = True ), package = String (required = True ),
156
+ deprecation_reason = "Use product query instead" )
58
157
59
158
def resolve_product (self , info , id ):
60
159
return get_product_by_id (id )
61
160
62
-
63
- schema = build_schema (Query , types = [Product ])
64
- app = Flask (__name__ )
65
- app .add_url_rule ('/' , view_func = GraphQLView .as_view (
66
- 'graphql' ,
67
- schema = schema
68
- ))
69
-
70
- products = [
71
- {
72
- "id" : "apollo-federation" ,
73
- "sku" : "federation" ,
74
- "package" : "@apollo/federation" ,
75
- "variation" : "OSS" ,
76
- },
77
- {
78
- "id" : "apollo-studio" ,
79
- "sku" : "studio" ,
80
- "package" : "" ,
81
- "variation" : "platform" ,
82
- },
83
- ]
161
+ def resolve_deprecated_product (self , info , sku , package ):
162
+ return get_deprecated_product_by_sku_and_package (sku , package )
84
163
85
164
86
- def get_product_variation (reference ):
87
- if isinstance (reference , Product ) and reference .variation :
88
- return {'id' : reference .variation }
89
- elif reference ["variation" ]:
90
- return {'id' : reference ["variation" ]}
91
- variation = next ((product for product in products if product ['id' ]
92
- == reference .id ), None )
93
- return {'id' : variation }
165
+ # -------- resolvers --------
94
166
95
167
96
168
def get_product_by_id (id ):
97
169
return next ((product for product in products if product ['id' ]
98
- == id ), None )
170
+ == id ), None )
99
171
100
172
101
173
def get_product_by_sku_and_package (sku , package ):
102
174
return next ((product for product in products if product ['sku' ]
103
- == sku and product ['package' ] == package ), None )
175
+ == sku and product ['package' ] == package ), None )
104
176
105
177
106
178
def get_product_by_sku_and_variation (sku , variation ):
107
179
return next ((product for product in products if product ['sku' ]
108
- == sku and product ['variation' ] == variation ), None )
180
+ == sku and product ['variation' ] == variation ), None )
181
+
182
+
183
+ def get_deprecated_product_by_sku_and_package (sku , package ):
184
+ if deprecated_product ['sku' ] == sku and deprecated_product ['package' ] == package :
185
+ return deprecated_product
186
+
187
+ return None
109
188
110
189
190
+ # -------- server --------
191
+
192
+
193
+ schema = build_schema (query = Query )
194
+ app = Flask (__name__ )
195
+ app .add_url_rule ('/' , view_func = GraphQLView .as_view (
196
+ 'graphql' ,
197
+ schema = schema
198
+ ))
199
+
111
200
if __name__ == '__main__' :
112
201
app .run (host = '0.0.0.0' , port = 4001 )
0 commit comments