Sync facade¶
A blocking wrapper around the async API for scripts, notebooks, and REPL use.
Dtol.open_device(...) returns a SyncDtolSession that dispatches every call
through an anyio blocking portal — no parallel implementation. See the
Sync quickstart.
dtollib.sync ¶
Sync facade — :class:Dtol, :class:SyncDtolSession, :class:SyncPortal.
Async is canonical; the sync facade wraps it through :class:SyncPortal
so scripts, notebooks, and REPL sessions can drive tasks without
await.
Provides:
- :class:
Dtol— entry point (Dtol.open_device(spec)). - :class:
SyncDtolSession— blocking wrapper over :class:~dtollib.tasks.DtolSession. - :func:
record/ :func:record_polled— blocking streaming wrappers yielding a :class:SyncRecording. - :class:
SyncPortal/ :func:run_sync.
AcquisitionSummary
dataclass
¶
AcquisitionSummary(
started_at,
finished_at=None,
payloads_emitted=0,
payloads_dropped=0,
errors_observed=0,
overruns_observed=0,
underruns_observed=0,
extra=_empty_extra(),
)
Mutable summary of one recording session.
Updated in place by the recorder; finished_at is set on context exit.
The :class:Recording[T] handle exposes this so consumers can read
progress without poking at the recorder's internals.
overruns_observed and underruns_observed are SDK-level,
distinguishable from payloads_dropped (which counts
consumer-side losses under DROP_* overflow policies). See
docs/design.md §14.1 for the rationale.
Dtol ¶
Static namespace for sync entry points.
Idiomatic usage::
with Dtol.open_device(spec) as session:
reading = session.poll()
print(reading.values)
open_device
staticmethod
¶
Sync analogue of :func:dtollib.open_device.
Returns a :class:SyncDtolSession — usable as a normal
context manager.
Source code in src/dtollib/sync/daq.py
ErrorPolicy ¶
Bases: StrEnum
How a recorder reacts to a backend error mid-stream.
Attributes:
| Name | Type | Description |
|---|---|---|
RAISE |
Cancel the recorder; the exception propagates out of the
|
|
RETURN |
Emit a payload with |
|
SKIP |
Drop the failed payload silently. Increments
|
OverflowPolicy ¶
Bases: StrEnum
How a recorder reacts when its outgoing stream buffer fills.
Attributes:
| Name | Type | Description |
|---|---|---|
BLOCK |
Backpressure — the producer awaits buffer space. Default; preserves every payload at the cost of stalling the upstream buffer pool. Slow consumers risk SDK-level OVERRUN. |
|
DROP_OLDEST |
Discard the head of the buffer to make room. Trades
payload completeness for producer liveness. Increments
|
|
DROP_NEWEST |
Discard the incoming payload. Same trade-off as
|
SyncAsyncIterator ¶
Blocking view over an async iterator, bound to a :class:SyncPortal.
Source code in src/dtollib/sync/portal.py
close ¶
Cancel the underlying async iterator if it exposes aclose.
Source code in src/dtollib/sync/portal.py
SyncDtolSession ¶
Blocking facade over :class:~dtollib.tasks.DtolSession.
Source code in src/dtollib/sync/session.py
__enter__ ¶
Spin up a portal, then open the underlying async session.
Source code in src/dtollib/sync/session.py
abort ¶
close ¶
is_running ¶
poll ¶
start ¶
SyncPortal ¶
Per-context wrapper around :class:anyio.from_thread.BlockingPortal.
Source code in src/dtollib/sync/portal.py
call ¶
Run func(*args, **kwargs) on the portal's event loop.
Source code in src/dtollib/sync/portal.py
wrap_async_context_manager ¶
Present an async context manager as a sync context manager.
wrap_async_iter ¶
Present an async iterator as a blocking, closeable iterator.
SyncRecording
dataclass
¶
Sync mirror of :class:dtollib.streaming.Recording.
The stream here is a :class:SyncAsyncIterator (iterate with a
plain for loop); the rest of the shape matches the async handle.
record ¶
record(
source,
*,
timeout=10.0,
stream_buffer_size=16,
error_policy=ErrorPolicy.RAISE,
overflow=OverflowPolicy.DROP_OLDEST,
)
Sync wrapper around :func:dtollib.streaming.record.
Yields a :class:SyncRecording[DaqBlock]. Iterate recording.stream
with a normal for loop. As with the async recorder, source must
have been opened with autostart=False (the recorder owns the
commit/arm/start sequence).
Example::
with (
SyncDtolSession(spec, autostart=False) as session,
record(session) as recording,
):
for block in recording.stream:
process(block)
Source code in src/dtollib/sync/recording.py
record_polled ¶
record_polled(
source,
*,
rate_hz,
error_policy=ErrorPolicy.RAISE,
overflow=OverflowPolicy.BLOCK,
buffer_size=64,
)
Sync wrapper around :func:dtollib.streaming.record_polled.
The sync facade only accepts a session source — the manager-mode
fan-out belongs to async-only call sites — so the per-tick payload is
always :class:DaqReading.
Source code in src/dtollib/sync/recording.py
run_sync ¶
Run one coroutine in a throwaway :class:SyncPortal.