Skip to main content

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.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for beebium 0.2.0
File Size Uploaded
beebium-0.2.0.tar.gz 459.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for beebium 0.2.0
File Interpreter ABI Platform
beebium-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 866.4 kB

Release files / beebium-0.2.0.tar.gz

Download URL beebium-0.2.0.tar.gz
Size 459.9 kB
Tags Source
SHA-256 checksum
How to use checksums
89287b4d7139fa60a5a426015445563810e9d39fcf5571be38286aa3904ea534
BLAKE2b-256 checksum
How to use checksums
a146156cd45b95a34047ae1f14953ea4e443bba6d37211511d70221c48938ec1
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.2.0-py3-none-any.whl

Download URL beebium-0.2.0-py3-none-any.whl
Size 406.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fcea8bb5f6738d66b7b8a0ab51cc2c607f14d80a53d3fb5ec1b8980cf4639f8c
BLAKE2b-256 checksum
How to use checksums
646db66ebaf9d3840a449ca79e896f6d8015c1a709aad1fbf5b43cf4da090c43
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 history Release notifications | RSS feed

0.4.0

2 release files

0.3.0

2 release files

This release

0.2.0 This release

2 release files

0.1.17

2 release files

0.1.16

2 release files

0.1.15

2 release files

0.1.14

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page