Skip to main content

async transport-agnostic graphql client

Project description

rath

codecov PyPI version Maintenance Maintainer PyPI pyversions PyPI status PyPI download month Code style: black Checked with mypy Ruff

Inspiration

Rath is a transportation agnostic graphql client for python focused on composability. It utilizes Links to compose GraphQL request logic, similar to the apollo client in typescript. It comes with predefined links to enable transports like aiohttp, websockets and httpx, as well as links to retrieve auth tokens, enable retry logic or validating requests on a schema.

Supported Transports

  • aiohttp
  • httpx
  • websockets (both graphql-ws and subscriptions-transport-ws)

Installation

pip install rath

Usage Example

from rath.links.auth import ComposedAuthLink
from rath.links.aiohttp import AIOHttpLink
from rath.links import compose
from rath import Rath

async def aload_token():
    return "SERVER_TOKEN"


auth = ComposedAuthLink(token_loader=aload_token)
link = AIOHttpLink(endpoint_url="https://countries.trevorblades.com/")


with Rath(link=compose(auth,link)) as rath:
    query = """query {
        countries {
            native
            capital
        }
        }

    """

    result = rath.query(query)
    print(result)

This example composes both the AuthToken and AIOHttp link: During each query the Bearer headers are set to the retrieved token, and the query is sent to the specified endpoint. (Additionally if the servers raises a 401, the token is refreshed and the query is retried)

Async Usage

Rath is build for async usage but uses koil, for async/sync compatibility

from rath.links.auth import ComposedAuthLink
from rath.links.aiohttp import AIOHttpLink
from rath.links import compose
from rath import Rath

async def aload_token():
    return "SERVER_TOKEN"


auth = ComposedAuthLink(token_loader=aload_token)
link = AIOHttpLink(endpoint_url="https://countries.trevorblades.com/")

async def main():

  async with Rath(link=compose(auth,link)) as rath:
      query = """query {
          countries {
              native
              capital
          }
          }

      """

      result = await rath.aquery(query)
      print(result)


asyncio.run(main())

Example Transport Switch

Links allow the composition of additional logic based on your graphql operation. For example you might want to use different grapqhl transports for different kind of operations (e.g using websockets for subscriptions, but using standard http requests for potential caching on queries and mutations). This can be easily accomplished by providing a split link.

from rath.links.auth import ComposedAuthLink
from rath.links.aiohttp import AIOHttpLink
from rath.links.graphql_ws import GraphQLWSLink
from rath.links import compose, split

from rath import Rath

async def aload_token():
    return "SERVER_TOKEN"


auth = ComposedAuthLink(token_loader=aload_token)
link = AIOHttpLink(endpoint_url="https://countries.trevorblades.com/")
ws = GraphQLWSLink(ws_endpoint_url="wss://countries.trevorblades.com/") # 


end_link = split(link, ws, lambda op: op.node.operation != "subscription")


with Rath(link=end_link) as rath:
    query = """query {
        countries {
            native
            capital
        }
        }

    """

    result = rath.query(query) # uses the http link
    print(result)

    subscription = """subscription {
        newCountry {
            native
            capital
        }
        }

    """

    for i in rath.subscribe(subscription): # uses the ws link
        print(i) # will fail because the server does not support subscriptions

  

Included Links

  • Validating Link (validate query against local schema (or introspect the schema))
  • Reconnecting WebsocketLink
  • AioHttpLink (with multi-part upload support)
  • SplitLink (allows to split the terminating link - Subscription into WebsocketLink, Query, Mutation into Aiohttp)
  • AuthTokenLink (Token insertion with automatic refreshs)

Typed Operations

Searching for a solution to generate typed operations for your graphql api? Look no further, rath + turms has you covered. Turms is a graphql code generator that allows you to generate typed operations for your graphql api.

Rath works especially well with turms generated typed operations:

import asyncio
from examples.api.schema import aget_capsules
from rath.rath import Rath
from rath.links.aiohttp import AIOHttpLink
from rath.links.auth import AuthTokenLink
from rath.links.compose import compose


async def token_loader():
    return ""


link = compose(
    AuthTokenLink(token_loader), AIOHttpLink("https://api.spacex.land/graphql/")
)


rath = Rath(
    link=link,
    register=True, # allows global access (singleton-antipattern, but rath has no state)
)


async def main():

    async with rath:
        capsules = await aget_capsules() # fully typed pydantic powered dataclasses generated through turms
        print(capsules)


asyncio.run(main())

This github repository also contains an example client with a turms generated query with the public SpaceX api, as well as a sample of the generated api.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rath-3.10.0.tar.gz (34.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rath-3.10.0-py3-none-any.whl (51.8 kB view details)

Uploaded Python 3

File details

Details for the file rath-3.10.0.tar.gz.

File metadata

  • Download URL: rath-3.10.0.tar.gz
  • Upload date:
  • Size: 34.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for rath-3.10.0.tar.gz
Algorithm Hash digest
SHA256 89385b0c2f3734e202e2ba6e5a7ac7d2c033741e7dd4a77de8d4219de9033ecf
MD5 fe972f47e30f6b57e5482eb0d21015d2
BLAKE2b-256 d96d819fdb8f09732c56703ec5eb252725a3e5a3c77631fa2ecc33e21ee29373

See more details on using hashes here.

File details

Details for the file rath-3.10.0-py3-none-any.whl.

File metadata

  • Download URL: rath-3.10.0-py3-none-any.whl
  • Upload date:
  • Size: 51.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for rath-3.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ae3a6bc2a9e48d78d6890ff6070acc10e3a35f48f54936a740827de1d214e9af
MD5 108bb3accf6581e5e566a463e4742a16
BLAKE2b-256 36c54cb5555ab70cc52175bf8bf06b00ebc642a1231ef1333f1d5373f9f9abfa

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page