moobius.network.ws_client#

Module-level functions#

asserted_dataclass_asdict#

Asserts that the input is the correct dataclass or is a dict which matches to a dataclsss.

Signature:

  • **asserted_dataclass_asdict**(x, the_class)

Parameters:

  • __x:__ The input dict or dataclass.

  • __the_class:__ The class to match to, such as types.Button.

Returns:

  • The modified value of x, as a dict.

Raises:

  • An Exception if there is a mismatch in the formatting.

time_out_wrap#

Sometimes the connection can hang forever. Adds a timeout that will make await raise an asyncio.TimeoutError if the function takes too long..

Signature:

  • **time_out_wrap**(co_routine, timeout)

Parameters:

  • __co_routine:__ Co-routine.

  • __timeout=16:__ A timeout.

Returns:

  • The co-routine with a timeout.

Raises:

  • (this function does not raise any notable errors)

Class WSClient#

WSClient is a websocket client that has a wide variety of Moobius-specific functions for sending payloads specific to the Moobius platform. It contains the standard socket functions such as on_connect(), send(), and receive() and is more robust: it has a queuing system and will automatically reconnect.

WSClient.connect#

Connects to the websocket server. Call after self.authenticate(). Keeps trying if it fails!.

Signature:

  • **WSClient.connect**(self)

Parameters:

  • __(this class constructor accepts no arguments):__

Returns:

  • None.

Raises:

  • (this function does not raise any notable errors)

WSClient.send#

Adds the message to self.outbound_queue for sending to the server. Note: Call this and other socket functions after self.authenticate()

If the server responds to the message it will be detected in the self.recieve() loop.

Signature:

  • **WSClient.send**(self, message)

Parameters:

  • __message:__ Dict-valued message (or JSON string).

Returns:

  • None.

Raises:

  • (this function does not raise any notable errors)

WSClient.receive#

Waits in a loop for messages from the websocket server or from the wand queue. Never.

Signature:

  • **WSClient.receive**(self)

Parameters:

  • __(this class constructor accepts no arguments):__

Returns:

  • The

Reconnectes if the connection fails or self.websocket.recv() stops getting anything (no heartbeats nor messages).

Raises:

  • (this function does not raise any notable errors)

WSClient.safe_handle#

Handles it with self.handle, which is specified on construction, catching errors.

Signature:

  • **WSClient.safe_handle**(self, message)

Parameters:

  • __message:__ String-valued message from the websocket server.

Returns:

  • None.

Raises:

  • (this function does not raise any notable errors)

WSClient.heartbeat#

Sends a heartbeat..

Signature:

  • **WSClient.heartbeat**(self, dry_run)

Parameters:

  • __dry_run:__ N optional dry_run to not send anything if True.

Returns:

  • The message dict.

Raises:

  • (this function does not raise any notable errors)

WSClient.dumps#

A slightly better json.dumps..

Signature:

  • **WSClient.dumps**(data)

Parameters:

  • __data:__ Datastructure or dataclass and.

Returns:

  • The JSON string.

Raises:

  • (this function does not raise any notable errors)

WSClient.service_login#

Logs in. Much like the HTTP api, this needs to be sent before any other messages.

Signature:

  • **WSClient.service_login**(self, service_id, access_token, dry_run)

Parameters:

  • __service_id:__ The client_id of a Moobius service object, which is the ID of the running service.

    Used in almost every function.

  • __access_token:__ TODO; This is the access token from http_api_wrapper; for clean code decouple access_token here!.

  • __dry_run:__ Don’t acually send anything (must functions offer a dry-run option).

Returns:

  • The message as a dict.

Raises:

  • (this function does not raise any notable errors)

WSClient.user_login#

Logs-in a user. Every 2h AWS will force-disconnect, so it is a good idea to send this on connect.

Signature:

  • **WSClient.user_login**(self, access_token, dry_run)

Parameters:

  • __access_token:__ Used in the user_login message that is sent.

    This is the access token from http_api_wrapper.

  • __dry_run:__ Don’t actually send anything if True.

Returns:

  • The message as a dict.

Raises:

  • (this function does not raise any notable errors)

WSClient.leave_channel#

A user leaves the channel with channel_id, unless dry_run is True..

Signature:

  • **WSClient.leave_channel**(self, user_id, channel_id, dry_run)

Parameters:

  • __user_id:__ User_id.

  • __channel_id:__ The channel_id.

  • __dry_run:__ Whether to dry_run.

Returns:

  • The message sent.

