pydevices

pydevices — Hardware Abstraction Layer & Core Contract.

pydevices Unified pure-Python hardware abstraction layer and core device contract for MicroPython, CircuitPython, CPython, direct WebAssembly, Pyodide, and Android.

Live Pure-Python Device

Installation & a Minimal App

One idiom across every supported interpreter.
# CPython desktop — the complete desktop stack in one command:
pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ pydevices-desktop

# A MicroPython board — install its board_config directly by path:
import mip
mip.install(
    "github:PyDevices/pydevices/board_configs/fbdisplay/esp32-p4-wifi6-touch-lcd-4b",
    index="https://PyDevices.github.io/mip",
)

# Then the same app code runs everywhere:
import board_config
from board_config import display_drv
import appdev
import events

app = appdev.App(board_config)
display_drv.fill(0xF54E00)

def on_click(event):
    print("Clicked at", event.pos)

app.on(events.MOUSEBUTTONDOWN, on_click)
app.run()

Anatomy of the Board Contract

What board_config wires up — the Core Stack from the org homepage diagram.

display_drv — Eager UI Hardware

Display, touch, and primary input initialize immediately on import via a displaydev backend (BusDisplay, SDLDisplay, PSDisplay, and others).

appdev.App — Event & Routing Layer

The host loop and traffic controller. Board configs never import appdev or export app themselves — the application owns this coordinator explicitly.

audiodev

Tone and PCM audio playback, wired the same way across every interpreter and backend.

multimer

Async and sync timers shared by appdev's event loop and application code alike.

events & keys

Shared event types and keycode constants — the same names whether the source is a touchscreen, a keyboard, or a browser canvas.

boarddev — Lazy Extra Peripherals

Sensors, external flash, and power monitoring declared in board_peripherals.py stay uninitialized until the application actually asks for them.

One Contract, Many Board Families

board_configs/ ships a backend for each of these — write against display_drv and swap boards freely.

busdisplay

Real hardware panels over SPI, I2C, or parallel buses via displayif — the path to an actual microcontroller board.

sdldisplay / pgdisplay / windisplay

Desktop simulators (SDL2, pygame, native Win32) for developing and testing without hardware on hand.

fbdisplay

Direct Linux framebuffer and DVI output boards, from Pi Pico DVI sockets to M5Stack Tab5.

pixeldisplay

Addressable LED matrices — NeoPixel (WS2812B) and DotStar (APA102) arrays as a display_drv.

psdisplay

Browser deployment via PyScript / Pyodide — the CPython-in-the-browser path.

jndisplay

Inline rendering inside a Jupyter Notebook cell.

board_configs/cp/

The same board contract adapted for CircuitPython's native display and input modules.

New in 0.5

0.5.1 to 0.5.3, 2026-09-24

A board config hands each driver its bus rather than its pins, and four I2S boards give audiodev the wire and a power hook so the audio pump drives them. android.py stages multi-file examples and their pure-Python dependencies onto the PyDevices Runner on your phone, fetching a missing package from the MIP index. Everything is in the changelog.

Read more

Depth lives in the repository

Newcomer's guide

Installation, the board contract, the architecture and the repository map in one place.

Board bring-up

From a freshly flashed board to a running example: Wi-Fi, then mip.

Android

The prebuilt Runner APK and android.py, which stages any script onto it.

Google Photos example

Pick photos on your phone and browse them on the board: an LVGL app on MicroPython, CircuitPython and CPython.