Skip to content

Python — Message Types

Message metadata classes and builder functions are in nnrp.core.messages.control and nnrp.core.messages.data, re-exported through nnrp.core.

Import

python
from nnrp.core import (
    ClientHelloMetadata, ServerHelloAckMetadata,
    SessionPatchMetadata, SessionPatchAckMetadata,
    FlowUpdateMetadata, ResultHintMetadata,
    TransportProbeMetadata, TransportProbeAckMetadata,
    SessionMigrateMetadata, SessionMigrateAckMetadata,
    CachePutMetadata, CacheAckMetadata, CacheInvalidateMetadata,
    ErrorMetadata, ControlExtensionEntry,
    ClientHelloTransportPolicyExtension, ServerHelloAckTransportPolicyExtension,
    ClientHelloLossToleranceExtension, ServerHelloAckLossToleranceExtension,
    ClientHelloPayloadCapabilitiesExtension, ServerHelloAckPayloadCapabilitiesExtension,
    FrameSubmitMetadata, ResultPushMetadata,
    build_frame_submit_packet, build_result_push_packet,
    build_result_drop_packet, build_frame_cancel_packet,
    build_ping_packet, build_pong_packet,
    build_flow_update_packet, build_result_hint_packet,
    unpack_tensor_body, unpack_tile_index_block,
    unpack_control_extension_block,
)

Control Message Metadata

All control message metadata classes implement .pack() -> bytes and @classmethod .unpack(data: bytes) -> Self.

ClientHelloMetadata

FieldTypeDescription
session_idintClient-assigned session ID
max_viewsintMax concurrent views
enable_cacheboolEnable server-side cache
payload_kind_maskPayloadKindSupported payload type mask

ServerHelloAckMetadata

FieldTypeDescription
session_idintServer-confirmed session ID
transport_idTransportIdSelected transport
enable_cacheboolCache enabled by server
max_cache_entriesintMax cache entries
max_cache_bytesintMax cache bytes
payload_kind_maskPayloadKindServer supported payload types

SessionPatchMetadata

FieldTypeDescription
patch_fieldsSessionPatchFieldFields to update (bitmask)
target_cadenceintTarget frame rate
quality_tierintQuality tier
active_lane_maskintActive view mask
preferred_codecintPreferred codec ID
preferred_compressionintPreferred compression level

SessionPatchAckMetadata

FieldTypeDescription
patch_fieldsSessionPatchFieldSuccessfully applied fields
statusSessionPatchAckStatusApplication status
reject_reasonSessionPatchRejectReasonReject reason (only valid on rejection)

ErrorMetadata

FieldTypeDescription
error_codeErrorCodeError code
error_scopeErrorScopeError scope
session_idintRelated session ID
frame_idintRelated frame ID

FlowUpdateMetadata

FieldTypeDescription
scope_kindFlowUpdateScopeKindUpdate scope
update_reasonFlowUpdateReasonUpdate reason
backpressure_levelFlowUpdateBackpressureLevelBackpressure level
connection_creditintConnection-level credit delta
session_creditintSession-level credit delta
operation_creditintOperation-level credit delta
operation_idintTarget operation ID
retry_after_msintSuggested retry delay (ms)
credit_epochintCredit epoch (anti-reorder)
flagsFlowUpdateFlagsFlags

ResultHintMetadata

FieldTypeDescription
budget_policyResultHintBudgetPolicySuggested budget policy
congestion_stateResultHintCongestionStateCurrent congestion state
reasonResultHintReasonHint reason
frame_idintRelated frame ID
queue_depthintCurrent queue depth
estimated_wait_msintEstimated wait time (ms)

Data Message Metadata

FrameSubmitMetadata

FieldTypeDescription
input_profileInputProfileInput data format
submit_modeSubmitModeSubmission mode
budget_policyBudgetPolicyAllowed degradation policy
payload_kind_bitmapPayloadKindPayload type bitmask
tile_countintTotal tile count
section_countintTensor section count
inference_budget_msintMax inference budget (ms)
deadline_msintAbsolute deadline (ms)

ResultPushMetadata

FieldTypeDescription
result_classResultClassResult completeness class
result_flagsResultFlagsResult flags
applied_budget_policyBudgetPolicyActual applied degradation policy
active_profile_idintInference profile ID used
inference_msintInference time (ms)
queue_msintQueue wait time (ms)
server_total_msintTotal server time (ms)
status_codeintStatus code
tile_index_modeTileIndexModeTile index encoding
covered_tile_countintCovered tile count
dropped_tile_countintDropped tile count
reused_frame_idintReused frame ID (for STALE_REUSE)
payload_kind_bitmapPayloadKindActual payload types present
payload_frame_countintNon-tensor payload frame count

Control Extension Types

python
@dataclass(frozen=True, slots=True)
class ControlExtensionEntry:
    type_id: int
    flags: ControlExtensionFlags
    payload: bytes
