Brainby arc-labs/docs
Python SDK

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.

OptionTypeDefault / Env
BrainHttpClientthreads

Each 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 + threads

A 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?

On this page