Vesta

Vesta is a Vestaboard client library for Python. It provides API clients and character encoding utilities.

Installation

Vesta requires Python 3.8 or later. It can be installed via PyPI:

$ python -m pip install vesta

It’s only runtime dependency is the HTTPX library, which will be installed automatically.

API Clients

Read / Write API

vesta.ReadWriteClient provides a client interface for interacting with a Vestaboard using the Read / Write API.

Important

A Read / Write API key is required to read or write messages. This key is obtained by enabling the Vestaboard’s Read / Write API via the Settings section of the mobile app or from the Developer section of the web app.

class vesta.ReadWriteClient(read_write_key: str, *, http_client: Client | None = None, base_url: str = 'https://rw.vestaboard.com/', headers: Mapping[str, str] | None = None)

Provides a Vestaboard Read / Write API client interface.

A Read / Write API key is required to read or write messages. This key is obtained by enabling the Vestaboard’s Read / Write API via the Settings section of the mobile app or from the Developer section of the web app.

Optionally, an alternate base_url can be specified, as well as any additional HTTP headers that should be sent with every request (such as a custom User-Agent header).

Added in version 0.8.0.

read_message() vesta.chars.Rows | None

Read the Vestaboard’s current message.

write_message(message: str | vesta.chars.Rows) bool

Write a message to the Vestaboard.

message can be either a string of text or a two-dimensional (6, 22) array of character codes representing the exact positions of characters on the board.

If text is specified, the lines will be centered horizontally and vertically. Character codes will be inferred for alphanumeric and punctuation characters, or they can be explicitly specified using curly braces containing the character code (such as {5} or {65}).

Raises:

ValueError – if message is a list with unsupported dimensions

Subscription API

vesta.SubscriptionClient provides a client interface for interacting with multiple Vestaboards using the Subscription API.

Important

An API secret and key is required to get subscriptions or send messages. These credentials can be created from the Developer section of the web app.

class vesta.SubscriptionClient(api_key: str, api_secret: str, *, http_client: Client | None = None, base_url: str = 'https://subscriptions.vestaboard.com', headers: Mapping[str, str] | None = None)

Provides a Vestaboard Subscription API client interface.

Credentials must be provided as an api_key and api_secret.

Optionally, an alternate base_url can be specified, as well as any additional HTTP headers that should be sent with every request (such as a custom User-Agent header).

Added in version 0.12.0.

get_subscriptions() List[Dict[str, Any]]

Lists all subscriptions to which the viewer has access.

send_message(subscription_id: str, message: str | vesta.chars.Rows) Dict[str, Any]

Send a new message to a subscription.

The authenticated viewer must have access to the subscription.

message can be either a string of text or a two-dimensional (6, 22) array of character codes representing the exact positions of characters on the board.

If text is specified, the lines will be centered horizontally and vertically. Character codes will be inferred for alphanumeric and punctuation characters, or they can be explicitly specified using curly braces containing the character code (such as {5} or {65}).

Raises:

ValueError – if message is a list with unsupported dimensions

Local API

vesta.LocalClient provides a client interface for interacting with a Vestaboard over the local network using Vestaboard’s Local API.

Important

Vestaboard owners must first request a Local API enablement token in order to use the Local API.

class vesta.LocalClient(local_api_key: str | None = None, *, http_client: Client | None = None, base_url: str = 'http://vestaboard.local:7000')

Provides a Vestaboard Local API client interface.

A Local API key is required to read or write messages. This key is obtained by enabling the Vestaboard’s Local API using a Local API Enablement Token.

If you’ve already enabled your Vestaboard’s Local API, that key can be provided immediately. Otherwise, it can be set after the client is constructed by calling enable(), which also returns the Local API key for future reuse.

An alternate base_url can also be specified.

Added in version 0.8.0.

property api_key: str | None

The client’s Local API key.

enable(enablement_token) str | None

Enable the Vestaboard’s Local API using a Local API Enablement Token.

If successful, the Vestaboard’s Local API key will be returned and the client’s api_key property will be updated to the new value.

property enabled: bool