ClassDirectionDescription
ClientHelloTransportPolicyExtensionC→SClient declares transport policy preference
ServerHelloAckTransportPolicyExtensionS→CServer confirms transport policy
ClientHelloLossToleranceExtensionC→SClient declares loss tolerance
ServerHelloAckLossToleranceExtensionS→CServer confirms loss tolerance
ClientHelloPayloadCapabilitiesExtensionC→SClient declares supported payload types
ServerHelloAckPayloadCapabilitiesExtensionS→CServer confirms payload capabilities

Packet Builder Functions

python
def build_frame_submit_packet(session_id: int, frame_id: int, *, ...) -> NnrpPacket: ...
def build_result_push_packet(session_id: int, frame_id: int, *, ...) -> NnrpPacket: ...
def build_result_push_mixed_packet(...) -> NnrpPacket: ...
def build_result_push_typed_payload_packet(...) -> NnrpPacket: ...
def build_result_drop_packet(session_id: int, frame_id: int, *, ...) -> NnrpPacket: ...
def build_frame_cancel_packet(session_id: int, frame_id: int, *, ...) -> NnrpPacket: ...
def build_ping_packet(session_id: int, *, frame_id: int = 0, ...) -> NnrpPacket: ...
def build_pong_packet(session_id: int, *, frame_id: int = 0, ...) -> NnrpPacket: ...
def build_flow_update_packet(session_id: int, *, metadata: FlowUpdateMetadata, ...) -> NnrpPacket: ...
def build_result_hint_packet(session_id: int, *, metadata: ResultHintMetadata, ...) -> NnrpPacket: ...

Unpack Utility Functions

python
def unpack_tensor_body(body: bytes, section_count: int) -> TensorBodyView: ...
def unpack_tile_index_block(body: bytes, mode: TileIndexMode) -> tuple[int, ...]: ...
def unpack_control_extension_block(payload: bytes) -> tuple[ControlExtensionEntry, ...]: ...
def unpack_inline_object_blocks(body: bytes) -> ...: ...
def unpack_object_reference_blocks(body: bytes) -> tuple[ObjectReferenceBlock, ...]: ...
def unpack_typed_payload_frames(body: bytes) -> ...: ...
def unpack_body(packet: NnrpPacket) -> ...: ...
def validate_frame_submit_body(packet: NnrpPacket, metadata: FrameSubmitMetadata) -> None: ...

Typical Use Cases

Case 1: Building and sending a FRAME_SUBMIT (low-level)

python
from nnrp.core import build_frame_submit_packet, FrameSubmitMetadata, TensorSectionData
from nnrp import SubmitMode, BudgetPolicy, InputProfile, TileIndexMode

metadata = FrameSubmitMetadata(
    frame_id=100,
    input_profile=InputProfile.CHANGED_TILES_LUMA,
    submit_mode=SubmitMode.INLINE,
    budget_policy=BudgetPolicy.ALLOW_PARTIAL,
    inference_budget_ms=8,
    tile_ids=(3, 7, 12),
    tile_index_mode=TileIndexMode.RAW_U16,
)
section = TensorSectionData(
    role_id=0, dtype_id=0,
    tile_payloads=(tile_3, tile_7, tile_12),
)
packet = build_frame_submit_packet(session_id=42, metadata=metadata, sections=(section,))
await transport.send(packet.pack())

Case 2: Parsing control extensions from a CLIENT_HELLO

python
from nnrp.core import unpack_control_extension_block, ClientHelloTransportPolicyExtension
from nnrp.enums import CLIENT_HELLO_TRANSPORT_POLICY_EXTENSION

extensions = unpack_control_extension_block(packet.metadata)
for entry in extensions:
    if entry.ext_type == CLIENT_HELLO_TRANSPORT_POLICY_EXTENSION:
        ext = ClientHelloTransportPolicyExtension.unpack(entry.payload)
        print("Requested transport policy:", ext.transport_policy)

Case 3: Parsing a RESULT_PUSH and reassembling tiles

python
from nnrp.core import unpack_body
from nnrp.core.enums import MessageType

packet = await connection.receive_packet()
assert packet.header.msg_type is MessageType.RESULT_PUSH
body = unpack_body(packet)
if body.tensor_body:
    for section_idx, section in enumerate(body.tensor_body.sections):
        for tile_idx, tile_bytes in enumerate(section.tile_payloads):
            reconstruct_tile(section_idx, tile_idx, tile_bytes)

Common Pitfalls

WARNING

  1. metadata vs body: NnrpPacket.metadata contains small structured fields (frame ID, budget, policy). NnrpPacket.body contains large binary payloads (Tensor data). Do not call unpack_tensor_body(packet.metadata, ...) — pass packet.body.

  2. tile_ids ordering must match tile_payloads ordering: tile_ids[i] corresponds to tile_payloads[i]. Mixed ordering causes the server to assemble tiles at the wrong positions, producing visual corruption.

  3. validate_frame_submit_body checks structural integrity only, not numerical validity of tensor data. Passing validation does not guarantee the inference engine can process it.

  4. build_result_push_mixed_packet vs build_result_push_typed_payload_packet: the former includes both Tensor and non-Tensor payloads; the latter is for non-Tensor only (e.g., token streams). Mixing them up causes empty sections on the receiver.

NNRP Documentation