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

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.1.10
File Size Uploaded
beebium-0.1.10.tar.gz 426.3 kB Details

Built distribution (wheel)

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

Total release size: 828.5 kB

Release files / beebium-0.1.10.tar.gz

Download URL beebium-0.1.10.tar.gz
Size 426.3 kB
Tags Source
SHA-256 checksum
How to use checksums
de28c27441a912ec3cd8450f890e3806785d5066704468d98fa38d2d765a27ed
BLAKE2b-256 checksum
How to use checksums
13c95a1028ea07139154d9a36f1eadc514d54e2575c68c9a0c22cf6214c17959
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.10-py3-none-any.whl

Download URL beebium-0.1.10-py3-none-any.whl
Size 402.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7d9bd5b507a27d9b1f5113015a4a038ad072055290d0620b672bc60bea93e567
BLAKE2b-256 checksum
How to use checksums
5ef4e0187ea02e8a204b3a0c7f4341c5d55bfaac225d7f6243d8ca7afd356319
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

0.2.0

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

This release

0.1.10 This release

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