Skip to main content

High-performance Python bindings for nng (nanomsg-next-gen)

Project description

nng

High-performance Python bindings for nng (nanomsg-next-gen), written in Cython.

Nanomsg-next-gen (NNG) is a messaging library written in C. It provides a small, consistent API for building distributed applications around a set of well-defined communication patterns: request-reply, publish-subscribe, pipeline, pair, survey, and bus. The library handles message framing, back-pressure, reconnection, and transport selection, so application code can focus on the protocol logic.

Table of contents

Why use a library like NNG rather than sockets directly?

The Python standard library has a lot of available functions for communicating with sockets between processes on the same or different computers.

Sockets are essentially data queues managed by the kernel and used to communicate between processes. When connecting to a website via TCP, or when receiving a video stream via UDP, you use sockets.

With the Python standard library, there are essentially two main ways to use sockets:

  • via the socket library.
  • via asyncio.

NNG provides an abstraction on top, enabling shorter and easier-to-read code. It provides a socket-like interface, except that:

  • The socket can listen on or bind to several interfaces at the same time.
  • It is possible to send or wait on a message before a peer has connected
  • Rather than handling individual connections with connected peers, you use a socket type that has implicit handling of peers. For instance a PUB socket will send a copy of any message sent to all connected peers.
  • Message semantics is directly handled (low level sockets are typically configured to receive a bytestream rather than messages). A background thread handles receiving incoming messages and queuing them (you need to quickly handle the reception of incoming messages to prevent blocking reception if the kernel queue is full).
  • Reconnection is handled automatically

Underneath, NNG is similar to a dedicated thread running asyncio. Both use epoll/kqueue/iocp to quickly detect sockets ready for reading/writing. It is programmed in C and fully thread-safe. Because it uses a dedicated thread, you can get asynchronous I/O without asyncio. submit_recv returns a future that resolves when a message is received. However this Python library also integrates NNG to an existing asyncio loop.

Don't use NNG if:

  • You want the lowest latency possible. In terms of latency, asyncio NNG (arecv) > raw asyncio > NNG (recv) > raw socket. If you want below, don't use Python. See PERFORMANCE.md for detailed benchmarks and interpretation.
  • You want to share heavy amount of data. NNG is based on TCP and similar, while for video streaming or remote desktop, UDP with custom handling of lost packets is more appropriate. For inter-process large data sharing, shared memory is preferred over named pipes/unix sockets (which NNG ipc uses), as they avoid kernel copies. If you don't need to maximize performance and can accept some data copies, NNG is appropriate though.
  • You need to integrate with another protocol (HTTP, custom, etc)

Use NNG if:

  • You are building distributed or multi-process applications and want well-defined message semantics without managing low-level socket details.
  • You need multiple communication patterns (request-reply, pub-sub, pipeline, pair, survey, bus) with a consistent, interchangeable API.
  • You want automatic reconnection, back-pressure, and message framing out of the box.
  • You want to mix blocking calls, asyncio coroutines, and concurrent.futures within the same codebase.
  • You need concurrent request handling on a server without the overhead of one thread per client (use contexts).
  • You want the same API for ipc, tcp or inproc endpoints
  • You don't want to manage each connection individually
  • You don't want to require asyncio to get asynchronous server/client connections, send/recv.

Why yet another Python wrapper for NNG?

Two Python wrappers for NNG already existed when this project was started.

My motivation for writing a third one came from practical experience with ZeroMQ. When looking for a first message library to experiment upon, it is quite natural to start with ZeroMQ, which is heavily used. However, what seemed simple on paper, lead to a lot of boilerplate to have things work properly. I was not satisfied and gave up on the topic for some time. After coming back on the topic, I decided to give NNG a try. However, the existing wrappers did not feel as complete as PyZMQ: docstrings were sparse, error handling was inconsistent, and there were no benchmarks to help make informed choices.

