Metadata-Version: 2.4
Name: pynng
Version: 1.0.0b3
Summary: Networking made simply using nng
Keywords: networking,nng,nanomsg,zmq,messaging,message,trio,asyncio
Author-Email: Cody Piersall <cody.piersall@gmail.com>
License-Expression: MIT
License-File: LICENSE.txt
License-File: LICENSES_THIRD_PARTY.txt
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Framework :: Trio
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Networking
Project-URL: Homepage, https://github.com/codypiersall/pynng
Project-URL: Source, https://github.com/codypiersall/pynng
Project-URL: Documentation, https://pynng.readthedocs.io/en/latest/
Requires-Python: >=3.10
Requires-Dist: cffi>=1.15.0
Requires-Dist: sniffio>=1.3.0
Provides-Extra: dev
Requires-Dist: mypy>=1.0; extra == "dev"
Requires-Dist: pyright>=1.1; extra == "dev"
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
Requires-Dist: pytest-trio>=0.8.0; extra == "dev"
Requires-Dist: trio>=0.22.0; extra == "dev"
Requires-Dist: types-cffi>=1.16.0; extra == "dev"
Requires-Dist: headerkit~=0.51.0; python_version >= "3.11" and extra == "dev"
Provides-Extra: docs
Requires-Dist: sphinx; extra == "docs"
Requires-Dist: sphinx-rtd-theme; extra == "docs"
Requires-Dist: sphinxcontrib-trio; extra == "docs"
Description-Content-Type: text/markdown

# pynng

