Skip to content

raknet

PyPI Python License

Python bindings for RakNet, the UDP networking library used by Minecraft Bedrock. It ships a faithful binding of RakNet's public API and a pythonic layer on top of it, with both a synchronous and an asyncio interface.

import raknet

with raknet.create_connection(("play.example.com", 19132), timeout=5) as conn:
    conn.send(b"\xfe...")          # a Bedrock game packet
    print(conn.recv(timeout=5))

Installation

pip install raknet

Requires Python 3.12 or newer. Prebuilt abi3 wheels are published for Windows and Linux (x86-64); a single wheel works across all supported Python versions.

The three layers

Module Interface Use it for
raknet synchronous blocking servers and clients, threads
raknet.asyncio asyncio event-loop applications; mirrors the sync API with await
raknet.raw faithful C++ binding direct access to RakPeerInterface and every RakNet type

The two high-level layers share one connection model: a Peer accepts and initiates connections, and each Connection is a message pipe with send / recv. Anything the high-level layer does not cover is reachable through peer.raw.

Quick start

Server

import raknet

def handle(connection):
    for message in connection:      # iterates until the peer disconnects
        connection.send(message)    # echo it back

with raknet.create_server(("0.0.0.0", 19132), max_connections=32) as server:
    server.serve_forever(handle)    # one thread per connection

Client

import raknet

with raknet.create_connection(("127.0.0.1", 19132), timeout=5) as conn:
    conn.send(b"\xfehello")
    reply = conn.recv(timeout=5)

asyncio

The asyncio layer is the same API with await in front; per-call timeouts are left to asyncio.timeout().

import asyncio
import raknet.asyncio

async def handle(connection):
    async for message in connection:
        await connection.send(message)

async def main():
    server = await raknet.asyncio.create_server(("0.0.0.0", 19132))
    async with server:
        await server.serve_forever(handle)

asyncio.run(main())

Server-list ping

pong = raknet.ping(("play.example.com", 19132), timeout=5)
print(pong.round_trip_time, pong.data)

More runnable programs are in examples/.

Messages

send and recv move bytes verbatim; there is no added framing. RakNet reads the first byte of every packet as a message id and only delivers packets whose id is a user id (>= 0x86, ID_USER_PACKET_ENUM). Lower ids are consumed as RakNet's own control traffic, so each payload must begin with a user id. Minecraft Bedrock uses 0xFE. Reliability, priority and the ordering channel are per-call:

conn.send(data, reliability=raknet.PacketReliability.RELIABLE_ORDERED,
          priority=raknet.PacketPriority.HIGH_PRIORITY, channel=0)

Errors

Failures raise exceptions rather than returning sentinels. All inherit from RakNetError, and the connection-lifecycle ones also inherit from the builtin ConnectionError.

Exception Raised when
StartupError the peer could not bind its socket
ConnectError a connection attempt was rejected (.reason carries the cause)
ConnectionClosedOK the remote disconnected gracefully
ConnectionClosedError the connection was lost without notice
TimeoutError a timeout= elapsed (the builtin)

Building from source

Building needs a C++17 compiler and Conan. The raknet recipe is hosted on the endstone remote:

conan remote add endstone https://conan.cloudsmith.io/endstone/conan/
pip install .

The conan-py-build backend drives Conan and CMake, so no separate conan install step is required.

Development

pip install -e .
pytest

License

BSD-3-Clause. See LICENSE.

RakNet is © Oculus VR and released under a BSD-style license.

About

Python bindings for the RakNet networking library with synchronous and asyncio APIs

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

71 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages