from getstream import AsyncStream
client = AsyncStream(api_key="your-api-key", api_secret="your-api-secret")Overview
The Python SDK ships an async client alongside the synchronous one. Reach for it when your backend already runs on an async stack (FastAPI, aiohttp, or anything built on asyncio), or when you need to issue many Stream calls concurrently without tying up a thread per request. The async client mirrors the synchronous client: every network call becomes a coroutine you await.
Initializing the async client
Import AsyncStream and construct it exactly like the synchronous Stream client:
It also reads STREAM_API_KEY and STREAM_API_SECRET from environment variables, so you can construct it with no arguments:
client = AsyncStream()If you already have a synchronous Stream instance, convert it with as_async():
from getstream import Stream
client = Stream(api_key="your-api-key", api_secret="your-api-secret").as_async()Making async calls
The API surface is identical to the synchronous client, except each network call is now awaited. Here is the getting-started flow rewritten for async:
import asyncio
from getstream import AsyncStream
from getstream.models import UserRequest, ChannelInput, MessageRequest
async def main():
async with AsyncStream(api_key="your-api-key", api_secret="your-api-secret") as client:
# Upsert a user
await client.upsert_users(UserRequest(id="john", name="John"))
# Create or join a channel
channel = client.chat.channel("messaging", "hello-world")
await channel.get_or_create(data=ChannelInput(created_by_id="john"))
# Send a message
await channel.send_message(
MessageRequest(text="Hello, Stream!", user_id="john")
)
asyncio.run(main())Note that channel(...) just builds a channel object locally, so it is not awaited. Token creation is also a local operation with no network call, so keep it synchronous:
token = client.create_token(user_id="john")Cleaning up
The async client keeps an open connection pool, so close it when you are done. The async with block above does this for you: on exit it closes the pool along with any chat, video, or moderation sub-clients. If you manage the client's lifetime yourself, call await client.aclose() explicitly:
client = AsyncStream(api_key="your-api-key", api_secret="your-api-secret")
try:
await client.upsert_users(UserRequest(id="john", name="John"))
finally:
await client.aclose()Reuse a single client for the lifetime of your process rather than creating one per request. It maintains one shared connection pool across chat, video, and moderation. See Connection Pooling for tuning the pool.
Running calls concurrently
The payoff of async is concurrency. Use asyncio.gather to run independent calls at the same time instead of awaiting them one after another:
await asyncio.gather(
client.upsert_users(UserRequest(id="john", name="John")),
client.upsert_users(UserRequest(id="jane", name="Jane")),
)The client caps concurrent connections per host, so a large fan-out is queued through the pool rather than opening an unbounded number of sockets.
Things to know
- Token-only clients cannot mint tokens or call admin endpoints. Pass
api_secretfor a server-side client that has full API access. See Tokens & Authentication. - The async client does not support Feeds. Accessing
client.feedsraisesNotImplementedError; use the synchronousStreamclient for Feeds.