API Reference

These are the core classes used to implement the behavior of the DISCOS client system. In general, users interacts primarily with a specific telescope client: SRTClient, MedicinaClient or NotoClient, but they can also use the more general DISCOSClient providing IP address and port of the DISCOS Manager machine (for example when connecting to a simulated instance of DISCOS). All values read inside the client are DISCOSNamespace objects.

DISCOSClient

class discos_client.client.DISCOSClient(*topics, address, sub_port=16000, req_port=16010, telescope=None, identity=None, server_public_key_file=None)[source]

Class that implements a generic DISCOSClient. It handles incoming ZMQ messages from the DISCOS control software and eventually allows the user to send remote commands.

Parameters:
  • topics (str) – topic names to subscribe to.

  • address (str) – IP address to subscribe to.

  • sub_port (int) – TCP port where the subscriber socket will connect.

  • req_port (int) – TCP port where the requester socket will connect.

  • telescope (str | None) – name of the telescope the client is connecting to.

  • identity (str | None) – name of the key file to be used for sending remote commands. Ideally, each application should have and use its own identity.

  • server_public_key_file (str | Path | None) – path to a ZMQ public certificate file containing the RPC server public key. Useful when using plain DISCOSClient without a predefined telescope profile.

Raises:
  • ValueError – If one or more given topics are not known.

  • FileNotFoundError – If the provided identity file is missing.

  • ValueError – If the the provided identity file does not contain a valid key pair.

command(cmd, *args)[source]

Sends a command to the remote server.

This method is only available if the DISCOSClient instance finds the correct authentication keys.

Parameters:
  • cmd (str) – The name of the command.

  • args – A series of arguments to be inclueded in the command.

Return type:

DISCOSNamespace

Returns:

A DISCOSNamespace containing the command answer.

DISCOSNamespace

class discos_client.namespace.DISCOSNamespace(parent_dict, key, schema_meta=None, reactive=True)[source]

Stable view node over a shared plain-dict data store.

The tree of DISCOSNamespace objects is built once by NSInitializer and never structurally changes (except for array resizes and new dynamic keys). All actual data lives in a plain Python dict/list hierarchy; each node keeps a reference to its parent container and its key inside that container, so that _get_node() amounts to a single O(1) dict/list lookup.

Consequences of this design:

  • Object identity is stable: client.antenna is client.antenna → True.

  • <<= is a plain dict deep-merge with no per-node object allocation, dropping the recursive DISCOSNamespace traversal.

  • Serialisation (format, str) calls json.dumps directly on the plain data dict — pure C, no Python unwrap recursion.

  • Per-node threading.RLock is gone; the GIL protects single- bytecode reads/writes (see analysis in commit history). Only the observer list uses an explicit threading.Lock.

Parameters:
  • parent_dict (dict | list) – The dict or list that contains this node.

  • key (str | int) – The key / index of this node inside parent_dict.

  • schema_meta (dict | None) – Static metadata extracted from the JSON Schema (title, description, unit, enum, format, type).

  • reactive (bool) – Whether to expose bind, unbind, wait and copy.

bind(callback, predicate=None, unwrap=False)[source]

Register callback to be called when this node changes.

Parameters:
  • callback (Callable[[Any], None]) – Called with the updated node (or its raw value when unwrap is True).

  • predicate (Callable[[Any], bool] | None) – Optional filter; the callback fires only when the predicate returns True.

  • unwrap (bool) – If True, the predicate and callback receive the raw primitive value instead of the namespace node.

Return type:

None

copy()[source]

Return an independent, non-reactive snapshot of the current state.

The data dict is deep-copied so subsequent updates to the live tree do not affect the snapshot. The namespace structure mirrors the original but holds no observers.

Return type:

DISCOSNamespace

get_value()[source]

Return the primitive value held by this leaf node.

Raises:

TypeError – If this node contains a dict or list.

Return type:

Any

unbind(callback=None, predicate=None)[source]

Remove a previously registered callback.

Parameters:
  • callback (Callable[[Any], None] | None) – The callback to remove. If None, all callbacks are removed.

  • predicate (Callable[[Any], bool] | None) – If given, only the entry with this exact predicate is removed; other entries for the same callback are kept.

Return type:

None

wait(predicate=None, timeout=None, unwrap=False)[source]

Block until this node changes (and optionally satisfies predicate).

Parameters:
  • predicate (Callable[[Any], bool] | None) – If given, keeps waiting until the predicate returns True.

  • timeout (float | None) – Maximum wait time in seconds.

  • unwrap (bool) – If True, returns the raw primitive value instead of the namespace node.

Return type:

Any

Returns:

This node (or its raw value if unwrap) after the change.