This repository was archived by the owner on Jun 13, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathrequested_fields.py
More file actions
59 lines (49 loc) · 2.02 KB
/
requested_fields.py
File metadata and controls
59 lines (49 loc) · 2.02 KB
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
# This was adapted from <https://github.com/mirumee/ariadne/discussions/1116#discussioncomment-6508603>
from collections.abc import Generator, Iterable
from graphql import GraphQLResolveInfo
from graphql.language import (
FieldNode,
FragmentSpreadNode,
InlineFragmentNode,
SelectionNode,
)
def selected_fields(info: GraphQLResolveInfo) -> set[str]:
"""
Given a GraphQL "sub-query", this recursively collects all the queried fields.
For example, if the original GraphQL query looks like `owner { repository { name } }`,
this would resolve to `repository` and `repository.name`.
This function works by traversing the parts of the GraphQL Query AST which
are exposed to each "resolver".
"""
names: set[str] = set()
for node in info.field_nodes:
if node.selection_set is None:
continue
names.update(_fields_from_selections(info, node.selection_set.selections))
return names
def _fields_from_selections(
info: GraphQLResolveInfo, selections: Iterable[SelectionNode]
) -> Generator[str, None, None]:
for selection in selections:
match selection:
case FieldNode():
name = selection.name.value
yield name
if selection.selection_set is not None:
yield from (
f"{name}.{field}"
for field in _fields_from_selections(
info, selection.selection_set.selections
)
)
case InlineFragmentNode():
yield from _fields_from_selections(
info, selection.selection_set.selections
)
case FragmentSpreadNode():
fragment = info.fragments[selection.name.value]
yield from _fields_from_selections(
info, fragment.selection_set.selections
)
case _:
raise NotImplementedError(f"field type {type(selection)} not supported")