Skip to main content

py-pcbu

This library automates interactions with PC Bio Unlock by implementing its protocol.

Installation

pip install py-pcbu

and if you plan on using the CLI, you also need to install the cli extra:

pip install py-pcbu[cli]

Usage

Pairing

  1. First, install PC Bio Unlock normally. Currently, versions >2.0.0 are supported, probably lower versions too.
  2. In the desktop app, click on Pair device. Go through the wizard steps, until you reach the QR Code.
  3. Get the JSON string out of the QR Code. On Android, I can only recommend using the FOSS app https://gitlab.com/Atharok/BarcodeScanner

Then we need to run the pair client using py-pcbu:

Option 1: py-pcbu as CLI

With a conf.local.json file similar to the conf.template.json, one can directly call:

python -m pcbu pair-client

Option 2: py-pcbu as library

Write a TCPPairClient as follows:

from pcbu.tcp.pair_client import TCPPairClient
from pcbu.models import PairingQRData

pairing_data = PairingQRData.from_json(your_qr_json_string_here)

client = TCPPairClient(pairing_qr_data=pairing_data, device_name="My unlock program")
await pair_response = client.pair()
print(pair_response)

This snippet prints in plaintext the payload received from the desktop. It contains sensitive informations such as your account password! So make sure to store it somewhere safe.

Unlocking

Option 1: py-pcbu as CLI

With a conf.local.json file similar to the conf.template.json, one can directly call:

python -m pcbu unlock-server

Option 2 py-pcbu as library

py-pcbu gives a simple TCPUnlockServer to run out of the box. It will automatically unlock any authenticated request matching a stored pairing_id:

from pcbu.models import PCPairing, PCPairingSecret
from pcbu.tcp.unlock_server import TCPUnlockServer

pairings_dicts =   [
    {
        "server_ip_address": "192.168.1.Y",
        "server_port": 43296,
        "pairing_id": "abcdef",
        "desktop_ip_address": "192.168.1.Y",
        "encryption_key": "some_super_long_key",
        "username": "user1@desktop",
        "password": "pwd1"
    },
    {
        "server_ip_address": "192.168.1.Y",
        "server_port": 43297,
        "pairing_id": "ghijk",
        "desktop_ip_address": "192.168.2.Z",
        "encryption_key": "another_super_long_key",
        "username": "user2@desktop",
        "password": "pwd2"
    }
]
pc_pairings = [PCPairingSecret.from_dict(d) for d in pairing_dicts]

async with TCPUnlockServer(pc_pairings) as server:
    await server.start()

This snippet will start a TCPUnlockServer listening on each of the server_ip_address:server_port from the PCPairingSecret list (i.e. on both ports 43296 and 43297). When the server receives an unlocking request, it will validate that the requesting's ip address matches one of the PCPairingSecret instances, decrypt the unlock request, and call the callback method TCPUnlockServerBase.on_valid_unlock_request which automatically accepts the unlocking request in this TCPUnlockServer implementation.

For more advanced use cases, one can also extend TCPUnlockServerBase from pcbu.tcp.unlock_server. The following methods can be overriden to react to events on the unlock server:

  • on_enter(self): called when the server's context is entered.
  • on_start(self): called upon starting the server.
  • on_valid_unlock_request(self, pairing: PCPairing): called when an unlock request has been authenticated and matches one of the registered PC pairings. The match is passed to the method. The basic TCPUnlockServer implementation directly calls self.unlock(pairing) in this method, but one can add other checks or defer the unlocking to a later time.
  • on_invalid_unlock_request(self, ip: str): called when an unlock request could not be authenticated or matched against the registerd pairings. The requesting ip address is passed.
  • on_exit(self): called when the server's context is exited, but just before exiting the individual TCP servers.

Development

For easier development, we include several VSCode launch configuration to allow easier debugging:

  • Pair Server: runs the pair-server CLI command. Emulates a pairing server (i.e. emulates the desktop's PCBU app showing you the QR Code). Automatically binds to the host's ip address, ignoring the .conf one.
  • Pair Client: runs the pair-client CLI command. Expects a pairing server to be up, and initiates the pairing process.
  • Unlock Server: runs the unlock-server CLI command. Waits for unlock requests. Automatically binds to the host's ip address, ignoring the .conf one.

All commands expect a gitignored conf.local.json file at the root of the repository. You can cp conf.template.json conf.local.json to get a base file to start from. Some conf options can be overwritten via CLI options, see

python -m pcbu --help

for more info.

TODOs

  • Rewrite TCPPairServer with asyncio
  • Rewrite TCPPairClient with asyncio
  • Rewrite TCPUnlockServer with asyncio
  • Write a TCPUnlockClient (i.e. emulating a Desktop requesting an unlock) with asyncio
  • Add pair-client command (removing scripts/test_pair.py)
  • Add unlock-client command
  • Handle more failure cases (e.g. rejected UnlockRequest on the client)

Releasing

Releases are automatically created when a change to version in pyproject.toml is detected. The new files are automatically uploaded to PyPI and the signed release is uploaded to GitHub Releases. The current steps to release are:

  1. Make sure pyproject.toml is updated with the new version
  2. Using cucumber/changelog, add the changes and update CHANGELOG.md with the new version
./changelog -o CHANGELOG.md added "Add this and that"
./changelog -o CHANGELOG.md release 0.1.2
  1. Commit the pyproject.toml and CHANGELOG.md changes
  2. Push the changes to GitHub
  3. Wait for the release to be published on PyPI
  4. Wait for the release to be published on GitHub Releases

Metadata

Release files for py-pcbu 0.6.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 py-pcbu 0.6.0
File Size Uploaded
py_pcbu-0.6.0.tar.gz 25.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for py-pcbu 0.6.0
File Interpreter ABI Platform
py_pcbu-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 52.9 kB

Release files / py_pcbu-0.6.0.tar.gz

Download URL py_pcbu-0.6.0.tar.gz
Size 25.7 kB
Tags Source
SHA-256 checksum
How to use checksums
582953e1537697855cf0b8ee193585b90a0fac7c4ee0705018923a316f0ef239
BLAKE2b-256 checksum
How to use checksums
ac1b4f2bab88dcf31059798d143a567154f48dc33b3842a64b2f554c994bbc1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.

Transparency log

Release files / py_pcbu-0.6.0-py3-none-any.whl

Download URL py_pcbu-0.6.0-py3-none-any.whl
Size 27.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
07f6c96e5d991a819506cbbd3ba08e7c599efd1a98bcd3407d4dbe314d1445f4
BLAKE2b-256 checksum
How to use checksums
b6700aa6cd9adbfdde0644c00532a719ab08adbe311c89c13079d8e7a25c8f0f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.

Transparency log

Release history Release notifications | RSS feed

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.1

2 release files

This release

0.6.0 This release

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

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