Async usage
The SDK is async-first. AsyncClient is the canonical client; the synchronous
Client is implemented as a facade on top.
Connect
Section titled “Connect”from openapp_sdk import AsyncClient
async with await AsyncClient.connect(api_key="...") as client: status = await client.status.get()The async with block ensures connections and background tasks are
cleaned up. If you manage the lifecycle manually, call
await client.aclose() yourself.
Concurrency
Section titled “Concurrency”All sub-client methods are coroutines; fire them concurrently with
asyncio.gather, asyncio.TaskGroup, or a semaphore:
import asyncio
async def warm_cache(client, org_ids): async with asyncio.TaskGroup() as tg: for oid in org_ids: tg.create_task(client.orgs.get(oid))A single AsyncClient is safe to share across coroutines; the underlying
transport uses a connection pool.
Cancellation
Section titled “Cancellation”Cancelling a coroutine cancels the in-flight request: the underlying HTTP call is aborted, and any retries in progress are cancelled too.
task = asyncio.create_task(client.devices.list())await asyncio.sleep(0.2)task.cancel()Timeouts
Section titled “Timeouts”Per-call timeouts are not currently part of the sub-client API; configure them
globally via Client.connect(request_timeout=...) or wrap individual calls
with asyncio.wait_for:
try: result = await asyncio.wait_for(client.devices.list(), timeout=5.0)except asyncio.TimeoutError: ...Sync facade
Section titled “Sync facade”If your application is synchronous, the top-level Client is a thin wrapper
that runs coroutines on a private event loop in a background thread. It has
the same sub-client surface:
from openapp_sdk import Client
client = Client.connect(api_key="...")print(client.status.get())client.close()Do not mix Client and AsyncClient in the same process for the same token —
they each own a runtime and you’d pay that cost twice.
Using the SDK in Jupyter / IPython
Section titled “Using the SDK in Jupyter / IPython”Jupyter runs on an already-running event loop. Prefer the AsyncClient and
await directly:
from openapp_sdk import AsyncClient
client = await AsyncClient.connect(api_key="...")await client.status.get()If you must use Client from inside an existing loop,
nest_asyncio.apply() is the usual workaround, but we recommend the async
variant instead.
Trio / AnyIO
Section titled “Trio / AnyIO”The SDK’s Python-facing surface uses stdlib asyncio today. Running it under
AnyIO/Trio works for request/response calls (via anyio.from_thread.run)
but is not first-class; open an issue if you want deeper support.