A more specific concern was asyncio overhead. The ZeroMQ Python bindings had measurable overhead in async code, which I had partially mitigated with a custom selector backed by zmq_poll. NNG's callback-based completion model seemed more amenable to tight asyncio integration. Achieving that level of integration requires Cython, which the other wrappers did not use.

The result is a library with:

  • Full type annotations and docstrings on all public symbols.
  • A .pyi stub file automatically generated from the compiled extension.
  • Synchronous send/recv, async (await), and thread-safe concurrent.futures variants on every socket and context.
  • Explicit error hierarchy: every nng error code maps to a typed Python exception.
  • Benchmarks of the various send/recv alternatives, with and without encryption.
  • Examples covering every communication pattern.

What I like about NNG

Having used both ZeroMQ and NNG, I found that ZeroMQ quickly pushes you toward ROUTER sockets everywhere, which removes constraints but adds significant complexity that is easy to get wrong (client failure handling, heartbeats, etc). NNG, by contrast, provides richer built-in socket behaviour and more flexibility. Need to handle several clients concurrently? Just open several contexts on the same socket. The context system is powerful and lightweight, and was well-designed to keep application logic simple.

Another key difference is that NNG is designed to be fully thread-safe. Closing a socket from another thread is safe and will simply cause pending operations to fail with NngClosed, making it much easier to write clean shutdown code without worrying about synchronization or cancellation. NNG also has built-in TLS support.

Installation

The package requires Python 3.11 or later and a C++ compiler. NNG is bundled as a submodule and compiled automatically.

pip install nng

