Connection
The JSON-RPC 2.0 transport to the middleware. TrueNASWSConnection is what
client.conn returns; it is rarely constructed directly, since
TrueNASClient opens and authenticates one for you.
pytruenas.connection
A lean synchronous JSON-RPC 2.0 client for the TrueNAS middleware.
This is a deliberately small client covering exactly what pytruenas needs:
open a websocket to the middleware, send a request, wait for the matching
response, and surface errors as exceptions. Jobs are not tracked client-side --
the middleware's own core.job_wait method (a normal blocking call) is used
for that. Event subscriptions (core.subscribe) ARE supported: see
:meth:TrueNASWSConnection.subscribe and :class:Subscription -- a bounded queue drained on
the caller's thread, with optional inline callbacks.
Three transports are supported by :class:TrueNASWSConnection:
wss://host/api/current-- TLS websocket to a remote host;ws://host/api/current-- plain websocket to a remote host;ws+unix:///var/run/middleware/middlewared.sock-- the local middleware unix socket, used when running on the NAS (no network round trip, no auth needed for a root-owned socket).
The wire format is JSON-RPC 2.0 <https://www.jsonrpc.org/specification>_ with
TrueNAS's extended-JSON value encoding (ejson below: datetime/date/
time/set/IP-interface round-tripping).
All annotations use quoted unions so the module imports on Python 3.9.
TrueNASWSConnection(uri=None, *, verify_ssl=True, call_timeout=CALL_TIMEOUT, py_exceptions=False, logger=None)
A synchronous JSON-RPC 2.0 client for the TrueNAS middleware.
uri may be a ws:///wss:// URL or a ws+unix:// unix-socket
URL; None (or a bare ws+unix://) connects to the local middleware
socket at :data:DEFAULT_UNIX_SOCKET.
The connection is a single blocking websocket. :meth:call sends one
request and blocks on the matching response (by id); a background
reader thread demultiplexes responses so concurrent calls from different
threads are safe, and routes collection_update notifications to any
:meth:subscribe sinks. Job tracking is intentionally omitted -- use the
middleware's core.job_wait for jobs.
Source code in src/pytruenas/connection.py
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 | |
call_timeout = call_timeout
instance-attribute
logger = logger if logger is not None else _LOGGER
instance-attribute
py_exceptions = py_exceptions
instance-attribute
uri = uri
instance-attribute
verify_ssl = verify_ssl
instance-attribute
__enter__()
Source code in src/pytruenas/connection.py
640 641 | |
__exit__(*exc)
Source code in src/pytruenas/connection.py
643 644 | |
call(method, *params, timeout=_UNSET, **_ignored)
Call method with params and return its result.
Blocks until the response arrives or timeout seconds elapse. The
default sentinel uses :attr:call_timeout; an explicit timeout=None
waits indefinitely (used by core.job_wait for long jobs).
Compatibility keyword arguments (job, background, callback,
…) accepted by the upstream client are ignored -- this client is
synchronous and does not track jobs client-side. Any other unexpected
keyword is logged at debug level rather than silently swallowed.
Raises :class:ValidationErrors/:class:ClientException on a server
error, :class:CallTimeout on timeout, and :class:ClientException
with errno=ECONNABORTED if the connection dropped.
Source code in src/pytruenas/connection.py
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 | |
close()
Close the websocket connection. Idempotent.
Source code in src/pytruenas/connection.py
623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 | |
subscribe(event, callback=None, *, maxsize=DEFAULT_EVENT_QUEUE_SIZE)
Subscribe to a middleware event and return a :class:Subscription.
event is a collection name (e.g. "alert.list",
"reporting.realtime"). Consume via the returned subscription's
:meth:~Subscription.events iterator and/or an optional callback
(called inline on the reader thread -- keep it fast).
Registers the sink BEFORE issuing core.subscribe so no event can
arrive between the server acknowledging and the sink existing; the sink
is removed again if the subscribe call fails.
Source code in src/pytruenas/connection.py
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 | |
Subscription(event, callback, maxsize, client)
A live subscription to a middleware event (core.subscribe).
Obtain one from :meth:TrueNASWSConnection.subscribe. Consume events by iterating
:meth:events (a bounded queue drains on the caller's thread -- no hidden
threads, backpressure is visible) and/or by passing a callback at
subscribe time (invoked inline on the reader thread -- keep it fast and
non-blocking; a raising callback is logged and swallowed so it never kills
the reader or other subscriptions).
Close with :meth:unsubscribe or a with block. When the queue fills
(a slow consumer) the OLDEST event is dropped and :attr:dropped is
incremented -- the reader never blocks.
Source code in src/pytruenas/connection.py
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | |
__slots__ = ('event', 'id', 'dropped', '_queue', '_callback', '_client', '_closed')
class-attribute
instance-attribute
dropped = 0
instance-attribute
event = event
instance-attribute
id = None
instance-attribute
__enter__()
Source code in src/pytruenas/connection.py
357 358 | |
__exit__(*exc)
Source code in src/pytruenas/connection.py
360 361 | |
events(timeout=None)
Yield events until the subscription (or the connection) closes.
Blocks on each event up to timeout seconds; timeout=None waits
indefinitely. The iterator ends cleanly when :meth:unsubscribe is
called or the connection drops.
Source code in src/pytruenas/connection.py
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 | |
unsubscribe()
Cancel this subscription (idempotent; safe after the client closes).
Source code in src/pytruenas/connection.py
353 354 355 | |
Event
Bases: NamedTuple
One collection_update notification delivered to a subscription.
Mirrors the middleware wire shape verified against TrueNAS 26.0:
{"method": "collection_update", "params": {"msg": ..., "collection":
..., "fields": {...}}}.
collection-- the event name subscribed to (the routing key);msg--"added"/"changed"/"removed";fields-- the record payload (may beNonefor some events);id-- the record id when the middleware includes one, elseNone.
collection
instance-attribute
fields
instance-attribute
id = None
class-attribute
instance-attribute
msg
instance-attribute
ClientException(error, errno=None, trace=None, extra=None)
Bases: Exception
Any error surfaced by a :class:TrueNASWSConnection call or connection.
errno carries the middleware's error number when it maps to a POSIX
errno (used by the filesystem layer to raise the right OSError);
trace/extra carry the server-side traceback and per-field error
detail when present.
Source code in src/pytruenas/connection.py
169 170 171 172 173 174 175 176 177 178 179 180 | |
errno = errno
instance-attribute
error = error
instance-attribute
extra = extra
instance-attribute
trace = trace
instance-attribute
__str__()
Source code in src/pytruenas/connection.py
182 183 | |
ValidationErrors(errors)
Bases: ClientException
A collection of per-attribute validation errors from the server.
Each entry is (attribute, errmsg, errcode). The stringified form lists
every attribute + message, matching how the middleware reports them.
Source code in src/pytruenas/connection.py
193 194 195 | |
errors = [(tuple(e)) for e in errors]
instance-attribute
__str__()
Source code in src/pytruenas/connection.py
197 198 199 200 201 202 | |
CallTimeout()
Bases: ClientException
Raised when a call does not return within its timeout.
Source code in src/pytruenas/connection.py
208 209 | |
dumps(obj, **kwargs)
Serialize obj to a JSON string, extended-type aware.
Source code in src/pytruenas/connection.py
145 146 147 | |
loads(data, **kwargs)
Deserialize a JSON string, decoding the middleware's extended types.
Source code in src/pytruenas/connection.py
150 151 152 | |