Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DSL implementation of fragments #235

Merged
merged 11 commits into from Sep 12, 2021
91 changes: 90 additions & 1 deletion docs/advanced/dsl_module.rst
Expand Up @@ -164,7 +164,7 @@ Variable arguments

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

* Instanciate a :class:`DSLVariableDefinitions <gql.dsl.DSLVariableDefinitions>`::
* Instantiate a :class:`DSLVariableDefinitions <gql.dsl.DSLVariableDefinitions>`::

var = DSLVariableDefinitions()

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

Fragments
^^^^^^^^^

To define a `Fragment`_, you have to:

* Instantiate a :class:`DSLFragment <gql.dsl.DSLFragment>` with a name::

name_and_appearances = DSLFragment("NameAndAppearances")

* Provide the GraphQL type of the fragment with the
:meth:`on <gql.dsl.DSLFragment.on>` method::

name_and_appearances.on(ds.Character)

* Add children fields using the :meth:`select <gql.dsl.DSLFragment.select>` method::

name_and_appearances.select(ds.Character.name, ds.Character.appearsIn)

Once your fragment is defined, to use it you should:

* select it as a field somewhere in your query::

query_with_fragment = DSLQuery(ds.Query.hero.select(name_and_appearances))

* add it as an argument of :func:`dsl_gql <gql.dsl.dsl_gql>` with your query::

query = dsl_gql(name_and_appearances, query_with_fragment)

The above example will generate the following request::

fragment NameAndAppearances on Character {
name
appearsIn
}

{
hero {
...NameAndAppearances
}
}

Inline Fragments
^^^^^^^^^^^^^^^^

To define an `Inline Fragment`_, you have to:

* Instantiate a :class:`DSLInlineFragment <gql.dsl.DSLInlineFragment>`::

human_fragment = DSLInlineFragment()

* Provide the GraphQL type of the fragment with the
:meth:`on <gql.dsl.DSLInlineFragment.on>` method::

human_fragment.on(ds.Human)

* Add children fields using the :meth:`select <gql.dsl.DSLInlineFragment.select>` method::

human_fragment.select(ds.Human.homePlanet)

Once your inline fragment is defined, to use it you should:

* select it as a field somewhere in your query::

query_with_inline_fragment = ds.Query.hero.args(episode=6).select(
ds.Character.name,
human_fragment
)

The above example will generate the following request::

hero(episode: JEDI) {
name
... on Human {
homePlanet
}
}

Note: because the :meth:`on <gql.dsl.DSLInlineFragment.on>` and
:meth:`select <gql.dsl.DSLInlineFragment.select>` methods return :code:`self`,
this can be written in a concise manner::

query_with_inline_fragment = ds.Query.hero.args(episode=6).select(
ds.Character.name,
DSLInlineFragment().on(ds.Human).select(ds.Human.homePlanet)
)


Executable examples
-------------------

Expand All @@ -265,3 +352,5 @@ Sync example

.. literalinclude:: ../code_examples/requests_sync_dsl.py

.. _Fragment: https://graphql.org/learn/queries/#fragments
.. _Inline Fragment: https://graphql.org/learn/queries/#inline-fragments
2 changes: 1 addition & 1 deletion docs/code_examples/aiohttp_async_dsl.py
Expand Up @@ -17,7 +17,7 @@ async def main():
# GQL will fetch the schema just after the establishment of the first session
async with client as session:

# Instanciate the root of the DSL Schema as ds
# Instantiate the root of the DSL Schema as ds
ds = DSLSchema(client.schema)

# Create the query using dynamically generated attributes from ds
Expand Down
2 changes: 1 addition & 1 deletion docs/code_examples/requests_sync_dsl.py
Expand Up @@ -17,7 +17,7 @@
# We should have received the schema now that the session is established
assert client.schema is not None

# Instanciate the root of the DSL Schema as ds
# Instantiate the root of the DSL Schema as ds
ds = DSLSchema(client.schema)

# Create the query using dynamically generated attributes from ds
Expand Down
6 changes: 3 additions & 3 deletions gql/cli.py
Expand Up @@ -183,7 +183,7 @@ def get_execute_args(args: Namespace) -> Dict[str, Any]:


def get_transport(args: Namespace) -> AsyncTransport:
"""Instanciate a transport from the parsed command line arguments
"""Instantiate a transport from the parsed command line arguments

:param args: parsed command line arguments
"""
Expand All @@ -196,7 +196,7 @@ def get_transport(args: Namespace) -> AsyncTransport:
# (headers)
transport_args = get_transport_args(args)

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

try:
# Instanciate transport from command line arguments
# Instantiate transport from command line arguments
transport = get_transport(args)

# Get extra execute parameters from command line arguments
Expand Down