Check if api_key has been set, indicating that Local API support has been enabled.

read_message() vesta.chars.Rows | None

Read the Vestaboard’s current message.

write_message(message: vesta.chars.Rows) bool

Write a message to the Vestaboard.

message must be a two-dimensional (6, 22) array of character codes representing the exact positions of characters on the board.

Raises:

ValueError – if message is a list with unsupported dimensions

VBML API

vesta.VBMLClient provides a client interface for Vestaboard’s VBML (Vestaboard Markup Language) API.

class vesta.VBMLClient(*, http_client: Client | None = None, base_url: str = 'https://vbml.vestaboard.com/', headers: Mapping[str, str] | None = None)

Provides a VBML (Vestaboard Markup Language) API client interface.

Added in version 0.11.0.

compose(components: List[Component], props: Mapping[str, str] | None = None) vesta.chars.Rows

Composes one or more styled components into rows of character codes.

props can be a map of dynamic properties that will be injected into the message templates using double bracket notation ({{propName}}). A prop value must be provided if it is used in a template.

Returns:

Rows of character codes representing the composed message

Raises:

ValueError – if no components are provided

Platform API

vesta.Client provides a client interface for interacting with the deprecated Vestaboard Platform API.

Warning

This is the original Vestaboard Platform API. It is deprecated and has been superseded by the other APIs listed above. In particular, Vestaboard encourages users of the Platform API to switch to the Subscription API, which offers nearly identical functionality.

class vesta.Client(api_key: str, api_secret: str, *, http_client: Client | None = None, base_url: str = 'https://platform.vestaboard.com', headers: Mapping[str, str] | None = None)

Provides a Vestaboard API client interface.

Credentials must be provided as an api_key and api_secret.

Optionally, an alternate base_url can be specified, as well as any additional HTTP headers that should be sent with every request (such as a custom User-Agent header).

Deprecated since version 0.12.

get_subscriptions() List[Dict[str, Any]]

Lists all subscriptions to which the viewer has access.

get_viewer() Dict[str, Any]

Describes the currently authenticated viewer.

post_message(subscription_id: str, message: str | vesta.chars.Rows) Dict[str, Any]

Post a new message to a subscription.

The authenticated viewer must have access to the subscription.

message can be either a string of text or a two-dimensional (6, 22) array of character codes representing the exact positions of characters on the board.

If text is specified, the lines will be centered horizontally and vertically. Character codes will be inferred for alphanumeric and punctuation characters, or they can be explicitly specified using curly braces containing the character code (such as {5} or {65}).

Raises:

ValueError – if message is a list with unsupported dimensions

Character Encoding

All Vestaboard characters (letters, numbers, symbols, and colors) are encoded as integer character codes. Vesta includes some helpful routines for working with these character codes.

vesta.chars.COLS: Final[int] = 22

The number of columns on a board.

vesta.chars.ROWS: Final[int] = 6

The number of rows on a board.

vesta.chars.Row

A row of character codes.

alias of List[int]

vesta.chars.Rows

A list of rows, forming a character grid.

alias of List[List[int]]

class vesta.Color(value)

Bases: IntEnum

Color chips

BLACK = 70
BLANK = 0
BLUE = 67
FILLED = 71
GREEN = 66
ORANGE = 64
RED = 63
VIOLET = 68
WHITE = 69
YELLOW = 65
vesta.encode(s: str) vesta.chars.Row

Encodes a string as a list of character codes.

In addition to printable characters, the string can contain character code sequences inside curly braces, such as {5} or {65}.

Raises:

ValueError – if the string contains unsupported characters or codes

>>> encode("{67} Hello, World {68}")
[67, 0, 8, 5, 12, 12, 15, 55, 0, 23, 15, 18, 12, 4, 0, 68]
vesta.encode_row(s: str, *, align: Literal['left', 'center', 'right'] = 'left', fill: int = Color.BLANK) vesta.chars.Row

Encodes a string as a row of character codes.

In addition to printable characters, the string can contain character code sequences inside curly braces, such as {5} or {65}.

