๐ด unaiverse.networking.p2p.p2p
What this module does ๐ด
Implements the high-level P2P node abstraction over the Go libp2p library, exposing connect, disconnect, direct/broadcast messaging, pub/sub topics, relay reservation, and peer discovery as a context-managed Python API.
p2p
¶
โโโโโ โโโโโ โโโโโโ โโโโโ โโโโโ โโโโโ โโโโโ โโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโ โโโโโโโโโโ
โโโโโ โโโโโ โโโโโโโโ โโโโโ โโโโโ โโโโโ โโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ
โโโโ โโโโ โโโโโโโโ โโโโ โโโโโโ โโโโ โโโโ โโโโ โโโโ โ โ โโโโ โโโโ โโโโ โโโ โโโโ โ โ
โโโโ โโโโ โโโโโโโโโโโโโ โโโโโโโโ โโโโ โโโโ โโโโ โโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโ
โโโโ โโโโ โโโโ โโโโโโโโ โโโโโโโ โโโโ โโโโโ โโโ โโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโ
โโโโ โโโโ โโโโ โโโโโโโ โโโโโโโโ โโโโ โโโโโโโโโ โโโโ โ โ โโโโ โโโโ โโโ โโโโ โโโโ โ โ
โโโโโโโโโโ โโโโโ โโโโโโโโโโโโโโโโโ โโโโโ โโโโโ โโโโโโโโโโ โโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโ
โโโโโโโโ โโโโโ โโโโโ โโโโโโโโ โโโโโ โโโ โโโโโโโโโโ โโโโโ โโโโโ โโโโโโโโโ โโโโโโโโโโ
A Collectionless AI Project (https://collectionless.ai)
Registration/Login: https://unaiverse.io
Code Repositories: https://github.com/collectionlessai/
Main Developers: Stefano Melacci (Project Leader), Christian Di Maio, Tommaso Guidi
P2PError
¶
Bases: Exception
Exception raised for errors originating in the Go libp2p layer.
Wraps low-level Go library failures (null results, Go-reported error states, failed connections, failed sends, etc.) so callers can catch a single exception type for all P2P-related problems without inspecting raw C pointers or JSON error payloads.
P2P
¶
P2P(identity_dir: str, port: int = 0, ips: List[str] = None, enable_relay_client: bool = True, enable_relay_service: bool = False, use_broad_limits: bool = False, is_isolated: bool = False, knows_is_public: bool = False, enable_tls: bool = False, domain_name: Optional[str] = None, tls_cert_path: Optional[str] = None, tls_key_path: Optional[str] = None, dht_enabled: bool = True, dht_keep: bool = False, webrtc_enabled: bool = True, flood_sub: bool = False, ice_stun_servers: Optional[List[str]] = None, ice_turn_servers: Optional[List[Dict[str, Any]]] = None, log_sub: str = 'pub')
Python wrapper around the Go libp2p shared library.
Each instance represents one independent libp2p node backed by the Go runtime.
The class manages the full node lifecycle: library initialisation (via
setup_library), node creation (__init__), peer connectivity
(connect_to, disconnect_from), direct and PubSub messaging
(send_message_to_peer, broadcast_message, pop_messages), relay
operations (reserve_on_relay), and graceful shutdown (close).
The Go library is a shared resource: it is loaded once per process and stored
in the class-level libp2p attribute. setup_library must be called
exactly once before any instance is created; subsequent calls are silently
ignored. Up to _MAX_INSTANCES nodes may be active simultaneously; each
instance is assigned a slot in _instance_ids and releases it on
close.
Attributes:
| Name | Type | Description |
|---|---|---|
libp2p |
GoLibP2P
|
Class-level reference to the loaded |
log_sub |
Controls whether this node logs subscription events. Set to
|
Note
The class supports the context-manager protocol. Using a P2P instance
inside a with block guarantees that close is called on exit even
if an exception is raised.
Initialize and start a new libp2p node with the given configuration.
Acquires a free instance slot from the shared _instance_ids pool and
calls the Go CreateNode function with a JSON configuration blob that
encodes all the options listed below. If node creation fails, the slot is
released before re-raising the exception so it can be used by future
instances.
The identity_dir directory is created if it does not already exist. The
node's private key and any TLS certificates are persisted there so that the
peer ID remains stable across restarts.
When both enable_relay_client and enable_relay_service are False,
the relay subsystem is still enabled as a client if enable_relay_service
is True (the client flag is ORed with the service flag internally).
Custom TLS (tls_cert_path / tls_key_path / domain_name) and
AutoTLS (enable_tls with no custom paths) are mutually exclusive. If any
of the custom TLS arguments is supplied, all three must be provided.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
identity_dir
|
str
|
Path to a directory where the node's private key and TLS certificates are loaded from or written to. Created automatically if absent. |
required |
port
|
int
|
TCP port number to listen on. Pass |
0
|
ips
|
List[str]
|
List of IP address strings to bind to. Defaults to |
None
|
enable_relay_client
|
bool
|
If |
True
|
enable_relay_service
|
bool
|
If |
False
|
use_broad_limits
|
bool
|
If |
False
|
is_isolated
|
bool
|
If |
False
|
knows_is_public
|
bool
|
If |
False
|
enable_tls
|
bool
|
If |
False
|
domain_name
|
Optional[str]
|
Domain name for AutoTLS or custom TLS. Required when
|
None
|
tls_cert_path
|
Optional[str]
|
Path to a PEM-encoded TLS certificate file for custom
TLS. Must be provided together with |
None
|
tls_key_path
|
Optional[str]
|
Path to a PEM-encoded TLS private key file for custom
TLS. Must be provided together with |
None
|
dht_enabled
|
bool
|
If |
True
|
dht_keep
|
bool
|
If |
False
|
webrtc_enabled
|
bool
|
If |
True
|
flood_sub
|
bool
|
If |
False
|
ice_stun_servers
|
Optional[List[str]]
|
List of STUN server URIs in the form
|
None
|
ice_turn_servers
|
Optional[List[Dict[str, Any]]]
|
List of TURN server configuration dicts, each
containing |
None
|
log_sub
|
str
|
Subscription logging mode string passed to the Go layer.
Defaults to |
'pub'
|
Raises:
| Type | Description |
|---|---|
P2PError
|
If |
ValueError
|
If a partial set of custom TLS arguments is provided (all
three of |
Source code in unaiverse/networking/p2p/p2p.py
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | |
peer_id
property
¶
Return the peer ID of the local libp2p node.
The value is set during __init__ by parsing the first multiaddress
returned by the Go CreateNode call, and is reset to None after
close is called.
Returns:
| Type | Description |
|---|---|
Optional[str]
|
The peer ID string (e.g. |
Optional[str]
|
or |
Optional[str]
|
been closed. |
addresses
property
¶
Return the current list of multiaddresses from the Go engine.
Delegates to get_node_addresses with an empty peer ID to query the
local node. The Go layer caches address information via internal events,
so the call is effectively O(1). On failure the exception is caught,
logged, and an empty list is returned so callers can safely iterate the
result without additional error handling.
Returns:
| Type | Description |
|---|---|
List[str]
|
A list of multiaddress strings including the |
List[str]
|
or an empty list if the Go call fails. |
is_public
property
¶
Return whether the local node is publicly reachable.
The value is set during __init__ from the "isPublic" field in the
Go CreateNode response. It reflects the reachability state at startup
(or immediately after if knows_is_public was True); it is not
updated dynamically during the node's lifetime.
Returns:
| Type | Description |
|---|---|
Optional[bool]
|
|
Optional[bool]
|
NAT without public reachability, or |
Optional[bool]
|
successfully initialised. |
relay_is_enabled
property
¶
Return whether circuit-relay client functionality is enabled for this node.
The value is set during __init__ as the logical OR of the
enable_relay_client and enable_relay_service constructor arguments,
because enabling the relay service implicitly requires the relay client.
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
the relay service was enabled), |
setup_library
classmethod
¶
setup_library(max_instances: Optional[int] = None, max_channels: Optional[int] = None, max_queue_per_channel: Optional[int] = None, max_message_size: Optional[int] = None, enable_logging: bool = False, unai_logger=None) -> None
Initialize the underlying Go libp2p library with capacity and logging settings.
This class method must be called exactly once per process before any P2P
instance is created. Subsequent calls while the library is already initialised
are silently skipped with a warning. The method configures the Go runtime with
capacity limits, then calls InitializeLibrary on the Go side.
When enable_logging is True and unai_logger is provided and the
FdCapture utility is available, all Go stdout/stderr output is intercepted
at the OS file-descriptor level before the Go library is initialised, so that
every line emitted by the Go runtime (including startup messages) is routed
through unai_logger.p2p() rather than appearing raw on the terminal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_instances
|
Optional[int]
|
Maximum number of simultaneous |
None
|
max_channels
|
Optional[int]
|
Maximum number of channels per instance. Falls back to
|
None
|
max_queue_per_channel
|
Optional[int]
|
Maximum number of queued messages per channel. Falls
back to |
None
|
max_message_size
|
Optional[int]
|
Maximum allowed message size in bytes. Falls back to
|
None
|
enable_logging
|
bool
|
If |
False
|
unai_logger
|
An instance of |
None
|
Raises:
| Type | Description |
|---|---|
P2PError
|
If |
Source code in unaiverse/networking/p2p/p2p.py
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | |
connect_to
¶
Establish a connection to a remote peer identified by its multiaddresses.
The Go ConnectTo function is called with the full list of multiaddresses
so the runtime can try each one in order until a connection succeeds. The
peer ID is extracted from the first multiaddress for logging purposes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
multiaddrs
|
list[str]
|
Non-empty list of multiaddress strings for the target peer
(e.g. |
required |
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary representing the connected peer's |
Dict[str, Any]
|
containing the |
Dict[str, Any]
|
multiaddress strings) keys as returned by the Go library. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
P2PError
|
If the Go |
Source code in unaiverse/networking/p2p/p2p.py
disconnect_from
¶
Close all connections to a specific peer and remove its tracking state.
The Go DisconnectFrom function is called with the peer ID. A format
warning is logged if the ID does not follow the standard libp2p v0
(Qm...) or v1 (12D3...) prefix conventions, but the call is still
attempted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
peer_id
|
str
|
The Peer ID string of the peer to disconnect from. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
P2PError
|
If the Go |
Source code in unaiverse/networking/p2p/p2p.py
send_message_to_peer
¶
Send a direct (unicast) message to a specific peer over the given channel.
The channel string encodes both the transport mode and the target peer ID in
the format <owner_peer_id>::dm:<target_peer_id>-<suffix>. The target peer
ID is extracted from the channel string for logging. The raw byte payload and
its length are forwarded to the Go SendMessageToPeer function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
str
|
Channel identifier string in the direct-message format
|
required |
msg_bytes
|
bytes
|
The serialised message payload as a |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
P2PError
|
If the Go |
Source code in unaiverse/networking/p2p/p2p.py
broadcast_message
¶
Broadcast a message via GossipSub/PubSub to all subscribers of a topic.
All peers that have called subscribe_to_topic with the same channel
string will receive the message. The underlying Go call reuses
SendMessageToPeer with the channel identifying a pubsub topic rather than
a direct peer, distinguished by the ::ps: infix in the channel format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
str
|
Channel identifier string in the pubsub format
|
required |
msg_bytes
|
bytes
|
The serialised message payload as a |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
P2PError
|
If the Go |
Source code in unaiverse/networking/p2p/p2p.py
pop_messages
¶
Retrieve and remove the oldest pending message from each channel queue.
Calls the Go PopMessages function which dequeues one message per
active channel for this instance. The result is deserialized from the Go
pointer to a Python list of raw byte arrays, one entry per message.
The Go layer may return three distinct states:
- "Empty": no messages are waiting; an empty list is returned.
- "Error": a Go-side failure occurred; P2PError is raised.
- A list payload: one or more messages are available and returned.
Returns:
| Type | Description |
|---|---|
List[bytes]
|
A list of |
List[bytes]
|
empty list when no messages are currently queued. |
Raises:
| Type | Description |
|---|---|
P2PError
|
If the Go |
Source code in unaiverse/networking/p2p/p2p.py
subscribe_to_topic
¶
Subscribe to a GossipSub/PubSub topic so that future broadcasts are received.
Calls the Go SubscribeToTopic function with the channel string. After a
successful subscription, messages published on the same channel by any peer
(including via broadcast_message) will appear in subsequent pop_messages
calls. Subscribing to a topic the node is already subscribed to is handled by
the Go layer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
str
|
Channel identifier string in the pubsub format
|
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
P2PError
|
If the Go |
Source code in unaiverse/networking/p2p/p2p.py
unsubscribe_from_topic
¶
Unsubscribe from a GossipSub/PubSub topic to stop receiving its messages.
Calls the Go UnsubscribeFromTopic function with the channel string. After
a successful call, broadcasts on that channel are no longer delivered to this
node's message queue. This is the inverse of subscribe_to_topic.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel
|
str
|
Channel identifier string in the pubsub format
|
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
P2PError
|
If the Go |
Source code in unaiverse/networking/p2p/p2p.py
reserve_on_relay
¶
Reserve a circuit-relay v2 slot on the specified relay node.
Calls the Go ReserveOnRelay function with the target relay's peer ID.
A successful reservation allows this node to be reached through the relay
even when it is behind NAT. The reservation expires at the returned
timestamp; callers are responsible for renewing it before expiry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
relay_peer_id
|
str
|
The peer ID string of the relay node to reserve a slot on. Must be a non-empty string. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The UTC expiration timestamp of the reservation as an ISO 8601 string |
str
|
(e.g. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
P2PError
|
If the Go |
Source code in unaiverse/networking/p2p/p2p.py
get_node_addresses
¶
Return the known multiaddresses for the local node or a specific remote peer.
Calls the Go GetNodeAddresses function. When peer_id is an empty
string, the Go layer returns addresses for the local node; otherwise it
returns addresses it has learned for the given remote peer. This method is
also used internally by the addresses property.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
peer_id
|
str
|
The peer ID string of the target peer. Pass an empty string
(the default) to query the local node's own addresses. Defaults to
|
''
|
Returns:
| Type | Description |
|---|---|
List[str]
|
A list of multiaddress strings, each including the |
List[str]
|
suffix, as returned by the Go library. |
Raises:
| Type | Description |
|---|---|
P2PError
|
If the Go |
Source code in unaiverse/networking/p2p/p2p.py
get_webrtc_connections
¶
Return the list of peers with an active WebRTC DataChannel connection.
Calls the Go GetWebRTCConnections function. Only relevant when the node
was started with webrtc_enabled=True. Each entry describes one peer that
currently has an open WebRTC DataChannel with this node.
Returns:
| Type | Description |
|---|---|
List[Dict[str, Any]]
|
A list of dictionaries, each containing at least |
List[Dict[str, Any]]
|
and |
List[Dict[str, Any]]
|
the Go library. |
Raises:
| Type | Description |
|---|---|
P2PError
|
If the Go |
Source code in unaiverse/networking/p2p/p2p.py
get_connected_peers_info
¶
Return information about all peers currently connected to this node.
Calls the Go GetConnectedPeers function. Unlike most other methods, a
failure here is caught and logged rather than re-raised, and an empty list
is returned instead. This allows the method to be called safely from a
polling loop without risk of crashing the caller.
Returns:
| Type | Description |
|---|---|
List[Dict[str, Any]]
|
A list of dictionaries, each representing a connected peer. Common keys |
List[Dict[str, Any]]
|
include |
List[Dict[str, Any]]
|
|
List[Dict[str, Any]]
|
|
List[Dict[str, Any]]
|
list on error or when no peers are connected. |
Note
Errors are logged but not propagated. Callers that need to distinguish
between an empty result and a failure should use get_message_queue_length
or check the node state independently.
Source code in unaiverse/networking/p2p/p2p.py
get_rendezvous_peers_info
¶
Return the full rendezvous state including discovered peers and metadata.
Calls the Go GetRendezvousPeers function which returns one of three
states:
- "Empty": no rendezvous updates have been received yet; None is
returned.
- "Error": a Go-side failure occurred; P2PError is raised.
- "Success": a rendezvous update is available; the state dict is
returned.
Like get_connected_peers_info, exceptions are caught, logged, and an
empty list is returned to protect polling callers.
Returns:
| Type | Description |
|---|---|
Dict[str, Any] | List | None
|
A dictionary with the rendezvous state containing |
Dict[str, Any] | List | None
|
(list of discovered peer info dicts), |
Dict[str, Any] | List | None
|
|
Dict[str, Any] | List | None
|
rendezvous data has arrived yet; or an empty list if an unexpected |
Dict[str, Any] | List | None
|
error occurs. |
Note
Errors are logged but not propagated. The empty-list fallback on unexpected errors is intentional to avoid crashing polling threads.
Source code in unaiverse/networking/p2p/p2p.py
get_message_queue_length
¶
Return the number of messages currently waiting in the incoming queue.
Calls the Go MessageQueueLength function, which returns a C integer
directly without the JSON envelope used by other calls. The result is
converted via from_go_int. On failure the exception is caught, logged,
and -1 is returned to signal an error without raising.
Returns:
| Type | Description |
|---|---|
int
|
The count of queued messages as a non-negative integer, or |
int
|
the Go call fails. |
Note
A return value of -1 indicates a failure rather than a queue length;
callers should handle this case explicitly when the value is used for
flow control.
Source code in unaiverse/networking/p2p/p2p.py
close
¶
Gracefully shut down the libp2p node and release its instance slot.
Calls the Go CloseNode function. When close_all is True, a
special instance index of -1 is passed to the Go layer to close every
active node at once, and all slots in _instance_ids are reset to
False. When close_all is False, only this instance is closed
and its slot is freed.
After the Go call succeeds, _peer_id is set to None to signal that
the node is no longer active.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
close_all
|
bool
|
If |
False
|
Returns:
| Type | Description |
|---|---|
None | str
|
A human-readable confirmation string such as |
None | str
|
|
None | str
|
|
Raises:
| Type | Description |
|---|---|
P2PError
|
If the Go |
Source code in unaiverse/networking/p2p/p2p.py
1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 | |