Beebium Python Client
What is Beebium?
Beebium is a headless, cycle-accurate BBC Micro emulator with a client-server architecture. The emulator runs as a server process -- one per machine variant (Model B, B+, B+ 128K, B with ROM/RAM board) -- and is driven entirely over gRPC, so front-ends and automation talk to it across a well-defined protocol rather than being wired into the emulation core.
What is the Python client?
beebium is the Python client for that protocol: a typed API over the gRPC
services for controlling and automating emulator instances from Python -- type
on the keyboard, read the screen in any display mode, peek and poke memory,
drive the debugger, mount discs, and more. It is built for pytest-based testing
of BBC Micro software: a bbc fixture gives each test a fresh machine.
Relationship to beebium-server
beebium-server is a separate, optional package: platform wheels that carry
the emulator itself -- the server binaries, the ROMs, the presets and the
bundled extensions. Install both and you have a complete, self-contained
headless system:
pip install beebium beebium-server
With beebium-server present, Beebium.launch() needs no arguments -- it finds
the server and its ROMs in that wheel. Without it, the client works just as well
with a server installed any other way (Homebrew, the .deb/.rpm packages,
Scoop, or a checkout build) or one already running, reached with
Beebium.connect().
Installation
With uv:
uv add beebium beebium-server # add to your project
# or, into a plain virtualenv:
uv pip install beebium beebium-server
With pip:
pip install beebium beebium-server
beebium-server is optional (see above). On an externally-managed system
install into a virtualenv (or use uv/pipx).
Extras
pip install beebium[imaging] # + Pillow, for saving captured frames as images
pip install beebium[discovery] # + zeroconf, for discovering servers over mDNS
Usage
Every example below is a real test that runs against the beebium-server wheel
(see readme/snippets/), so the code here is the code that runs.
Launch a server
The flagship path: with beebium-server installed, launch() takes no
arguments and stops the server again when the block exits.
from beebium.client import Beebium
# With the beebium-server package installed, launch() needs no arguments:
# the emulator binary and its ROMs come from that wheel, and the server is
# stopped again when the block exits.
with Beebium.launch() as bbc:
bbc.expect("BASIC") # wait for the boot banner / BASIC prompt
bbc.keyboard.type("PRINT 2+2")
bbc.keyboard.press_return()
print(bbc.expect("4")) # -> 4
Connect to a running server
from beebium.client import Beebium
# Connect to a server that is already running. The target defaults to
# localhost on port 48875 (0xBEEB); pass "host:port" to reach another.
with Beebium.connect() as bbc:
bbc.debugger.stop()
print(f"PC = 0x{bbc.cpu.pc:04X}")
Choose a variant or a specific server
from beebium.client import Beebium
# Pick a machine variant: "model-b" (default), "model-b-plus",
# "model-b-plus-128k" or "model-b-romram". To run a specific install
# instead of the default search, pass server="/path/to/beebium" (a binary
# or an install root), or set the BEEBIUM_SERVER environment variable.
with Beebium.launch(variant="model-b-plus") as bbc:
bbc.expect("BASIC")
Type on the keyboard
Given a launched or connected bbc:
bbc.keyboard.type("PRINT 2+2") # type text, shifting as needed
bbc.keyboard.press_return()
bbc.keyboard.key_down("A") # or drive individual keys
bbc.keyboard.key_up("A")
Read the screen
bbc.video.screen_text() reads the displayed text in any mode. For MODE 7
(teletext) work, beebium.client.screen adds helpers -- read_mode7_screen,
screen_contains, find, dump_screen -- that correct for hardware scrolling.
# Read the text the machine is displaying, whatever the screen mode.
text = bbc.video.screen_text().text
# Wait (up to a timeout) for text to appear -- pexpect-style automation.
bbc.expect("BASIC")
Read and write memory
# Side-effect-free peek -- safe even for I/O registers.
via_flags = bbc.memory.address.peek[0xFE4D] # System VIA IFR
zero_page = bbc.memory.address.peek[0x0000:0x0100]
# Follow a 6502 vector (16-bit little-endian).
wrchv = bbc.memory.address.peek.word(0x020E) # the OSWRCH vector
# Bus access reads and writes through the memory bus, like real hardware.
bbc.memory.address.bus[0x1900] = 0x42
value = bbc.memory.address.bus[0x1900]
Drive the debugger
state = bbc.debugger.stop() # pause; returns the execution state
print(state.is_running) # -> False
print(bbc.cpu.registers) # A=.. X=.. Y=.. SP=.. PC=.. P=.. [flags]
# Break the next time the OS writes a character, then let it run. The
# breakpoint is removed automatically when the block exits.
with bbc.debugger.breakpoint(0xFFEE): # OSWRCH entry point
bbc.keyboard.type("X") # the echoed key drives OSWRCH
bbc.debugger.run_and_wait_for_stop()
print(f"stopped at PC=0x{bbc.cpu.pc:04X}")
Testing with pytest
Installing beebium registers the pytest plugin, so the bbc fixture is
available with no extra configuration:
# The beebium pytest plugin registers a `bbc` fixture: a fresh BBC Micro,
# launched and torn down per test. Install beebium and it is available with no
# conftest wiring.
def test_print(bbc):
bbc.expect("BASIC")
bbc.keyboard.type("PRINT 2+2")
bbc.keyboard.press_return()
assert bbc.expect("4") == "4"
Companion fixtures: bbc_shared (one machine per module), stopped_bbc (starts
paused), and the session-scoped mos_filepath / basic_filepath. Point the
plugin at a server or ROMs with --beebium-server / --beebium-rom-dir (or the
BEEBIUM_SERVER / BEEBIUM_ROM_DIR environment variables).
Further reading
Fuller documentation and runnable programs live in the repository: see
docs/ for the
gRPC service reference and subsystem guides, and
examples/
for end-to-end scripts. (Later: links to the published API reference.)
Contributing
Development happens in the
Beebium repository. This README is
generated -- do not edit README.md directly. See
CONTRIBUTING.md for the checkout, uv and wheel-test workflow
and for how to edit the README (its template and snippets).
License
GPL-3.0-or-later. See COPYING.txt.
Release files for beebium 0.1.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| beebium-0.1.8.tar.gz | 426.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| beebium-0.1.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 828.5 kB
Release files / beebium-0.1.8.tar.gz
| Download URL | beebium-0.1.8.tar.gz |
|---|---|
| Size | 426.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c52a5a0b536d7b553b8acc734c69834dca6e3efe1986a2b8c2e24cf5301d6186
|
|
BLAKE2b-256 checksum How to use checksums |
373367383361ebc4c39fcccd3ec545ef3433ddf99e016359e9855fe5b436304e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / beebium-0.1.8-py3-none-any.whl
| Download URL | beebium-0.1.8-py3-none-any.whl |
|---|---|
| Size | 402.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fb2c3f63b15035d597bd0f30cb356ec3cd2f66bedb598521dfef2b524a7c5cbd
|
|
BLAKE2b-256 checksum How to use checksums |
5b74a813ab14a8b123a4d401accb42f57673859313a2b89b48d15ac753c07eb9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|