API

Device

class Device(*args, startup: Optional[str] = None, attempts: int = 0, **kwargs)

Belay interface into a micropython device.

Can be used as a context manager; calls self.close on exit.

Uses the autoregistry.RegistryMeta metaclass for easy-to-access subclasses.

implementation

Implementation details of device.

Type

Implementation

MAX_CMD_HISTORY_LEN = 1000
close() None

Close the connection to device.

Automatically called on context manager exit.

reconnect(attempts: Optional[int] = None) None

Reconnect to the device and replay the command history.

Parameters

attempts (int) -- Number of times to attempt to connect to board with a 1 second delay in-between. If None, defaults to whatever value was supplied to init. If init value is 0, then defaults to 1.

static setup() Callable[[belay.device.P], belay.device.R]
static setup(*, implementation: str = "''", **kwargs) Callable[[Callable[[belay.device.P], belay.device.R]], Callable[[belay.device.P], belay.device.R]]

Execute decorated function's body in a global-context on-device when called.

Function arguments are also set in the global context.

Can either be used as a staticmethod @Device.setup for marking methods in a subclass of Device, or as a standard method @device.setup for marking functions to a specific Device instance.

Parameters
  • f (Callable) -- Function to decorate. Can only accept and return python literals.

  • minify (bool) -- Minify cmd code prior to sending. Defaults to True.

  • register (bool) -- Assign an attribute to self.setup with same name as f. Defaults to True.

  • record (bool) -- Each invocation of the executer is recorded for playback upon reconnect. Defaults to True.

  • autoinit (bool) -- Automatically invokes decorated functions at the end of object __init__. Methods will be executed in order-registered. Defaults to False.

  • ignore_errors (bool) -- Discard any device-side uncaught exception. Defaults to False.

  • implementation (str) -- If supplied, the provided method will only be used if the board's implementation name matches. Several methods of the same name can be overloaded that support different implementations. Common values include "micropython", and "circuitpython". Defaults to an empty string, which all implementations will match to.

soft_reset()

Reset device, executing main.py if available.

sync(folder: Union[str, pathlib.Path], dst: str = '/', keep: Union[None, list, str, bool] = None, ignore: Union[None, list, str] = None, minify: bool = True, mpy_cross_binary: Optional[Union[str, pathlib.Path]] = None, progress_update=None) None

Sync a local directory to the remote filesystem.

