Encrypted P2P connections from Python, powered by hyperdht-cpp.
- Python 3.8+
- Linux (x86_64 or aarch64)
- Build tools: cmake, ninja, pkg-config
- Libraries: libsodium, libuv
# Debian / Ubuntu
sudo apt install cmake ninja-build pkg-config libsodium-dev libuv1-dev python3
# Fedora
sudo dnf install cmake ninja-build pkgconf libsodium-devel libuv-devel python3
# Arch
sudo pacman -S cmake ninja pkgconf libsodium libuv pythoncd examples/python
./build.shThis builds libhyperdht.so in build-shared/ at the repo root.
The Python wrapper needs libhyperdht.so and libuv.so at runtime. It searches in this order:
HYPERDHT_LIBenv var -- explicit path to the.sofileLD_LIBRARY_PATH-- standard library search path- System paths --
/usr/lib,/usr/local/lib(vialdconfig) - Relative to the package --
../../build-shared/(for development)
Pick whichever works for your setup:
# Option 1: env var (recommended for development)
export HYPERDHT_LIB=/path/to/build-shared/libhyperdht.so
# Option 2: LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/path/to/build-shared:$LD_LIBRARY_PATH
# Option 3: system install
sudo cp build-shared/libhyperdht.so /usr/local/lib/
sudo ldconfiglibuv is usually already installed system-wide (libuv.so.1). If not, install it with your package manager.
python3 keypair_demo.py # keypair generation + deterministic seeds
python3 hash_demo.py "hello world" # BLAKE2b-256 hash
python3 state_demo.py # DHT state inspectionpython3 ping_demo.py # ping a bootstrap node
python3 storage_demo.py put "hello from python" # store data on the DHT
python3 storage_demo.py get <hash> # retrieve by content hash# Terminal 1: start a server
python3 example.py server
# Terminal 2: connect to it
python3 example.py connect <public_key_hex># Start a local web server
python3 webserver.py &
# Expose it over HyperDHT
python3 holesail_server.py --live 8080
# Connect from anywhere (JS holesail or mobile app)
holesail --connect hs://0000...| File | What it does |
|---|---|
keypair_demo.py |
Random, seeded, and deterministic keypair generation |
hash_demo.py |
BLAKE2b-256 hash (same function the DHT uses internally) |
state_demo.py |
Inspect DHT state: health, routing table, stats, suspend/resume |
storage_demo.py |
Immutable and mutable key-value storage on the live DHT |
ping_demo.py |
Direct UDP ping to any DHT node |
example.py |
Server + client + keygen (the main demo) |
holesail_server.py |
P2P tunnel server with --live, --seed, --secure |
webserver.py |
Minimal HTTP server for holesail testing |
test_wrapper.py |
22 automated tests for the Python wrapper |
The library uses a libuv event loop internally. Three rules you must follow:
-
Single-threaded -- all
hyperdhtcalls must happen on the same thread that runsdht.run(). Never callstream.write(),dht.connect(), or any other library function from a background thread. If you need to bridge blocking I/O (like TCP sockets), useselectorsoruv_async_sendto marshal work back to the event loop thread. -
Wait for
on_open-- afterdht.open_stream(), the SecretStream header exchange must complete before you can write. Theon_opencallback signals readiness. Writes beforeon_openreturn error code -1. If you're bridging to a TCP socket, don't start reading from TCP untilon_openfires. -
Callback lifetime -- keep references to all ctypes callback objects (the decorated
@CFUNCTYPEfunctions) for as long as they might be called. If Python garbage-collects a callback while the C library still holds a pointer to it, you get a segfault.
The hyperdht/ package uses ctypes to call libhyperdht.so (the C API).
No Python C extensions, no pip install, no compilation on the Python side.
Just import hyperdht and go.
export HYPERDHT_LIB=../../build-shared/libhyperdht.so
python3 test_wrapper.pyStart a Python server, connect from JavaScript (or vice versa):
# Python server (this machine)
python3 example.py server
# JS client (any machine with hyperdht installed)
node -e "
const DHT = require('hyperdht')
const d = new DHT()
const s = d.connect(Buffer.from('<public_key>', 'hex'))
s.on('open', () => { console.log('CONNECTED!'); d.destroy() })
"