Skip to main content

Quick Start

Let's discover Rath in less than 5 minutes.

Inspiration

Rath is like Apollo, but for python. It adheres to the design principle of Links and enables composing complex GraphQL setups, like seperation of query and subscription endpoints, dynamic token loading, etc.., as well as being compatible with a variety of graphql transports like aiohttp and httpx.

Installation

pip install rath

Design

Rath provides async and sync interfaces to support both programming paradigms, no matter which transport you are using. This allow for example for synchronous iteration of websockets subscriptions. The prefered way of using rath is through context managers, so that clean up code (like closing websocket connections), can be handled automatically.

from rath.links.aiohttp import AioHttpLink
from rath import Rath

link = AioHttpLink(url="https://api.spacex.land/graphql/")


rath = Rath(link=link)

with rath as r

query = """query TestQuery {
capsules {
id
missions {
flight
}
}
}
"""

result = r.query(query)

tip

This example requires aiohttp to be installed.

Subscriptions follow a similar pattern. Just iterate over the results in the subscribe method (actual subscription happens in another thread, so keep alive signals are automatically send). Here the context manager takes care of automatically cleaning up the stateful websocket connection when leaving the context.

from rath.links.aiohttp import AioHttpLink
from rath.links.websocket import WebsocketLink
from rath import Rath

link = WebsocketLink(url="...your subscription service ...")


rath = Rath(link=link)

with rath as r

sub = """subscription NiceEvent {
capsules {
id
missions {
flight
}
}
}
"""

for event in r.subscribe(sub):
print(event)

If you dont want to use a context manager you can also choose to use the connect/disconnect methods:

from rath.links.aiohttp import AioHttpLink
from rath import Rath

link = AioHttpLink(url="https://api.spacex.land/graphql/")


rath = Rath(link=link)
rath.connect()

query = """query TestQuery {
capsules {
id
missions {
flight
}
}
}
"""

result = rath.query(query)


# later
rath.disconnect()

warning

If you choose this approach, make sure that you call disconnect in your code at some stage. Especially when using asynchronous links/transports (supporting subscriptions) in a sync environment,as only on disconnect we will close the threaded loop that these transports required to operate. Otherwise this connection will stay open.

Asyncio

This is the same within an asyncio loop:

from rath.links.aiohttp import AIOHttpLink
from rath import Rath
import asyncio

link = AioHttpLink(url="https://api.spacex.land/graphql/")
rath = Rath(link=link)


async def main():
async with rath as r:

query = """query TestQuery {
capsules {
id
missions {
flight
}
}
}
"""

result = await r.query(query)


asyncio.run(main())

Likewise for subscriptions

from rath.links.aiohttp import AioHttpLink
from rath.links.websocket import WebsocketLink
from rath import Rath

link = WebsocketLink(url="...your subscription service ...")


rath = Rath(link=link)


async def main():
async with rath as r

sub = """subscription NiceEvent {
capsules {
id
missions {
flight
}
}
}
"""

async for event in r.subscribe(sub):
print(event)

asyncio.run(main())
info

In this scenario we are using the asyncio event loop and do not spawn a seperate thread.