Skip to content

Commit bd96caa

Browse files
authored
DSL implementation of fragments (#235)
1 parent 7236bbd commit bd96caa

File tree

6 files changed

+584
-109
lines changed

6 files changed

+584
-109
lines changed

docs/advanced/dsl_module.rst

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ Variable arguments
164164

165165
To provide variables instead of argument values directly for an operation, you have to:
166166

167-
* Instanciate a :class:`DSLVariableDefinitions <gql.dsl.DSLVariableDefinitions>`::
167+
* Instantiate a :class:`DSLVariableDefinitions <gql.dsl.DSLVariableDefinitions>`::
168168

169169
var = DSLVariableDefinitions()
170170

@@ -252,6 +252,93 @@ It is possible to create an Document with multiple operations::
252252
operation_name_3=DSLMutation( ... ),
253253
)
254254

255+
Fragments
256+
^^^^^^^^^
257+
258+
To define a `Fragment`_, you have to:
259+
260+
* Instantiate a :class:`DSLFragment <gql.dsl.DSLFragment>` with a name::
261+
262+
name_and_appearances = DSLFragment("NameAndAppearances")
263+
264+
* Provide the GraphQL type of the fragment with the
265+
:meth:`on <gql.dsl.DSLFragment.on>` method::
266+
267+
name_and_appearances.on(ds.Character)
268+
269+
* Add children fields using the :meth:`select <gql.dsl.DSLFragment.select>` method::
270+
271+
name_and_appearances.select(ds.Character.name, ds.Character.appearsIn)
272+
273+
Once your fragment is defined, to use it you should:
274+
275+
* select it as a field somewhere in your query::
276+
277+
query_with_fragment = DSLQuery(ds.Query.hero.select(name_and_appearances))
278+
279+
* add it as an argument of :func:`dsl_gql <gql.dsl.dsl_gql>` with your query::
280+
281+
query = dsl_gql(name_and_appearances, query_with_fragment)
282+
283+
The above example will generate the following request::
284+
285+
fragment NameAndAppearances on Character {
286+
name
287+
appearsIn
288+
}
289+
290+
{
291+
hero {
292+
...NameAndAppearances
293+
}
294+
}
295+
296+
Inline Fragments
297+
^^^^^^^^^^^^^^^^
298+
299+
To define an `Inline Fragment`_, you have to:
300+
301+
* Instantiate a :class:`DSLInlineFragment <gql.dsl.DSLInlineFragment>`::
302+
303+
human_fragment = DSLInlineFragment()
304+
305+
* Provide the GraphQL type of the fragment with the
306+
:meth:`on <gql.dsl.DSLInlineFragment.on>` method::
307+
308+
human_fragment.on(ds.Human)
309+
310+
* Add children fields using the :meth:`select <gql.dsl.DSLInlineFragment.select>` method::
311+
312+
human_fragment.select(ds.Human.homePlanet)
313+
314+
Once your inline fragment is defined, to use it you should:
315+
316+
* select it as a field somewhere in your query::
317+
318+
query_with_inline_fragment = ds.Query.hero.args(episode=6).select(
319+
ds.Character.name,
320+
human_fragment
321+
)
322+
323+
The above example will generate the following request::
324+
325+
hero(episode: JEDI) {
326+
name
327+
... on Human {
328+
homePlanet
329+
}
330+
}
331+
332+
Note: because the :meth:`on <gql.dsl.DSLInlineFragment.on>` and
333+
:meth:`select <gql.dsl.DSLInlineFragment.select>` methods return :code:`self`,
334+
this can be written in a concise manner::
335+
336+
query_with_inline_fragment = ds.Query.hero.args(episode=6).select(
337+
ds.Character.name,
338+
DSLInlineFragment().on(ds.Human).select(ds.Human.homePlanet)
339+
)
340+
341+
255342
Executable examples
256343
-------------------
257344

@@ -265,3 +352,5 @@ Sync example
265352

266353
.. literalinclude:: ../code_examples/requests_sync_dsl.py
267354

355+
.. _Fragment: https://graphql.org/learn/queries/#fragments
356+
.. _Inline Fragment: https://graphql.org/learn/queries/#inline-fragments

docs/code_examples/aiohttp_async_dsl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ async def main():
1717
# GQL will fetch the schema just after the establishment of the first session
1818
async with client as session:
1919

20-
# Instanciate the root of the DSL Schema as ds
20+
# Instantiate the root of the DSL Schema as ds
2121
ds = DSLSchema(client.schema)
2222

2323
# Create the query using dynamically generated attributes from ds

docs/code_examples/requests_sync_dsl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# We should have received the schema now that the session is established
1818
assert client.schema is not None
1919

20-
# Instanciate the root of the DSL Schema as ds
20+
# Instantiate the root of the DSL Schema as ds
2121
ds = DSLSchema(client.schema)
2222

2323
# Create the query using dynamically generated attributes from ds

gql/cli.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ def get_execute_args(args: Namespace) -> Dict[str, Any]:
183183

184184

185185
def get_transport(args: Namespace) -> AsyncTransport:
186-
"""Instanciate a transport from the parsed command line arguments
186+
"""Instantiate a transport from the parsed command line arguments
187187
188188
:param args: parsed command line arguments
189189
"""
@@ -196,7 +196,7 @@ def get_transport(args: Namespace) -> AsyncTransport:
196196
# (headers)
197197
transport_args = get_transport_args(args)
198198

199-
# Instanciate transport depending on url scheme
199+
# Instantiate transport depending on url scheme
200200
transport: AsyncTransport
201201
if scheme in ["ws", "wss"]:
202202
from gql.transport.websockets import WebsocketsTransport
@@ -226,7 +226,7 @@ async def main(args: Namespace) -> int:
226226
logging.basicConfig(level=args.loglevel)
227227

228228
try:
229-
# Instanciate transport from command line arguments
229+
# Instantiate transport from command line arguments
230230
transport = get_transport(args)
231231

232232
# Get extra execute parameters from command line arguments

0 commit comments

Comments
 (0)