Skip to main content

QUIC library with NAT traversal

Project description

QUIC Portal (experimental)

⚠️ Warning: This library is experimental and not intended for production use.

High-performance QUIC communication library with automatic NAT traversal within Modal applications.

Features

  • Automatic NAT traversal: Built-in STUN discovery and UDP hole punching, using Modal Dict for rendezvous.
  • High-performance QUIC: Rust-based implementation for maximum throughput and minimal latency
  • Simple API: Easy-to-use Portal class with static methods for server/client creation. WebSocket-style messaging.

Installation

# Install from PyPi (only certain wheels built)
pip install ...
# Install from source (requires Rust toolchain)
git clone <repository>
cd quic-portal
pip install .

Quick Start

Usage with Modal

import asyncio
import modal
from quic_portal import Portal

app = modal.App("my-quic-app")

@app.function()
async def server_function(coord_dict: modal.Dict):
    # Create server with automatic NAT traversal
    portal = await Portal.create_server(dict=coord_dict, local_port=5555)
    
    # Receive and echo messages
    while True:
        data = await portal.recv(timeout_ms=10000)
        if data:
            message = data.decode("utf-8")
            print(f"Received: {message}")
            await portal.send(f"Echo: {message}".encode("utf-8"))

@app.function()
async def client_function(coord_dict: modal.Dict):
    
    # Send messages
    await portal.send(b"Hello, QUIC!")
    response = await portal.recv(timeout_ms=5000)
    if response:
        print(f"Got response: {response.decode('utf-8')}")

@app.local_entrypoint()
async def main(local: bool = False):
    # Create ephemeral coordination dict
    async with modal.Dict.ephemeral() as coord_dict:
        # Start server
        server_task = await server_function.spawn.aio(coord_dict)
        
        # Run client
        if local:
            # Run test between local environment and remote container.
            await client_function.local(coord_dict)
        else:
            # Run test between two containers.
            await client_function.remote.aio(coord_dict)
        
        server_task.cancel()

Manual NAT Traversal

For advanced use cases where you handle NAT traversal yourself, or the server has a public IP:

from quic_portal import Portal

# After NAT hole punching is complete...
# Server side
server = Portal(local_port=5555)
await server.listen(5555)

# Client side  
client = Portal(local_port=5556)
await client.connect("server_ip", 5555, 5556)

# WebSocket-style messaging
await client.send(b"Hello!")
response = await server.recv(timeout_ms=1000)

API Reference

Portal Class

Static Methods

Portal.create_server(dict, local_port=5555, stun_server=("stun.ekiga.net", 3478), punch_timeout=15)

Create a server portal with automatic NAT traversal.

Parameters:

  • dict (modal.Dict): Modal Dict for peer coordination
  • local_port (int): Local port for QUIC server (default: 5555)
  • stun_server (tuple): STUN server for NAT discovery (default: ("stun.ekiga.net", 3478))
  • punch_timeout (int): Timeout in seconds for NAT punching (default: 15)

Returns: Connected Portal instance ready for communication

Portal.create_client(dict, local_port=5556, stun_server=("stun.ekiga.net", 3478), punch_timeout=15)

Create a client portal with automatic NAT traversal.

Parameters:

  • dict (modal.Dict): Modal Dict for peer coordination (must be same as server)
  • local_port (int): Local port for QUIC client (default: 5556)
  • stun_server (tuple): STUN server for NAT discovery (default: ("stun.ekiga.net", 3478))
  • punch_timeout (int): Timeout in seconds for NAT punching (default: 15)

Returns: Connected Portal instance ready for communication

Instance Methods

send(data: Union[bytes, str]) -> None

Send data over QUIC connection (WebSocket-style).

recv(timeout_ms: Optional[int] = None) -> Optional[bytes]

Receive data from QUIC connection. Blocks until message arrives or timeout.

Parameters:

  • timeout_ms (int, optional): Timeout in milliseconds (None for blocking)

Returns: Received data as bytes, or None if timeout

is_connected() -> bool

Check if connected to peer.

close() -> None

Close the connection and clean up resources.

Examples

See the examples/ directory for complete working examples:

  • modal_simple.py - Basic server/client communication
  • modal_benchmark.py - Performance benchmarking

Requirements

  • Python 3.8+
  • Modal (for automatic NAT traversal)
  • Rust toolchain (for building from source)

License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quic_portal-0.1.0.tar.gz (26.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

quic_portal-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.34+ x86-64

quic_portal-0.1.0-cp38-abi3-macosx_11_0_arm64.whl (1.2 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

File details

Details for the file quic_portal-0.1.0.tar.gz.

File metadata

  • Download URL: quic_portal-0.1.0.tar.gz
  • Upload date:
  • Size: 26.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.8.6

File hashes

Hashes for quic_portal-0.1.0.tar.gz
Algorithm Hash digest
SHA256 43c2c2055cb0324a96c9c97d4fb8cfb13f9cc8b766e010be7b0f04cfe34f5746
MD5 15b6cc352348a3f0b30e9564a97c41fb
BLAKE2b-256 e493bee3efca7cf75a78d51fe45712eafcd30183007c17faf5145612772145b4

See more details on using hashes here.

File details

Details for the file quic_portal-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for quic_portal-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 b4803a9d408557f94107a94fe5e6e19e409584ee764c8768df319012d8fe7eaa
MD5 799c36d462a913a347023ebf10c1f28b
BLAKE2b-256 a2318d8de8b485c14d9923b4a3716532e9bbe879576fad8674bbea92278841ae

See more details on using hashes here.

File details

Details for the file quic_portal-0.1.0-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for quic_portal-0.1.0-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e02de97512a73d47b891ffe5946e58b929758f21d19e547e78a823283b7a5ff5
MD5 08c6c6024829d985b2ee3a063bbc405d
BLAKE2b-256 a84bdcbf35b0931f66265341607629cdbbd9d9b04c4e9aa0bd754ffd75286503

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page