1
1
from inspect import isawaitable
2
+ from typing import Any , Callable , Dict
2
3
4
+ from graphql .error import GraphQLError
5
+ from graphql .pyutils import AwaitableOrValue , inspect
3
6
from graphql .type import (
4
7
GraphQLArgument ,
8
+ GraphQLField ,
9
+ GraphQLFieldMap ,
5
10
GraphQLInputField ,
11
+ GraphQLInputFieldMap ,
6
12
GraphQLInputObjectType ,
7
13
GraphQLNonNull ,
8
14
GraphQLObjectType ,
15
+ GraphQLResolveInfo ,
9
16
GraphQLString ,
10
- GraphQLField ,
17
+ Thunk
11
18
)
12
- from graphql .error import GraphQLError
13
- from graphql .pyutils import inspect
14
19
15
- from ..utils import resolve_maybe_thunk
20
+ MutationFn = Callable [[Dict [str , Any ], GraphQLResolveInfo ], AwaitableOrValue [Any ]]
21
+
22
+
23
+ def resolve_maybe_thunk (thing_or_thunk : Thunk ) -> Any :
24
+ return thing_or_thunk () if callable (thing_or_thunk ) else thing_or_thunk
16
25
17
26
18
27
def mutation_with_client_mutation_id (
19
- name , input_fields , output_fields , mutate_and_get_payload ):
20
- augmented_input_fields = dict (
21
- resolve_maybe_thunk (input_fields ),
22
- clientMutationId = GraphQLInputField (
23
- GraphQLNonNull (GraphQLString )))
24
- augmented_output_fields = dict (
25
- resolve_maybe_thunk (output_fields ),
26
- clientMutationId = GraphQLField (
27
- GraphQLNonNull (GraphQLString )))
28
- input_type = GraphQLInputObjectType (
29
- name + 'Input' ,
30
- fields = augmented_input_fields )
28
+ name : str ,
29
+ input_fields : Thunk [GraphQLInputFieldMap ],
30
+ output_fields : Thunk [GraphQLFieldMap ],
31
+ mutate_and_get_payload : MutationFn ,
32
+ description : str = None ,
33
+ deprecation_reason : str = None ) -> GraphQLField :
34
+ """
35
+ Returns a GraphQLFieldConfig for the specified mutation.
36
+
37
+ The input_fields and output_fields should not include `clientMutationId`,
38
+ as this will be provided automatically.
39
+
40
+ An input object will be created containing the input fields, and an
41
+ object will be created containing the output fields.
42
+
43
+ mutate_and_get_payload will receive a dict with a key for each input field,
44
+ and it should return an object (or a dict) with an attribute (or a key)
45
+ for each output field. It may return synchronously or asynchronously.
46
+ """
47
+ def augmented_input_fields () -> GraphQLInputFieldMap :
48
+ return dict (
49
+ resolve_maybe_thunk (input_fields ),
50
+ clientMutationId = GraphQLInputField (
51
+ GraphQLNonNull (GraphQLString )))
52
+
53
+ def augmented_output_fields () -> GraphQLFieldMap :
54
+ return dict (
55
+ resolve_maybe_thunk (output_fields ),
56
+ clientMutationId = GraphQLField (
57
+ GraphQLNonNull (GraphQLString )))
58
+
31
59
output_type = GraphQLObjectType (
32
60
name + 'Payload' ,
33
61
fields = augmented_output_fields )
34
62
35
- async def resolve (_root , info , ** args ):
36
- input_ = args .get ('input' ) or {}
37
- payload = mutate_and_get_payload (info , ** input_ )
63
+ input_type = GraphQLInputObjectType (
64
+ name + 'Input' ,
65
+ fields = augmented_input_fields )
66
+
67
+ # noinspection PyShadowingBuiltins
68
+ async def resolve (_root , info , input ):
69
+ payload = mutate_and_get_payload (input , info )
38
70
if isawaitable (payload ):
39
71
payload = await payload
40
72
try :
41
- payload .clientMutationId = input_ ['clientMutationId' ]
73
+ payload .clientMutationId = input ['clientMutationId' ]
42
74
except KeyError :
43
75
raise GraphQLError (
44
76
'Cannot set clientMutationId'
@@ -47,5 +79,7 @@ async def resolve(_root, info, **args):
47
79
48
80
return GraphQLField (
49
81
output_type ,
82
+ description = description ,
83
+ deprecation_reason = deprecation_reason ,
50
84
args = {'input' : GraphQLArgument (GraphQLNonNull (input_type ))},
51
85
resolve = resolve )
0 commit comments