Sync vs async
brain-db-sdk is synchronous. How both clients block, and how to run them under concurrency without an async client.
The SDK is synchronous
BrainHttpClient and BrainClient both block: every verb call returns a
decoded result, not a coroutine or a future. There is no AsyncBrainClient,
no await, and no event-loop integration in the package.
If you need to call Brain from an asyncio stack, run the blocking call in a
worker thread with asyncio.to_thread(...) (or a ThreadPoolExecutor) so it
does not block the event loop. The clients are thread-safe, so one instance
can back many worker threads.
Getting concurrency
The two clients reach concurrency differently.
BrainHttpClientthreadsEach call is one blocking HTTP round-trip on urllib.request. For
concurrent requests, share one client across a thread pool — construction
is cheap and the client holds no exclusive state.
BrainClientmultiplexed socket + threadsA single wire client multiplexes many in-flight requests over one socket —
a background reader thread demultiplexes responses by stream_id, so the
verbs are thread-safe and many threads can issue requests against one
client at once. Add a Pool for socket-level parallelism across several
connections.
HTTP client under a thread pool
from concurrent.futures import ThreadPoolExecutor
from brain_db_sdk import BrainHttpClient
client = BrainHttpClient("sk-...", base_url="https://api.arc-labs.ai")
cues = ["Where does Ada live?", "What does Ada prefer?", "Who is Ada?"]
with ThreadPoolExecutor(max_workers=8) as pool:
answers = list(pool.map(client.recall, cues))Wire client under concurrency
A single multiplexed connection already serves concurrent requests from many threads:
from concurrent.futures import ThreadPoolExecutor
from brain_db_sdk import BrainClient, Auth, RecallBuilder
client = BrainClient.connect("127.0.0.1", 9090, Auth.token(b"my-token"))
def do_recall(cue: str):
return client.recall(RecallBuilder(cue).build())
with ThreadPoolExecutor(max_workers=8) as pool:
answers = list(pool.map(do_recall, cues))For socket-level parallelism across independent connections, use a
Pool.
Calling from asyncio
import asyncio
from brain_db_sdk import BrainHttpClient
client = BrainHttpClient("sk-...", base_url="https://api.arc-labs.ai")
async def handler(cue: str):
# Offload the blocking call so the event loop stays responsive.
return await asyncio.to_thread(client.recall, cue)Lifecycle
Both clients support explicit close and the context-manager form.
from brain_db_sdk import BrainHttpClient
client = BrainHttpClient("sk-...")
# BrainHttpClient holds no persistent socket — there is no close() to call.
# Construct once per process and reuse it.from brain_db_sdk import BrainClient, Auth
# Context manager: BYE + close on exit.
with BrainClient.connect("127.0.0.1", 9090, Auth.token(b"my-token")) as client:
...
# Or explicit:
client = BrainClient.connect("127.0.0.1", 9090, Auth.token(b"my-token"))
try:
...
finally:
client.close()Was this page helpful?