Raises:

  • (this function does not raise any notable errors)

WSClient.join_channel#

A user joins the channel with channel_id, unless dry_run is True..

Signature:

  • **WSClient.join_channel**(self, user_id, channel_id, dry_run)

Parameters:

  • __user_id:__ User_id.

  • __channel_id:__ The channel_id.

  • __dry_run:__ Whether to dry_run.

Returns:

  • The message sent.

Raises:

  • (this function does not raise any notable errors)

WSClient.send_characters#

Updates the characters that the recipients see.

Signature:

  • **WSClient.send_characters**(self, characters, service_id, channel_id, recipients, dry_run)

Parameters:

  • __characters:__ The group id to represent the characters who are updated.

  • __service_id:__ As always.

  • __channel_id:__ The channel id.

  • __recipients:__ The group id to send to.

  • __dry_run:__ If True don’t acually send the message (messages are sent in thier JSON-strin format).

Returns:

  • The message as a dict.

Raises:

  • (this function does not raise any notable errors)

WSClient.send_buttons#

Updates the buttons that the recipients see.

Signature:

  • **WSClient.send_buttons**(self, buttons, service_id, channel_id, recipients, dry_run)

Parameters:

  • __buttons:__ The buttons list to be updated.

  • __service_id:__ As always.

  • __channel_id:__ The channel id.

  • __recipients:__ The group id to send to.

  • __dry_run:__ Don’t actually send anything if True.

Returns:

  • The message as a dict.

Raises:

  • (this function does not raise any notable errors)

Example:

>>> continue_button = >>> {"button_name": "Continue Playing", "button_id": "play", >>> "button_name": "Continue Playing", "new_window": False, >>> "arguments": []} >>> ws_client.update_buttons("service_id", "channel_id", [continue_button], ["user1", "user2"])

WSClient.send_menu#

Updates the right-click menu that the recipients can open on various messages.

Signature:

  • **WSClient.send_menu**(self, menu_items, service_id, channel_id, recipients, dry_run)

Parameters:

  • __menu_items:__ List of MenuItem dataclasses.

  • __service_id:__ As always.

  • __channel_id:__ The channel id.

  • __recipients:__ The group id to send the changes to.

  • __dry_run:__ Don’t actually send anything if True.

Returns:

  • The message as a dict.

Raises:

  • (this function does not raise any notable errors)

WSClient.send_style#

Updates the style (whether the canvas is expanded, other look-and-feel aspects) that the recipients see.

Signature:

  • **WSClient.send_style**(self, style_items, service_id, channel_id, recipients, dry_run)

Parameters:

  • __style_items:__ The style content to be updated. Dicts are converted into 1-elemnt lists.

  • __service_id:__ As always.

  • __channel_id:__ The channel id.

  • __recipients:__ The group id to send to.

  • __dry_run:__ Don’t actually send anything if True.

Returns:

  • The message as a dict.

Raises:

  • (this function does not raise any notable errors)

Example:

>>> style_items = [ >>> { >>> "widget": "channel", >>> "display": "invisible", >>> }, >>> { >>> "widget": "button", >>> "display": "highlight", >>> "button_hook": { >>> "button_id": "button_id", >>> "button_name": "done", >>> "arguments": [] >>> }, >>> "text": "

Start from here.

This is a Button, which most channels have

" >>> }] >>> ws_client.update_style("service_id", "channel_id", style_items, ["user1", "user2"])

WSClient.update_channel_info#

Updates the channel name, description, etc for a given channel.

Signature:

  • **WSClient.update_channel_info**(self, channel_info, service_id, channel_id, dry_run)

Parameters:

  • __channel_info:__ The data of the update.

  • __service_id:__ As always.

  • __channel_id:__ The channel id.

  • __dry_run:__ Don’t actually send anything if True.

Returns:

  • The message as a dict.

Raises:

  • (this function does not raise any notable errors)

Example:

>>> ws_client.update_channel_info("service_id", "channel_id", {"name": "new_channel_name"})

WSClient.update_canvas#

Updates the canvas that the recipients see.

Signature:

  • **WSClient.update_canvas**(self, service_id, channel_id, canvas_items, recipients, dry_run)

Parameters:

  • __service_id:__ As always.

  • __channel_id:__ The channel id.

  • __canvas_items:__ The elements to push to the canvas.

  • __recipients:__ The recipients character_ids who see the update.

  • __dry_run:__ Don’t actually send anything if True.

Returns:

  • The message as a dict.

Raises:

  • (this function does not raise any notable errors)

Example:

>>> canvas1 = CanvasItem(path="image/url", text="the_text") >>> canvas2 = CanvasItem(text="the_text2") >>> ws_client.update_canvas("service_id", "channel_id", [canvas1, canvas2], ["user1", "user2"])

WSClient.update#

A generic update function that is rarely used.

Signature:

  • **WSClient.update**(self, data, target_client_id, service_id, dry_run)

Parameters:

  • __data:__ The content of the update.

  • __target_client_id:__ The target client id (TODO: not currently used).

  • __service_id:__ The ID of the service.

  • __dry_run:__ Don’t actually send anything if True.

Returns:

  • The message as a dict.

Raises:

  • (this function does not raise any notable errors)

WSClient.message_up#

Used by users to send messages.

Signature:

  • **WSClient.message_up**(self, user_id, service_id, channel_id, recipients, subtype, content, context, dry_run)

Parameters:

  • __user_id:__ An enduser id generally.

  • __service_id:__ Which service to send to.

  • __channel_id:__ Which channel to broadcast the message in.

  • __recipients:__ The group id to send to.

  • __subtype:__ The subtype of message to send (text, etc). Goes into message[‘body’] JSON.

  • __content:__ What is inside the message[‘body’][‘content’] JSON.

  • __context:__ Optional metadata.

  • __dry_run=None:__ Don’t actually send anything if True.

Returns:

  • The message as a dict.

Raises:

  • (this function does not raise any notable errors)

WSClient.message_down#

Sends a message to the recipients.

Signature:

  • **WSClient.message_down**(self, user_id, service_id, channel_id, recipients, subtype, content, sender, context, dry_run)

Parameters:

  • __user_id:__ An service id generally.

  • __service_id:__ Which service to send to.

  • __channel_id:__ Which channel to broadcast the message in.

  • __recipients:__ The group id to send to.

  • __subtype:__ The subtype of message to send (text, etc). Goes into message[‘body’] JSON.

  • __content:__ What is inside the message[‘body’][‘content’] JSON.

  • __sender:__ The sender ID of the message, which determines who the chat shows the message as sent by.

  • __context:__ Optional metadata.

  • __dry_run=None:__ Don’t actually send anything if True.

Returns:

  • The message as a dict.

Raises:

  • (this function does not raise any notable errors)

WSClient.send_button_click#

Sends a button click as a user.

Signature:

  • **WSClient.send_button_click**(self, button_id, bottom_button_id, button_args, channel_id, user_id, dry_run)

Parameters:

  • __button_id:__ The button’s ID.

  • __bottom_button_id:__ The bottom button, set to “confirm” if there is no bottom button.

  • __button_args:__ What arguments (if any) were selected on the button (use an empty list of there are none).

  • __channel_id:__ The id of the channel the user pressed the button in.

  • __user_id:__ The ID of the (user mode) service.

  • __dry_run:__ Don’t actually send anything if True.

Returns:

  • The message sent as a dict.

Raises:

  • (this function does not raise any notable errors)

WSClient.send_menu_item_click#

Sends a menu item click as a user.

Signature:

  • **WSClient.send_menu_item_click**(self, menu_item_id, bottom_button_id, button_args, the_message, channel_id, user_id, dry_run)

Parameters:

  • __menu_item_id:__ The menu item’s ID.

  • __bottom_button_id:__ The bottom button, set to “confirm” if there is no bottom button.

  • __button_args:__ What arguments (if any) were selected on the menu item’s dialog (use an empty list of there are none).

  • __the_message:__ Can be a string-valued message_id, or a full message body. If a full message the subtype and content will be filled in.

  • __channel_id:__ The id of the channel the user pressed the button in.

  • __user_id:__ The ID of the (user mode) service.

  • __dry_run:__ Don’t actually send anything if True.

Returns:

  • The message sent as a dict.

Raises:

  • (this function does not raise any notable errors)

WSClient.refresh_as_user#

Refreshes everything the user can see. The socket will send back messages with the information later.

Signature:

  • **WSClient.refresh_as_user**(self, user_id, channel_id, dry_run)

Parameters:

  • __user_id:__ Used in the “action” message that is sent.

  • __channel_id:__ Used in the body of said message.

  • __dry_run:__ Don’t actually send anything if True.

    These three parameters are common to most fetch messages.

Returns:

  • The message that was sent as a dict.

Raises:

  • (this function does not raise any notable errors)

Class attributes#

Internals#