Proxy Objects
ProxyObject provides a way to interact with remote objects on your MicroPython or CircuitPython device as if they were local Python objects. This is useful for hardware peripherals, custom classes, or modules that cannot be serialized.
Overview
When executing code with task() or __call__(), return values must typically be serializable literals (numbers, strings, lists, dicts, etc.). ProxyObject creates a transparent wrapper for non-serializable objects, forwarding operations to the device automatically.
Creating Proxy Objects
Use Device.proxy() to create proxies:
from belay import Device
device = Device("/dev/ttyUSB0")
# Create and proxy a remote object
device("sensor = TemperatureSensor()")
sensor = device.proxy("sensor")
temp = sensor.temperature
sensor.calibrate()
# Import modules directly
machine = device.proxy("import machine")
pin = machine.Pin(25, machine.Pin.OUT)
pin.on()
Return Value Behavior
Values are automatically returned directly or as proxies based on type:
Immutable types (bool, int, float, str, bytes, none) → returned directly
Mutable types (list, dict, custom objects) → returned as
ProxyObject
temp = sensor.temperature # Returns float directly (e.g., 23.5)
config = sensor.config # Returns ProxyObject wrapping dict
threshold = config["threshold"] # Returns value directly
Working with Collections
Lists, dictionaries, and nested objects work transparently:
# Lists
device("data = [1, 2, 3, 4, 5]")
data = device.proxy("data")
print(data[0], data[-1]) # 1 5
data[0] = 100 # Modify remotely
print(len(data)) # 5
for item in data: # Iterate
print(item)
# Dictionaries
device("config = {'brightness': 10, 'mode': 'auto'}")
config = device.proxy("config")
brightness = config["brightness"] # 10
config["brightness"] = 20
if "mode" in config:
print("Mode configured")
Working with Methods and Modules
Call methods and use modules naturally:
# Methods
device("""
class LED:
def __init__(self, pin):
self.state = False
def on(self):
self.state = True
led = LED(25)
""")
led = device.proxy("led")
led.on()
print(led.state) # True
# Modules
machine = device.proxy("import machine")
led_pin = machine.Pin(25, machine.Pin.OUT) # remotely creates an led_pin object
led_pin.on()
Memory Management
Proxies automatically delete remote references when garbage collected. Use delete=False to prevent this:
# Auto-deletes micropython object when local object "temp" goes out-of-scope and garbage collected.
temp = device.proxy("temp_obj").value
# Never deletes micropython object
machine = device.proxy("import machine", delete=False)