gql Python GraphQL Client

repository·master·Indexed 23 days ago

https://github.com/graphql-python/gql

A Python GraphQL client compatible with any GraphQL-compliant implementation. It supports synchronous and asynchronous execution patterns, multiple protocols including HTTP and WebSockets, and operations such as Queries, Mutations, and Subscriptions. Key features include local request validation, file uploads, request batching, a DSL module for dynamic query composition, and a gql-cli for command-line schema downloads and query execution.

Tokens
22.7K
Snippets
46
Records
127
Agent score
82%

What's inside gql

  1. Overview of GQL features

    master

    GQL is a GraphQL client for Python inspired by React-Relay and Apollo-Client. Key features include:

    • Multiple Protocols: Supports http (including multipart for subscriptions) and websockets (Apollo, graphql-ws, Phoenix channels, and AWS AppSync realtime).
    • Validation: Ability to validate requests locally using a provided schema or via introspection.
    • Operations: Supports Queries, Mutations, and Subscriptions.
    • Execution Modes: Supports both sync and async usage.
    • Advanced Capabilities: Supports File uploads, Custom scalars/Enums, Batching requests, and a DSL module for dynamic query composition.
    • CLI: Includes a gql-cli script for executing queries or downloading schemas from the command line.
  2. Handle Python reserved words in GraphQL arguments

    master

    If a GraphQL argument name is a Python reserved word (e.g., for, in, from, if), you cannot use it as a keyword argument. To resolve this, use dictionary unpacking with the ** operator inside the .args() method or when calling the field.

    Instead of ds.Query.field(from=5), use ds.Query.field.args(**{"from": 5}) or ds.Query.field(**{"from": 5}).

  3. Configure Keep-Alives for Apollo and GraphQL-ws protocols

    master

    Keep-alive settings prevent connections from being dropped due to inactivity. The implementation differs by protocol:

    Apollo Protocol

    Supports unidirectional keep-alive (ka) messages from the server to the client. Use keep_alive_timeout to close the transport if no message is received within the specified seconds.

    GraphQL-ws Protocol

    Supports bidirectional ping/pong messages.

    • keep_alive_timeout: Closes the transport if no message is received from the backend within the timeout.
    • ping_interval: The interval (in seconds) at which the client sends pings.
    • pong_timeout: The maximum delay (in seconds) the client waits for a pong response after sending a ping.
  4. Use async transports for asynchronous GraphQL queries

    master

    Async transports in gql utilize underlying asynchronous libraries to allow running GraphQL queries without blocking the execution thread. This is useful for high-concurrency applications or when integrating with existing asyncio workflows.

    Supported async transport implementations include:

    • aiohttp
    • httpx_async
    • websockets
    • aiohttp_websockets
    • phoenix
    • appsync
  5. Handle local GraphQL specification errors

    master

    If gql detects that a query or its results do not conform to the GraphQL specification, it may raise a GraphQLError (from graphql-core).

    Common causes include:

    • The query is syntactically invalid.
    • The query does not match the provided schema.
    • The results received from the backend do not match the schema (specifically when parse_results is set to True).
  6. Understand GQL Transports

    master

    GQL Transports define the mechanism used to establish a connection with a GraphQL backend. They abstract the underlying communication protocols, allowing you to switch between different methods such as HTTP or WebSockets without changing your query logic.

    Transports are categorized into two main types:

    • Sync Transports: For synchronous execution flows.
    • Async Transports: For asynchronous execution flows (using asyncio).
  7. Use synchronous transports in GQL

    master

    Sync transports are designed for use with synchronous libraries and cannot be used in asynchronous contexts. If your application logic is synchronous, you should select a transport based on your preferred underlying HTTP library.

    GQL provides sync transport implementations for:

    • requests
    • httpx

    Note that these transports are not compatible with async/await workflows.

  8. Use gql.transport classes to manage GraphQL communication

    master

    The gql.transport module provides the base abstractions for sending GraphQL queries to a server. You can use different transport implementations depending on whether you need synchronous or asynchronous execution, or if you want to interact with a local schema instead of a remote endpoint.

    Core transport classes include:

    • Transport: The base class for synchronous transport implementations.
    • AsyncTransport: The base class for asynchronous transport implementations.
    • LocalSchemaTransport: A specialized transport used for executing queries against a local schema (e.g., for testing or local development) rather than over a network.
  9. Enable automatic batching of requests

    master

    If your application executes multiple requests independently in a short window (e.g., from different threads in sync code or different asyncio tasks in async code), you can enable automatic batching.

    By defining a batching_interval (in seconds) in your Client configuration, the client will wait for that interval to pass after receiving an execute call. Any other requests received during that interval will be collected and sent together in a single batch request.

  10. Use multipart subscriptions with AIOHTTPTransport

    master

    The AIOHTTPTransport supports subscriptions using the multipart subscription protocol (compatible with Apollo GraphOS Router). The transport sends an Accept header: multipart/mixed;subscriptionSpec="1.0", application/json.

    How it works:

    • The server streams updates as separate parts in a multipart/mixed response.
    • Each part contains a JSON payload: --graphql\nContent-Type: application/json\n\n{"payload": {"data": {...}, "errors": [...]}}.
    • Heartbeats: Empty JSON objects ({}) are automatically filtered out.
    • Errors: GraphQL errors appear inside the payload property; Transport errors appear with a top-level errors field and null payload.
    • End of Stream: The subscription terminates when the server sends the --graphql-- boundary marker.
  11. Compose queries dynamically with the DSL module

    master

    Instead of writing GraphQL queries as raw Python strings, you can use the gql.dsl module to build queries programmatically using a Domain Specific Language (DSL). The DSL is generated from a provided schema using DSLSchema. This approach allows you to construct complex queries using Python object attributes, which can help prevent syntax errors and enable dynamic query construction based on application logic.

    from gql.dsl import DSLSchema, DSLQuery, dsl_gql
    
    # Initialize the DSL schema from your GraphQL schema
    ds = DSLSchema(StarWarsSchema)
    
    # Build the query dynamically
    query = dsl_gql(
        DSLQuery(
            ds.Query.hero.select(
                ds.Character.id,
                ds.Character.name,
                ds.Character.friends.select(ds.Character.name),
            )
        )
    )