[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/codypiersall/pynng/blob/master/LICENSE.txt)
[![PyPI Version](https://img.shields.io/pypi/v/pynng.svg)](https://pypi.org/project/pynng)
[![smoketest](https://github.com/codypiersall/pynng/actions/workflows/smoketest.yml/badge.svg?branch=master)](https://github.com/codypiersall/pynng/actions/workflows/smoketest.yml)
[![Build](https://github.com/codypiersall/pynng/actions/workflows/cibuildwheel.yml/badge.svg?branch=master)](https://github.com/codypiersall/pynng/actions/workflows/cibuildwheel.yml)
[![docs](https://img.shields.io/readthedocs/pynng.svg)](https://pynng.readthedocs.io)
[![Python](https://img.shields.io/pypi/pyversions/pynng.svg)](https://pypi.org/project/pynng)

Ergonomic bindings for [nanomsg next generation] \(nng), in Python.
pynng provides a nice interface on top of the full power of nng.  nng, and
therefore pynng, make it easy to communicate between processes on a single
computer or computers across a network.  This library is compatible with Python
3.10+ (Python 3.10 is deprecated following its October 2026 EOL; Python 3.11+
is recommended).  nng is the [rewriting](https://nanomsg.github.io/nng/RATIONALE.html) of
[Nanomsg](https://nanomsg.org/), which is the spiritual successor to [ZeroMQ](http://zeromq.org/).

Goals
-----

Provide a Pythonic, works-out-of-the box library on Windows and Unix-y
platforms.  Like nng itself, the license is MIT, so it can be used without
restriction.

Installation
------------

On Windows, macOS, and Linux, the usual

    pip install pynng

should suffice. Pre-built binary wheels are available for Windows, Linux (x86_64, aarch64), and macOS (universal2). If building from source or on platforms without binary wheels, [CMake](https://cmake.org/) and a C compiler are required.

Building from the GitHub repo works as well, natch:

    git clone https://github.com/codypiersall/pynng
    cd pynng
    uv pip install -e '.[dev]'

pynng might work on the BSDs as well.  Who knows!

Using pynng
-----------

Using pynng is easy peasy:

```python
from pynng import Pair0

s1 = Pair0()
s1.listen('tcp://127.0.0.1:54321')
s2 = Pair0()
s2.dial('tcp://127.0.0.1:54321')
s1.send(b'Well hello there')
print(s2.recv())
s1.close()
s2.close()
```

Since pynng sockets support setting most parameters in the socket's `__init__`
method and is a context manager, the above code can be written much shorter:

```python
from pynng import Pair0

with Pair0(listen='tcp://127.0.0.1:54321') as s1, \
        Pair0(dial='tcp://127.0.0.1:54321') as s2:
    s1.send(b'Well hello there')
    print(s2.recv())
```

### Using pynng with an async framework

Asynchronous sending also works with
[trio](https://trio.readthedocs.io/en/latest/) and
[asyncio](https://docs.python.org/3/library/asyncio.html).  Here is an example
using trio:

```python
import pynng
import trio

async def send_and_recv(sender, receiver, message):
    await sender.asend(message)
    return await receiver.arecv()

with pynng.Pair0(listen='tcp://127.0.0.1:54321') as s1, \
        pynng.Pair0(dial='tcp://127.0.0.1:54321') as s2:
    received = trio.run(send_and_recv, s1, s2, b'hello there old pal!')
    assert received == b'hello there old pal!'
```

And here is the same example using asyncio:

```python
import asyncio
import pynng

async def send_and_recv(sender, receiver, message):
    await sender.asend(message)
    return await receiver.arecv()

with pynng.Pair0(listen='tcp://127.0.0.1:54321') as s1, \
        pynng.Pair0(dial='tcp://127.0.0.1:54321') as s2:
    received = asyncio.run(send_and_recv(s1, s2, b'hello there old pal!'))
    assert received == b'hello there old pal!'
```

Many other protocols are available as well:

* `Pair0`: one-to-one, bidirectional communication.
* `Pair1`: one-to-one, bidirectional communication, but also supporting
  polyamorous sockets
* `Pub0`, `Sub0`: publish/subscribe sockets.
* `Surveyor0`, `Respondent0`: Broadcast a survey to respondents, e.g. to find
  out what services are available.
* `Req0`, `Rep0`: request/response pattern.
* `Push0`, `Pull0`: Aggregate messages from multiple sources and load balance
  among many destinations.
* `Bus0`: mesh networking, where each node can send to and receive from all
  directly connected peers.

### NNG v1 and NNG v2 Support

`pynng` 1.x bundles **both** NNG v1 (`v1.12.5`) and NNG v2 (`v2.1.0`) in the
same wheel:

* `import pynng` — uses **NNG v1** (`v1.12.5` by default), preserving 100%
  compatibility with existing `pynng` applications.
* `import pynng.v2` — uses **NNG v2** (`v2.1.0` by default) with the same
  Pythonic socket/context API (`pynng` 2.0 will make NNG v2 the top-level
  default).

When building from source, you can override `NNG_REV` (v1) or `NNG_V2_REV` (v2),
or pass `-C cmake.args="-DPYNNG_USE_LATEST_PATCH=ON"` to automatically resolve
both tracks to the latest upstream patch tag in their respective `major.minor`
series.

Examples
--------

Several examples are available in the
[examples](https://github.com/codypiersall/pynng/tree/master/examples)
directory, covering pair, pub/sub, req/rep, push/pull, bus, survey, and
polyamorous pair1 patterns.

Documentation
-------------

Full documentation is available at [pynng.readthedocs.io](https://pynng.readthedocs.io/).

Troubleshooting
---------------

### macOS: `ld: archive member '/' not a mach-o file`

This error occurs when Homebrew LLVM's `llvm-ranlib` is used instead of Apple's
native `ranlib`. The `llvm-ranlib` tool has a
[known bug](https://github.com/llvm/llvm-project/issues/98997) where it produces
GNU archive format instead of BSD/Darwin format for static libraries with no
exported symbols. Apple's linker rejects these archives.

pynng's build system detects and works around this automatically. If you still
encounter this error, you can explicitly set the ranlib tool:

    CMAKE_RANLIB=/usr/bin/ranlib pip install pynng

Or pass it through scikit-build-core:

    pip install pynng -C cmake.args="-DCMAKE_RANLIB=/usr/bin/ranlib"

### Linux: `libclang` not found

pynng requires `libclang` development headers to parse NNG's C headers at build
time. Install the appropriate package for your distribution:

    # Debian/Ubuntu
    sudo apt install libclang-dev

    # RHEL/CentOS/Fedora
    sudo yum install clang-devel

    # Alpine
    apk add clang-dev

Contributing
------------

Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for
development setup, testing, and the contribution workflow.

Changelog
---------

See [CHANGELOG.md](CHANGELOG.md) for a list of notable changes.

Python Version Support & Deprecation Policy
------------------------------------------

`pynng` supports Python 3.10, 3.11, 3.12, 3.13, and 3.14. Following the official Python release lifecycle:

* **Python 3.10**: Reached end-of-life (EOL) in October 2026. Support for Python 3.10 is now deprecated and will be removed in a future release. Users are strongly encouraged to upgrade to Python 3.11 or newer.
* **Python 3.11–3.14**: Fully supported and tested across Linux, macOS, and Windows.

Git Branch Policy
-----------------

The **only** stable branch is `master`.  There will *never* be a `git push -f`
on master.  On the other hand, all other branches are not considered stable;
they may be deleted, rebased, force-pushed, and any other manner of funky
business.

[nanomsg next generation]: https://nanomsg.github.io/nng/index.html