align controls the text’s alignment within the row: left, right, or center. The fill character code (generally a Color) is used to fill out any additional space.

Raises:

ValueError – if the string contains unsupported characters or codes, or if the resulting encoding sequence would exceed the maximum number of supported columns

>>> encode_row("{67} Hello, World {68}", align="center")
[0, 0, 0, 67, 0, 8, 5, 12, 12, 15, 55, 0, 23, 15, 18, 12, 4, 0, 68, 0, 0, 0]
vesta.encode_text(s: str, *, align: Literal['left', 'center', 'right'] = 'left', valign: Literal['top', 'middle', 'bottom'] | None = 'top', max_rows: int = ROWS, margin: int = 0, fill: int = Color.BLANK, breaks: Container[int] = frozenset({0})) vesta.chars.Rows

Encodes a string of text into rows of character codes.

In addition to printable characters, the string can contain character code sequences inside curly braces, such as {5} or {65}.

align controls the text’s alignment within the row: left, right, or center. valign controls the text’s vertical alignment within the full board (up to max_rows): top, middle, bottom, or None (to never add rows, potentially resulting in a partial board).

max_rows determines the maximum number of rows that will be returned, potentially truncating the result. When max_rows is zero, the row count is unlimited.

margin specifies the width (in columns) of the left and right margins. The fill character code (generally a Color) is used to fill out any additional space.

breaks is the set of character codes used to compute line breaks. If a line of text won’t fit in the available columns, it will be “broken” at the first preceding break character, and the remaining characters will continue on the next row (potentially subject to additional breaks). If a break cannot be found, the line will be broken at the column limit (potentially mid-“word”).

Line boundaries (as determined by str.splitlines()) appearing in the source string always result in line breaks.

Raises:

ValueError – if the string contains unsupported characters or codes

>>> encode_text('multiple\nlines\nof\ntext', align="center", valign="middle")
... 
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 13, 21, 12, 20, 9, 16, 12, 5, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 12, 9, 14, 5, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 5, 24, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
vesta.pprint(data: vesta.chars.Row | vesta.chars.Rows, stream: TextIO = sys.stdout, *, sep: str = '|', block: str = '◼︎') None

Prints a console-formatted representation of encoded character data.

data may be a single list or a two-dimensional array of character codes.

VBML

VBML (Vestaboard Markup Language) defines a language for composing static and dynamic messages.

class vesta.vbml.Component(template: str | None = None, raw_characters: vesta.chars.Rows | None = None, style: Style | None = None, *, height: int | None = None, width: int | None = None, justify: Literal['left', 'right', 'center', 'justified'] | None = None, align: Literal['top', 'bottom', 'center'] | None = None, absolute_position: Position | None = None)

A Component defines a template with optional Style values.

Template is a message template string. It can contain any supported Vestaboard character as well as valid character code sequences inside curly braces, such as {5} or {65} and interpolated Props using double bracket notation ({{propName}}). Any lowercase letters will be cast to uppercase. A new row can be forced by inserting a newline (\n) sequence.

Alternatively, a raw_characters character array can be provided to set the initial (background) state of the component. raw_characters takes precedence over template.

A style dictionary can be provided. Individual Style values can also be given as keyword arguments (height, width, justify, align, absolute_position), and they will override any values from the style dictionary.

asdict() Dict[str, Any]

Returns the component’s JSON dictionary representation.

class vesta.vbml.Position

A Position defines an absolute position on a board.

x: int

X coordinate

y: int

Y coordinate

class vesta.vbml.Style

A Style defines a set of values that will be applied to a Component.

absolutePosition: Position

An exact position on the board. Bounded by width and height.

align: Literal['top', 'bottom', 'center']

The vertical alignment of a message. Defaults to top.

height: int

The height of the current component (1-6). Defaults to 6.

justify: Literal['left', 'right', 'center', 'justified']

The horizontal alignment of the message. Defaults to left.

width: int

The width of the current component (1-22). Defaults to 22.

vesta.vbml.Props

Map of dynamic properties that can be injected into message templates.

alias of Mapping[str, str]