Async Usage
Deribit clients are async-first and support two usage styles:
- construct a client and call methods directly for quick one-off requests
- use
async withwhen you want explicit lifecycle management
Quick Usage
For short request-response flows, plain construction is fine.
from typed_deribit import Deribit
client = Deribit.new(public=True)
ticker = await client.http.market_data.ticker(instrument_name='BTC-PERPETUAL')
print(ticker['last_price'])That works because .http, .ws, and .streams are each a cached_property — the
underlying transport opens lazily on first use, not at construction.
Context Manager Usage
Use async with when you want the client to open up front and close cleanly at the end of
the block.
from typed_deribit import Deribit
async with Deribit.new(testnet=True) as client:
instruments = await client.http.market_data.get_instruments(
currency='BTC', kind='future'
)
summary = await client.http.account.get_account_summary(currency='BTC')Deribit.new(...) connects nothing by itself — entering the top-level client via
async with is the only thing the caller does. .http, .ws, and .streams open their
own transports lazily as each is first used; there's no separate sub-client to enter.
Entering the top-level client does eagerly call __aenter__ on all three at once (so they're
already open the moment the block starts, rather than on first call), but that's still one
async with, never three.
This is the recommended style for:
- multiple requests in the same flow
- long-lived sessions
- any streaming workflow
- code where explicit cleanup matters
Streams
client.streams subscribes to Deribit's channel push feed, always over its own dedicated
WebSocket connection, independent of .ws. It fans into market_data (public channels —
tickers, order books, trades, ...), user (private user.* channels, need credentials),
block_rfq, and a raw rpc escape hatch for any JSON-RPC method not otherwise covered.
Use async with on the returned subscription so it unsubscribes automatically when the
block exits:
from typed_deribit import Deribit
async with Deribit.new(public=True) as client:
async with client.streams.market_data.ticker('BTC-PERPETUAL', 'raw') as ticks:
async for tick in ticks:
print(tick['last_price'])awaiting the subscription directly also works, but leaves it open until you call
unsubscribe() yourself:
from typed_deribit import Deribit
async with Deribit.new(public=True) as client:
ticks = await client.streams.market_data.ticker('BTC-PERPETUAL', 'raw')
async for tick in ticks:
print(tick['last_price'])
break
await ticks.unsubscribe()Private channels (client.streams.user.*) need credentials and raise AuthError lazily,
once the subscription actually connects, if the client has none.
Composite/Multi-Surface Client
Deribit.new(...) bundles three independent transports:
.http— request/reply over HTTP..ws— the same request/reply surface over WebSocket, plus a handful of methods Deribit only serves this way (trading.mass_quote,session.set_heartbeat, ...)..streams— channel subscriptions, always WebSocket, on its own connection separate from.ws.
.http and .ws expose the identical method surface — market_data, trading, account,
auth, block_rfq, block_trade, combo_books, matching_engine, session,
subscription_management, supporting — call whichever transport fits; they're two
separate connections, not aliases for one.
from typed_deribit import Deribit
async with Deribit.new(testnet=True) as client:
via_http = await client.http.market_data.ticker(instrument_name='BTC-PERPETUAL')
via_ws = await client.ws.market_data.ticker(instrument_name='BTC-PERPETUAL')All three (.http, .ws, .streams) are entered and exited together under one top-level
async with Deribit.new(...).
Guidance
Use direct construction for quick reads. Use async with by default when doing more than
one call, opening streams, or wanting predictable cleanup.