Unofficial Python client for the Luckfox PicoKVM JSON-RPC API
Project description
picokvm-client
Python client for the Luckfox PicoKVM.
A thin, synchronous wrapper around its JSON-RPC 2.0 API (POST /api/rpc)
and cookie-auth endpoint (POST /auth/login-local), built on httpx and
jsonrpcclient.
Unofficial. Independent, community-built client. Not affiliated with, authorized by, or endorsed by Luckfox or JetKVM. "PicoKVM" and "JetKVM" belong to their respective owners and are used here only to describe compatibility. No vendor source code is included; this reimplements the device's public JSON-RPC protocol and standard USB HID Boot-Protocol reports.
Compatibility
Targets the Luckfox PicoKVM. Its firmware is a Luckfox-Pico fork of
JetKVM, so the wire protocol currently
overlaps with JetKVM and its other forks. This client is only tested against
the PicoKVM and makes no compatibility promise to JetKVM; a JetKVM is better
served by a dedicated jetkvm-client.
Install
pip install picokvm-client
# or
uv add picokvm-client
CLI
The package installs a picokvm command:
export PICOKVM_URL=http://kvm.example PICOKVM_PASSWORD=hunter2
picokvm ping
picokvm device-id
picokvm video-state
picokvm type "hello world"
picokvm combo "Ctrl+Alt+Del"
picokvm rpc getJigglerState
--url and --password override the environment variables. Run
picokvm --help for the full command list.
Safety. The HID commands (
type,key,combo,click) inject input into whatever host is attached to the KVM. A mistake can lock the keyboard, type into the wrong window, or click at random coordinates. Test against a throwaway target before using these in automation.
Library
from picokvm_client import PicoKVMClient
with PicoKVMClient("http://kvm.example", password="hunter2") as kvm:
if not kvm.ping():
raise RuntimeError("KVM not responding")
state = kvm.get_video_state()
print(f"Video: {state.width}x{state.height}, ready={state.ready}")
kvm.key_combo("Ctrl+Alt+Del")
kvm.type_text("hello world\n")
kvm.click(state.width // 2, state.height // 2)
kvm.mount_with_http("https://files.example.com/installer.iso")
kvm.trigger_reset()
The client owns an httpx.Client that holds the session cookie. Use it as a
context manager so the connection pool and cookie are released on exit.
Methods
Common operations have typed methods. Anything else on the device is reachable
through client.rpc(method, **params), a generic JSON-RPC call.
| Family | Typed methods | Via .rpc() |
|---|---|---|
| HID input | keyboard_report, abs_mouse_report, rel_mouse_report, wheel_report, get_keyboard_led_state, send_usb_wakeup_signal, type_text, click, key_press, key_combo |
macros, layout get/set, jiggler |
| Video | get_video_state, wait_for_video |
EDID, capture |
| Virtual media | mount_with_http, mount_built_in_image, mount_with_storage, unmount_image |
upload, listing |
| Device management | get_device_id, ping, reboot, send_wol_magic_packet |
network, OTA, logs |
| Power | trigger_power, trigger_reset |
hold-power |
| Auth | login (called automatically by __enter__ when a password is set) |
logout |
Exceptions
All exceptions inherit from PicoKVMError (itself a plain Exception, no
third-party base). Each carries advisory exit_code, hint, and retryable
attributes that a caller can map onto its own error type.
| Exception | Raised on |
|---|---|
AuthError |
HTTP 401 from login or RPC |
TransportError |
non-2xx HTTP (other than 401), invalid JSON, network failure |
RpcError |
a JSON-RPC 2.0 error response |
PicoKVMError |
base class for the above |
Examples
Runnable scripts in examples/ (each reads PICOKVM_URL and
PICOKVM_PASSWORD):
| Script | What it does |
|---|---|
| 01_login_and_status.py | Connect, ping, print device ID and video state |
| 02_send_text_and_combo.py | Type a string and send a key combo |
| 03_mount_iso_and_reboot.py | Mount an ISO over HTTP and wait for boot |
Testing
Tests drive the client through httpx.MockTransport, so no sockets are
opened. Each typed method asserts the exact JSON-RPC method and params it
puts on the wire.
The HID commands (type_text, click, key_press, key_combo) are checked
at the payload level only, not against real hardware. Run a manual smoke test
on a throwaway target before relying on them.
Development
uv sync --extra dev
pre-commit install --install-hooks
pre-commit install --hook-type commit-msg
git config commit.template .gitmessage
Checks: uv run pytest, uv run ruff check src tests,
uv run mypy src/picokvm_client --strict. Commit messages follow .gitlint
(subject 10 to 72 chars, body wrapped at 72, Signed-off-by required, so use
git commit -s).
Issues
File issues at https://github.com/onurcelep/picokvm-client/issues.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file picokvm_client-0.1.0.tar.gz.
File metadata
- Download URL: picokvm_client-0.1.0.tar.gz
- Upload date:
- Size: 29.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b691087d7b9ac6df1bcd290e812c0a8085d9ba065832622ded917dd599a6bea
|
|
| MD5 |
432aef5535e170f50fd313f7ccd9e31a
|
|
| BLAKE2b-256 |
a0c7ebd98e2b0303329de16a1769f24f397e54440bb4988e350021a3e7c9a9c7
|
Provenance
The following attestation bundles were made for picokvm_client-0.1.0.tar.gz:
Publisher:
publish.yml on onurcelep/picokvm-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
picokvm_client-0.1.0.tar.gz -
Subject digest:
9b691087d7b9ac6df1bcd290e812c0a8085d9ba065832622ded917dd599a6bea - Sigstore transparency entry: 1924114396
- Sigstore integration time:
-
Permalink:
onurcelep/picokvm-client@1a05f0f8a673f8a3ce6ac6705592d84a0df56de4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/onurcelep
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1a05f0f8a673f8a3ce6ac6705592d84a0df56de4 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file picokvm_client-0.1.0-py3-none-any.whl.
File metadata
- Download URL: picokvm_client-0.1.0-py3-none-any.whl
- Upload date:
- Size: 22.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a747335dd36d7721bed423ec34cc0626e1b09bc4302afe3bbf09628c8fa0a2b
|
|
| MD5 |
7f7a4acd01a5061769ecf8d3d8fcbd47
|
|
| BLAKE2b-256 |
7fffb463c7b60e16bb94267710fdf69542729a6e1e526c45f2bc1dadce835462
|
Provenance
The following attestation bundles were made for picokvm_client-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on onurcelep/picokvm-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
picokvm_client-0.1.0-py3-none-any.whl -
Subject digest:
8a747335dd36d7721bed423ec34cc0626e1b09bc4302afe3bbf09628c8fa0a2b - Sigstore transparency entry: 1924114505
- Sigstore integration time:
-
Permalink:
onurcelep/picokvm-client@1a05f0f8a673f8a3ce6ac6705592d84a0df56de4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/onurcelep
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1a05f0f8a673f8a3ce6ac6705592d84a0df56de4 -
Trigger Event:
workflow_dispatch
-
Statement type: