whisker.qtclient

whisker/qtclient.py


Copyright © 2011-2020 Rudolf Cardinal (rudolf@pobox.com).

This file is part of the Whisker Python client library.

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.


Multithreaded framework for Whisker Python clients using Qt.

class whisker.qtclient.ThreadOwnerState(value)[source]

An enumeration.

class whisker.qtclient.WhiskerController(server: str, parent: SimpleClass | None = None, connect_timeout_ms: int = 5000, read_timeout_ms: int = 500, name: str = 'whisker_controller', sysevent_prefix: str = 'sys_', **kwargs)[source]

Controls the Whisker immediate socket.

  • Encapsulates the Whisker API.

  • Lives in Whisker thread (B) (see WhiskerOwner).

  • Emits signals that can be processed by the Whisker task (derived from WhiskerQtTask).

Signals:

  • finished()

  • connected()

  • disconnected()

  • message_received(str, arrow.Arrow, int)

  • event_received(str, arrow.Arrow, int)

  • key_event_received(str, arrow.Arrow, int)

  • client_message_received(int, str, arrow.Arrow, int)

  • warning_received(str, arrow.Arrow, int)

  • syntax_error_received(str, arrow.Arrow, int)

  • error_received(str, arrow.Arrow, int)

  • pingack_received(arrow.Arrow, int)

Parameters:
  • server – host name or IP address of Whisker server

  • parent – optional parent :QObject

  • connect_timeout_ms – time to wait for successful connection (ms) before considering it a failure

  • read_timeout_ms – time to wait for each read (primary effect is to determine the application’s responsivity when asked to finish; see WhiskerMainSocketListener)

  • name – (name for StatusMixin)

  • sysevent_prefix – default system event prefix (for WhiskerController)

  • kwargs – parameters to superclass

is_connected() bool[source]

Is our immediate socket connected?

(If the immediate socket is running, the main socket should be too.)

ping() None[source]

Ping the server.

Override WhiskerApi.ping() so we can emit a signal on success.

class whisker.qtclient.WhiskerMainSocketListener(server: str, port: int, parent: SimpleClass | None = None, connect_timeout_ms: int = 5000, read_timeout_ms: int = 100, name: str = 'whisker_mainsocket', **kwargs)[source]

Whisker thread (A) (see WhiskerOwner). Listens to the main socket.

Signals:

  • finished()

  • disconnected()

  • line_received(msg: str, timestamp: arrow.Arrow)

Parameters:
  • server – host name or IP address of Whisker server

  • port – main port number for Whisker server

  • parent – optional parent :QObject

  • connect_timeout_ms – time to wait for successful connection (ms) before considering it a failure

  • read_timeout_ms – time to wait for each read (primary effect is to determine the application’s responsivity when asked to finish; see WhiskerMainSocketListener)

  • name – (name for StatusMixin)

  • kwargs – parameters to superclass

class whisker.qtclient.WhiskerOwner(task: WhiskerQtTask, server: str, main_port: int = 3233, parent: SimpleClass | None = None, connect_timeout_ms: int = 5000, read_timeout_ms: int = 500, name: str = 'whisker_owner', sysevent_prefix: str = 'sys_', **kwargs)[source]

Object to own and manage communication with a Whisker server.

This object is owned by the GUI thread. It devolves work to two other threads:

  1. main socket listener (WhiskerMainSocketListener, as the instance self.mainsock, in the thread self.mainsockthread);

  2. task (WhiskerQtTask, as the instance self.task in the thread self.taskthread) + immediate socket blocking handler (WhiskerController, as the instance self.controller in the thread self.taskthread).

References to “main” here just refers to the main socket (as opposed to the immediate socket), not the thread that’s doing most of the processing.

Signals of relevance to users:

  • connected()

  • disconnected()

  • finished()

  • message_received(str, arrow.Arrow, int)

  • event_received(str, arrow.Arrow, int)

  • pingack_received(arrow.Arrow, int)

Parameters:
  • task – instance of something derived from WhiskerQtTask

  • server – host name or IP address of Whisker server

  • main_port – main port number for Whisker server

  • parent – optional parent :QObject

  • connect_timeout_ms – time to wait for successful connection (ms) before considering it a failure

  • read_timeout_ms – time to wait for each read (primary effect is to determine the application’s responsivity when asked to finish; see WhiskerMainSocketListener)

  • name – (name for StatusMixin)

  • sysevent_prefix – default system event prefix (for WhiskerController)

  • kwargs – parameters to superclass

is_running() bool[source]

Are any of our worker threads starting/running/stopping?

ping() None[source]

Pings the Whisker server.

report_status() None[source]

Print current thread/server state to the log.

start() None[source]

Start our worker threads.

stop() None[source]

Called by the GUI when we want to stop.

class whisker.qtclient.WhiskerQtTask(parent: SimpleClass | None = None, name: str = 'whisker_task', **kwargs)[source]

Base class for building a Whisker task itself. You should derive from this.

Signals:

  • finished()

Parameters:
  • parent – optional parent :QObject

  • name – (name for StatusMixin)

  • kwargs – parameters to superclass

on_connect() None[source]

The WhiskerOwner makes this slot get called when the WhiskerController is connected.

You should override this.

set_controller(controller: WhiskerController) None[source]

Called by WhiskerOwner. No need to override.

whisker.qtclient.disable_nagle(socket: <MagicMock id='139817539388464'>) None[source]

Disable the Nagle algorithm on the Qt socket. (This makes it send any outbound data immediately, rather than waiting and packaging it up with potential subsequent data. So this function chooses a low-latency mode over a high-efficiency mode.)

whisker.qtclient.get_socket_error(socket: <MagicMock id='139817539388464'>) str[source]

Returns a textual description of the last error on the specified Qt socket.

whisker.qtclient.is_socket_connected(socket: <MagicMock id='139817539388464'>) bool[source]

Is the Qt socket connected?

whisker.qtclient.quote(msg: str) str[source]

Return its argument suitably quoted for transmission to Whisker.

  • Whisker has quite a primitive quoting system…

  • Check with strings that actually include quotes.