For TLS support (tls+tcp://, wss://), install the pre-built package that bundles Mbed TLS:

pip install nng-ssl

The nng-ssl wheel is drop-in compatible with nng; the same import nng works for both. Install one or the other, not both.

To build from source:

git clone --recurse-submodules https://github.com/axeldavy/python-nng.git
cd python-nng
pip install .

See TLS support for instructions on enabling TLS at build time.

Quick start

REP / REQ

The REQ/REP pattern implements synchronous request-reply. The requester sends a message and blocks until a reply arrives. The replier receives one request at a time and must send exactly one reply before receiving the next.

import nng

# Server side (in a thread or separate process)
rep = nng.RepSocket()
rep.add_listener("tcp://127.0.0.1:5555").start()
while True:
    msg = rep.recv()
    rep.send(b"pong")

# Client side
req = nng.ReqSocket()
req.add_dialer("tcp://127.0.0.1:5555").start()
req.send(b"ping")
reply = req.recv()
print(reply)  # "pong"

To handle multiple clients concurrently on the server side without threads, open independent contexts. Each context maintains its own request-reply state machine:

import asyncio
import nng

async def handle(ctx: nng.Context) -> None:
    while True:
        msg = await ctx.arecv()
        await ctx.asend(b"pong")

async def main() -> None:
    rep = nng.RepSocket()
    rep.add_listener("tcp://127.0.0.1:5555").start()
    workers = [rep.open_context() for _ in range(8)]
    await asyncio.gather(*(handle(ctx) for ctx in workers))

PUB / SUB

The PUB/SUB pattern distributes messages from one publisher to any number of subscribers. Subscribers receive only messages whose body starts with a registered prefix.

import nng

# Publisher
pub = nng.PubSocket()
pub.add_listener("tcp://127.0.0.1:5556").start()
pub.send(b"news.sports result of the match")
pub.send(b"news.weather it will rain")

# Subscriber
sub = nng.SubSocket()
sub.add_dialer("tcp://127.0.0.1:5556").start()
sub.subscribe(b"news.sports")   # receive only sports messages
# sub.subscribe(b"")            # or subscribe to everything
msg = sub.recv()

There is no acknowledgment: if a subscriber cannot consume messages fast enough, the oldest messages in its buffer are dropped by default. The publisher is never blocked by a slow subscriber.

PUSH / PULL

The PUSH/PULL pattern distributes work items across a pool of workers. Each message goes to exactly one worker, chosen by load-balancing.

import nng

# Work distributor
push = nng.PushSocket()
push.add_listener("tcp://127.0.0.1:5557").start()
for i in range(100):
    push.send(f"task-{i}")

# Worker (run several of these in parallel)
pull = nng.PullSocket()
pull.add_dialer("tcp://127.0.0.1:5557").start()
while True:
    task = pull.recv()
    print("processing", task)

PAIR

The PAIR pattern connects exactly two sockets in a bidirectional channel. It is the simplest pattern: each side can send and receive freely. Once a peer has connected, no other peer can connect (even after a disconnect). This makes it ideal for in-process communication between threads, or for one-to-one protocols between processes.

import nng

srv = nng.PairSocket()
srv.add_listener("inproc://myapp").start()

cli = nng.PairSocket()
cli.add_dialer("inproc://myapp").start()

cli.send(b"hello")
print(srv.recv())  # "hello"

Async support

Every socket and context exposes three ways to send and receive:

Method Description
send / recv Blocking call. Releases the GIL while waiting.
asend / arecv Coroutines. Use with await inside an asyncio event loop.
submit_send / submit_recv Returns a concurrent.futures.Future, which resolves upon completion.

Note that it is possible to mix them, or call them concurrently from multiple threads. In addition it is worth noting that Ctrl-C is fully supported (unlike in some other libraries), even with send and recv.

import asyncio
import nng

async def main() -> None:
    rep = nng.RepSocket()
    rep.add_listener("tcp://127.0.0.1:5558").start()

    req = nng.ReqSocket()
    req.add_dialer("tcp://127.0.0.1:5558").start()

    await req.asend(b"hello")
    msg = await rep.arecv()
    await rep.asend(msg.to_bytes().upper())
    reply = await req.arecv()
    print(reply)  # "HELLO"

asyncio.run(main())

The library also provides async generators arecv_ready and asend_ready for advanced use; each yields once every time the socket transitions from not-ready to ready.

Transports

All transports are selected by URL scheme and are otherwise interchangeable from application code.

Scheme Description
tcp://host:port TCP/IP. Accepts both IPv4 and IPv6. Use tcp4:// or tcp6:// to force one version.
ipc:///path Unix domain sockets (POSIX) or named pipes (Windows).
inproc://name In-process communication within the same Python process. Zero-copy where possible.
abstract://name Linux abstract namespace sockets. Not persisted to the filesystem.
tls+tcp://host:port TCP with TLS. Requires a TLS-enabled build (see below).
ws://host:port/path WebSocket.
wss://host:port/path WebSocket over TLS.

Listeners bind to an address; dialers connect to one. The distinction is orthogonal to the protocol role: a REP socket can dial and a REQ socket can listen.

To bind to an ephemeral TCP port, pass port 0 in the listener URL. The assigned port can be retrieved from listener.port after start() returns.

Communication patterns

Socket pair Pattern Use case
ReqSocket / RepSocket Request-reply RPC, command-response
PubSocket / SubSocket Publish-subscribe Event fan-out, topic feeds
PushSocket / PullSocket Pipeline Task queues, stream processing
PairSocket / PairSocket Pair Bidirectional point-to-point channel
SurveyorSocket / RespondentSocket Survey Voting, service discovery
BusSocket / BusSocket Bus All-to-all broadcast mesh

Each pattern has well-defined send/recv semantics. Violating them — for instance calling send twice on a ReqSocket without an intervening recv — raises NngState.

TLS support

By default, nng is built without TLS support to keep the package pure MIT.

Pre-built wheel with TLS

The easiest way to get TLS support is the nng-ssl package on PyPI. It bundles Mbed TLS 4.1.0 (Apache-2.0 license) compiled as a static library and requires no extra system dependencies:

pip install nng-ssl

nng-ssl installs as the nng Python package, so existing code is unchanged. Do not install both nng and nng-ssl in the same environment.

Build from source with Mbed TLS (auto-fetched)

To build nng-ssl locally, Mbed TLS is downloaded and compiled automatically during the cmake configure step (internet access required at build time):

git clone --recurse-submodules https://github.com/axeldavy/python-nng.git
cd python-nng
cp builtin_tls/pyproject.toml pyproject.toml
pip install .

Build from source with a system TLS library

You can also build nng (not nng-ssl) against an independently installed TLS library:

# Mbed TLS (system-installed)
pip install . --config-settings "cmake.define.NNG_ENABLE_TLS=ON" --config-settings "cmake.define.NNG_TLS_ENGINE=mbed"

# OpenSSL
pip install . --config-settings "cmake.define.NNG_ENABLE_TLS=ON" --config-settings "cmake.define.NNG_TLS_ENGINE=openssl"

# wolfSSL
pip install . --config-settings "cmake.define.NNG_ENABLE_TLS=ON" --config-settings "cmake.define.NNG_TLS_ENGINE=wolf"

Once built, TLS connections use the tls+tcp:// scheme. Configuration is handled through TlsConfig:

import nng

srv_cfg = nng.TlsConfig.for_server(
    cert_pem=open("server.crt").read(),
    key_pem=open("server.key").read(),
    ca_pem=open("ca.crt").read(),       # required for mutual TLS
    auth_mode=nng.TLS_AUTH_REQUIRED,
    min_version=nng.TLS_VERSION_1_3,
)

rep = nng.RepSocket()
lst = rep.add_listener("tls+tcp://0.0.0.0:0", tls=srv_cfg)
lst.start()
print(f"listening on port {lst.port}")

Three authentication modes are available:

Constant Meaning
TLS_AUTH_NONE No peer certificate is requested.
TLS_AUTH_OPTIONAL A peer certificate is verified if presented.
TLS_AUTH_REQUIRED A peer certificate is required (mutual TLS). This is the default for clients.

TLS 1.2 and 1.3 are supported. The minimum and maximum protocol versions can be set via min_version and max_version using the TLS_VERSION_1_2 and TLS_VERSION_1_3 constants.

A comparison of plain, libsodium-encrypted, and TLS-encrypted throughput at various payload sizes is available in examples/PAIR/secure_subscriber/bench_overhead.py.

Performance

See PERFORMANCE.md for detailed benchmarks and interpretation.

In brief: on a local machine the async round-trip overhead (excluding cipher cost) is on the order of a few microseconds for inproc, and grows with transport cost for IPC and TCP. TLS throughput depends heavily on whether the TLS backend was compiled with hardware AES acceleration.

On the use of AI

Much of the writing has been assisted by AI (Claude Sonnet 4.6), in particular the benchmark code and the unit tests. I have 12 years of Python experience, and more in C/C++. I have written another Cython-based library DearCyGui. Thus while AI has been a great help, I have extensively reviewed, extended, and modified the code and documentation, and I am confident that the code is of good quality. If you find any issue, please open an issue or a PR.

License

python-nng is licensed under the MIT License. See LICENSE for more details.

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

nng-0.2.0.tar.gz (968.5 kB view details)

Uploaded Source

Built Distributions

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

nng-0.2.0-cp314-cp314t-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.14tWindows x86-64

nng-0.2.0-cp314-cp314t-manylinux_2_28_x86_64.whl (913.3 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.28+ x86-64

nng-0.2.0-cp314-cp314t-macosx_11_0_arm64.whl (788.0 kB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

nng-0.2.0-cp314-cp314t-macosx_10_15_x86_64.whl (828.4 kB view details)

Uploaded CPython 3.14tmacOS 10.15+ x86-64

nng-0.2.0-cp314-cp314-win_amd64.whl (1.0 MB view details)

Uploaded CPython 3.14Windows x86-64

nng-0.2.0-cp314-cp314-manylinux_2_28_x86_64.whl (917.9 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

nng-0.2.0-cp314-cp314-macosx_11_0_arm64.whl (770.3 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

nng-0.2.0-cp314-cp314-macosx_10_15_x86_64.whl (814.1 kB view details)

Uploaded CPython 3.14macOS 10.15+ x86-64

nng-0.2.0-cp313-cp313t-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.13tWindows x86-64

nng-0.2.0-cp313-cp313t-manylinux_2_28_x86_64.whl (912.2 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.28+ x86-64

nng-0.2.0-cp313-cp313t-macosx_11_0_arm64.whl (786.9 kB view details)

Uploaded CPython 3.13tmacOS 11.0+ ARM64

nng-0.2.0-cp313-cp313t-macosx_10_15_x86_64.whl (826.7 kB view details)

Uploaded CPython 3.13tmacOS 10.15+ x86-64

nng-0.2.0-cp313-cp313-win_amd64.whl (1.0 MB view details)

Uploaded CPython 3.13Windows x86-64

nng-0.2.0-cp313-cp313-manylinux_2_28_x86_64.whl (915.7 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

nng-0.2.0-cp313-cp313-macosx_11_0_arm64.whl (767.7 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

nng-0.2.0-cp313-cp313-macosx_10_15_x86_64.whl (812.5 kB view details)

Uploaded CPython 3.13macOS 10.15+ x86-64

nng-0.2.0-cp312-cp312-win_amd64.whl (1.0 MB view details)

Uploaded CPython 3.12Windows x86-64

nng-0.2.0-cp312-cp312-manylinux_2_28_x86_64.whl (915.3 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

nng-0.2.0-cp312-cp312-macosx_11_0_arm64.whl (768.6 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

nng-0.2.0-cp312-cp312-macosx_10_15_x86_64.whl (813.2 kB view details)

Uploaded CPython 3.12macOS 10.15+ x86-64

nng-0.2.0-cp311-cp311-win_amd64.whl (1.0 MB view details)

Uploaded CPython 3.11Windows x86-64

nng-0.2.0-cp311-cp311-manylinux_2_28_x86_64.whl (930.2 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

nng-0.2.0-cp311-cp311-macosx_11_0_arm64.whl (767.1 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

nng-0.2.0-cp311-cp311-macosx_10_15_x86_64.whl (810.1 kB view details)

Uploaded CPython 3.11macOS 10.15+ x86-64

File details

Details for the file nng-0.2.0.tar.gz.

File metadata

  • Download URL: nng-0.2.0.tar.gz
  • Upload date:
  • Size: 968.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nng-0.2.0.tar.gz
Algorithm Hash digest
SHA256 0cd735ced3374ca15cf32cb5456dd40bd45266eb3de26e5c091488ef10509f73
MD5 eb06d08548c417a4a4c013288ffdc1a6
BLAKE2b-256 0f8d374b9cc9f2013139e46c171fb05fe63a55e04387389117d2ca17697cd921

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp314-cp314t-win_amd64.whl.

File metadata

  • Download URL: nng-0.2.0-cp314-cp314t-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.14t, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nng-0.2.0-cp314-cp314t-win_amd64.whl
Algorithm Hash digest
SHA256 43602a15bdbec85b05bbfb1a222bf2c8a9adc2b874c577883b76d5db1ebfa941
MD5 fd5e1b8699e7bba011ba00b0f4daf34c
BLAKE2b-256 46bac0ee48a8355f0063bca3efa742f80e5df255dd47f9570a9ef97233daeff9

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp314-cp314t-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp314-cp314t-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ec7da3cb927f2c24cfcd4818bf6907ace3cd72a8080f36a60a0c66da9d338858
MD5 ae1a844057c94beaadc9ec357fef7d05
BLAKE2b-256 47feea79efcff83aa9e77b373b867c0c2e02e6e488eee7d57bae1036d0ff4468

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp314-cp314t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6657f43bf43a94fb83226b139313fdcaae990c6fed939729bb1b4f1b3b8a832a
MD5 f94557e7fd0b7e6afffc87f7a91719ab
BLAKE2b-256 cab9d6cd1473ad7f9c6521d0d3078a9144e4d160ed39b60e41e58f95ba5c621d

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp314-cp314t-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp314-cp314t-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 1647baca76e1c1ded46a74dd2c7f02c0750be573a2e0b939fd4fab4a126c51bf
MD5 9bb23f64867ad053c28ca04543e4203b
BLAKE2b-256 409624cf71ac9ee2d202c095917acc0325e63f58fad03883d64209aa189ca608

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: nng-0.2.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nng-0.2.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 41cc879968c4ee940adfa813706b1d3abff4175b90f3e00cce542da29dfb2eca
MD5 f1a5012db828f1544f640aff5d98846e
BLAKE2b-256 443f756c9c927c1f096adb7c9586a58ae8ea49ccc3ffe5ae579731979e09827d

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp314-cp314-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0057108125776b308da4cf4d36cdcfe1d77d4829633612f400d9f3169e93864f
MD5 10fb9cfc87855477ca4b559e00451027
BLAKE2b-256 22cb46845b68318bfb777fb9c17a72982ab4822fff8322a7aeab1ed98909e7ce

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

  • Download URL: nng-0.2.0-cp314-cp314-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 770.3 kB
  • Tags: CPython 3.14, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nng-0.2.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c2b4c74c1985a07ff4a34a4a964184b17afce7e488aa70b27b244e948762e75e
MD5 de2539ecb278bd943aa03efc0b1aa7e4
BLAKE2b-256 f7c908a974e60eecce575250de300d777c242cd58ec9bdc3ebc57b44da2f8485

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp314-cp314-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp314-cp314-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 57909773e8607636ccf39f09c5f7a121e411dd62e88be552828711a5b3c811dd
MD5 d8e2fc4ed4e4904ed25e7e0f0e92e026
BLAKE2b-256 8ce62f84481f8efa5e51893055e5acc16bc4160d5e8b5285888bb05ab2ad810f

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp313-cp313t-win_amd64.whl.

File metadata

  • Download URL: nng-0.2.0-cp313-cp313t-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: CPython 3.13t, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nng-0.2.0-cp313-cp313t-win_amd64.whl
Algorithm Hash digest
SHA256 2146609bbd756366ccec493850d85e8a980cbc04eb03c0bea4e8b9157eafc1a6
MD5 a3c780cd69275d29f1267d4c242473fb
BLAKE2b-256 3208e55c13052c17fae250bf51a3ef727d8ec434d76c6528ebbf1d3266548e97

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp313-cp313t-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp313-cp313t-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ad8c84d10c4ae08ea89082367e3179bf966bb4c1e6eff52a57a3b9944522f093
MD5 f5e0c1cd7d92c1a2337bbd8dec4fb90e
BLAKE2b-256 5a925f9cea5f6b670ced7e95b51c555b8f68874fe884fb841dea9498350d5843

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp313-cp313t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp313-cp313t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 36d3619f731f48b1499ed2eca775e7e8759edbb90dd9a3f5f648833c9610579b
MD5 459eb44484d1b29e2681d32786ad03e2
BLAKE2b-256 466b4474705f5bc2a33192eca07cb96c9b0bb3dfe3eb3c7e37e8239e5b0c96f0

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp313-cp313t-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp313-cp313t-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 d6ffd1f9603da1893fe34d27c7a402e27aa24a5d95e3f731de6532b4abfa1b08
MD5 acc1b3d7f2bebdd72eb96d66a05068ee
BLAKE2b-256 80bf8690cbe0a71d6130e5bf7c68966fe2dc071a6b08b532b69639afaaf7e861

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: nng-0.2.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nng-0.2.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 f7ff275ba9a91607969440a3260275e6427975a80d2a727c9716b2b23468af22
MD5 4b85d611460ff3f104c392751ff5db7f
BLAKE2b-256 d337ff1c01f2cab8f4975f124ab7045b9a53e8e21e6220a076ac1e16474d2e65

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3306f1fb3938c53b6044e83e93ee61c6c8a11f36813346a1a6d7b10b9b715608
MD5 ee6d312917d857b208da5207f31ac75b
BLAKE2b-256 22cc49543082a701d8244c573023de82fb6316f54c48ff9ab36f2e33b1bdd28d

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

  • Download URL: nng-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 767.7 kB
  • Tags: CPython 3.13, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nng-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 92062be73f3b5f235f06b307b51f718ddc3879f55e9d672596f4c93390c74943
MD5 3cb95d56c857d7511769b34ac229564b
BLAKE2b-256 cc3ec8586bdea0c9c5e2604d9cdd0ae6e37886066758902642db5113745668fd

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp313-cp313-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp313-cp313-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 5ab0a960af9a709688d59edf805c75b0f618985fa1b767f32e3d3099f70a76e7
MD5 393dadcb7e454a66880e2a233c022fa0
BLAKE2b-256 92067c0de04682fd65ad5b3e6367b7dc1251d014416276823c97ff052d2e5cf1

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: nng-0.2.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nng-0.2.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 8b69fd0080ca74512bdef67f7412eb5ef913fd31d067105411432d338184010b
MD5 db3636845ad5edcd8cd2c7d8e63432a9
BLAKE2b-256 aef9eb360c48d0b471cd29e4c965604ee868e78155e08ec6e3b58f599f86b5ba

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1a1985d3ba1938e573ead1d99e91f034ba39d0417cc664d4d130cf00c17cc884
MD5 431022fbe701661e028260f8a3e5216c
BLAKE2b-256 9af5515cb46cce41283669f30bb4d77f4b6efe77e876cf60420c489d03ace9e7

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

  • Download URL: nng-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 768.6 kB
  • Tags: CPython 3.12, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nng-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b2cef47ffb3f28e19bc455d191239cf4bcb8bd4fb67e1a93ed89f8e18af701d3
MD5 9cdefedeff404581be84d71dd2238fc0
BLAKE2b-256 7432d4ab58381f10d515caf9d028b3fa3e768bd23774b87fb2a94d6c6f46a139

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp312-cp312-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp312-cp312-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 b1f6a8ba78a7d88cbbdc361c22afe717bc3dbf2b9d96ad446378c1cdb1a14576
MD5 530b3ff1db7ccd750826711e81ed7554
BLAKE2b-256 56b17b7d71f711f4b0b3dcad77d3afd5f5cdb80b3a5333b07cbb6c8dfc47b3d5

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: nng-0.2.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nng-0.2.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 a457cde8cc9e237ef71fc312604062f4f90cff20109e9ef81fb72fe8025f5564
MD5 e20c4c159570b583cae6bae2c9a4b7fe
BLAKE2b-256 0bdccc68125b0db757a933184b2701779d03316db680ee4203977fe0eb2a1507

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2cc2338b5d4dbdb6e060bf5fc38373324d9d6b4278936554cffdf1e01ed4c7e1
MD5 2a6dd7175a98bfce695b8c5343167da0
BLAKE2b-256 3456b7fa6b8e14666823fe3520ed94ed17843b99737363c403198348588a7c64

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

  • Download URL: nng-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 767.1 kB
  • Tags: CPython 3.11, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nng-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f6332257158d83a0b10ffef4be463668c5cf6da5116517f3f111e6ad3cd1a6e9
MD5 85897e0e490f0294aafc1cf345c03bfe
BLAKE2b-256 5533a5444d0cbdf3cb6027e574bb2c20a82cb5e1c367d2e9fd1c71f0a2ade682

See more details on using hashes here.

File details

Details for the file nng-0.2.0-cp311-cp311-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for nng-0.2.0-cp311-cp311-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 6758a428b3bde5d8fb3716b6fe6f51442e0f147e3ed6a4da6398943919ceedb2
MD5 cbb18bd7f1313f4ebcbb7d2bed788612
BLAKE2b-256 eee371d08080a1cda5cb3319d4a0bdfa31a6e3cc236344ba423424f64c752b72

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