For each local file, check the remote file's hash, and transfer if they differ. If a file/folder exists on the remote filesystem that doesn't exist in the local folder, then delete it (unless it's in keep).

Parameters
  • folder (str, Path) -- Single file or directory of files to sync to the root of the board's filesystem.

  • dst (str) -- Destination directory on device. Defaults to unpacking folder to root.

  • keep (None | str | list | bool) -- Do NOT delete these file(s) on-device if not present in folder. If true, don't delete any files on device. If false, delete all unsynced files (same as passing []). If dst is None, defaults to ["boot.py", "webrepl_cfg.py", "lib"].

  • ignore (None | str | list) -- Git's wildmatch patterns to NOT sync to the device. Defaults to ["*.pyc", "__pycache__", ".DS_Store", ".pytest_cache"].

  • minify (bool) -- Minify python files prior to syncing. Defaults to True.

  • mpy_cross_binary (Union[str, Path, None]) -- Path to mpy-cross binary. If provided, .py will automatically be compiled. Takes precedence over minifying.

  • progress_update -- Partial for rich.progress.Progress.update(task_id,...) to update with sync status.

sync_dependencies(package: Union[module, str], *subfolders: Union[str, pathlib.Path], dst='/lib', **kwargs)

Convenience method for syncing dependencies bundled with package.

If using Belay's package manager feature, set dependencies_path to a folder inside your python package (e.g. dependencies_path="mypackage/dependencies").

The following example will sync all the files/folders in mypackage/dependencies/main to device's /lib.

import mypackage

device.sync_package(mypackage, "dependencies/main")

For intended use, sync_dependencies should be only be called once. Multiple invocations overwrite/delete previous calls' contents.

# Good
device.sync_package(mypackage, "dependencies/main", "dependencies/dev")

# Bad (deletes on-device files from "dependencies/main")
device.sync_package(mypackage, "dependencies/main")
device.sync_package(mypackage, "dependencies/dev")
Parameters
  • package (Union[ModuleType, str]) -- Either the imported package or the name of a package that contains the data we would like to sync.

  • *subfolders -- Subfolder(s) to combine and then sync to dst. Typically something like "dependencies/main"

  • dst (Union[str, Path]) -- On-device destination directory. Defaults to /lib.

  • **kwargs -- Passed along to Device.sync.

static task() Callable[[belay.device.P], belay.device.R]
static task(**kwargs) Callable[[Callable[[belay.device.P], belay.device.R]], Callable[[belay.device.P], belay.device.R]]

Execute decorated function on-device.

Sends source code to device at decoration time. Execution sends involves much smaller overhead.

Can either be used as a staticmethod @Device.task for marking methods in a subclass of Device, or as a standard method @device.task for marking functions to a specific Device instance.

Parameters
  • f (Callable) -- Function to decorate. Can only accept and return python literals.

  • minify (bool) -- Minify cmd code prior to sending. Defaults to True.

  • register (bool) -- Assign an attribute to self.task with same name as f. Defaults to True.

  • record (bool) -- Each invocation of the executer is recorded for playback upon reconnect. Only recommended to be set to True for a setup-like function. Defaults to False.

  • implementation (str) -- If supplied, the provided method will only be used if the board's implementation name matches. Several methods of the same name can be overloaded that support different implementations. Common values include "micropython", and "circuitpython". Defaults to an empty string, which all implementations will match to.

  • trusted (bool) -- Fully trust remote device. When set to False, only [None, bool, bytes, int, float, str, List, Dict, Set] return values can be parsed. When set to True, any value who's repr can be evaluated to create a python object can be returned. However, this also allows the remote device to execute arbitrary code on host. Defaults to False.

static teardown() Callable[[belay.device.P], belay.device.R]
static teardown(**kwargs) Callable[[Callable[[belay.device.P], belay.device.R]], Callable[[belay.device.P], belay.device.R]]

Executes decorated function's body in a global-context on-device when device.close() is called.

Function arguments are also set in the global context.

Can either be used as a staticmethod @Device.teardown for marking methods in a subclass of Device, or as a standard method @device.teardown for marking functions to a specific Device instance.

Parameters
  • f (Callable) -- Function to decorate. Can only accept and return python literals.

  • minify (bool) -- Minify cmd code prior to sending. Defaults to True.

  • register (bool) -- Assign an attribute to self.teardown with same name as f. Defaults to True.

  • record (bool) -- Each invocation of the executer is recorded for playback upon reconnect. Defaults to True.

  • ignore_errors (bool) -- Discard any device-side uncaught exception. Defaults to False.

  • implementation (str) -- If supplied, the provided method will only be used if the board's implementation name matches. Several methods of the same name can be overloaded that support different implementations. Common values include "micropython", and "circuitpython". Defaults to an empty string, which all implementations will match to.

terminal(*, exit_char='\x1d')

Start a blocking interactive terminal over the serial port.

static thread() Callable[[belay.device.P], belay.device.R]
static thread(**kwargs) Callable[[Callable[[belay.device.P], belay.device.R]], Callable[[belay.device.P], belay.device.R]]

Spawn on-device thread that executes decorated function.

Can either be used as a staticmethod @Device.thread for marking methods in a subclass of Device, or as a standard method @device.thread for marking functions to a specific Device instance.

Parameters
  • f (Callable) -- Function to decorate. Can only accept python literals as arguments.

  • minify (bool) -- Minify cmd code prior to sending. Defaults to True.

  • register (bool) -- Assign an attribute to self.thread with same name as f. Defaults to True.

  • record (bool) -- Each invocation of the executer is recorded for playback upon reconnect. Defaults to True.

  • implementation (str) -- If supplied, the provided method will only be used if the board's implementation name matches. Several methods of the same name can be overloaded that support different implementations. Common values include "micropython", and "circuitpython". Defaults to an empty string, which all implementations will match to.

class Implementation(name: str, version: Tuple[int, int, int] = (0, 0, 0), platform: str = '', emitters: Tuple[str] = ())

Implementation dataclass detailing the device.

Parameters
  • name (str) -- Type of python running on device. One of {"micropython", "circuitpython"}.

  • version (Tuple[int, int, int]) -- (major, minor, patch) Semantic versioning of device's firmware.

  • platform (str) -- Board identifier. May not be consistent from MicroPython to CircuitPython. e.g. The Pi Pico is "rp2" in MicroPython, but "RP2040" in CircuitPython.

  • emitters (tuple[str]) -- Tuple of available emitters on-device {"native", "viper"}.

emitters: Tuple[str] = ()
name: str
platform: str = ''
version: Tuple[int, int, int] = (0, 0, 0)

Helpers

list_devices() List[belay.usb_specifier.UsbSpecifier]

Lists available device ports.

Returns

Available devices identifiers.

Return type

List[UsbSpecifier]

Exceptions

exception AuthenticationError

Bases: belay.exceptions.BelayException

Invalid password or similar.

exception BelayException

Bases: Exception

Root Belay exception class.

exception ConnectionFailedError

Bases: belay.exceptions.BelayException

Unable to connect to specified device.

exception ConnectionLost

Bases: belay.exceptions.ConnectionFailedError

Lost connection to device.

exception DeviceNotFoundError

Bases: belay.exceptions.BelayException

Unable to find specified device.

exception FeatureUnavailableError

Bases: belay.exceptions.BelayException

Feature unavailable for your board's implementation.

exception InsufficientSpecifierError

Bases: belay.exceptions.BelayException

Specifier wasn't unique enough to determine a single device.

exception InternalError

Bases: belay.exceptions.BelayException

Internal to Belay logic error.

exception MaxHistoryLengthError

Bases: belay.exceptions.BelayException

Too many commands were given.

exception NoMatchingExecuterError

Bases: belay.exceptions.BelayException

No valid executer found for the given board Implementation.

exception NotBelayResponseError

Bases: belay.exceptions.BelayException

Parsed response wasn't for Belay.

exception SpecialFunctionNameError

Bases: belay.exceptions.BelayException

Attempted to use a reserved Belay function name.

The following name rules are reserved:

  • Names that start and end with double underscore, __.

  • Names that start with _belay or __belay