{"id":10118,"library":"pynng","title":"Pynng","description":"Pynng is a Python binding for the nng (nanomsg-next-generation) C library, providing lightweight, high-performance messaging patterns for network communication. It supports both synchronous and asynchronous (asyncio) operations, making it suitable for a wide range of network applications. The current version is 0.9.0, and it generally follows a moderate release cadence, with updates often introducing significant features or improvements.","status":"active","version":"0.9.0","language":"en","source_language":"en","source_url":"https://github.com/codypiersall/pynng","tags":["networking","asyncio","sockets","messaging","nng","nanomsg"],"install":[{"cmd":"pip install pynng","lang":"bash","label":"Install pynng"}],"dependencies":[],"imports":[{"note":"The library is imported under the 'pynng' namespace, not directly 'nng'.","wrong":"import nng","symbol":"pynng","correct":"import pynng"},{"note":"Common socket types are directly available from the top-level pynng module.","symbol":"Rep0, Req0","correct":"from pynng import Rep0, Req0"}],"quickstart":{"code":"import pynng\nimport asyncio\n\nasync def main():\n    addr = \"tcp://127.0.0.1:5555\"\n\n    async def server():\n        \"\"\"Simple Request-Reply server.\"\"\"\n        with pynng.Rep0() as rep_sock:\n            rep_sock.listen(addr)\n            print(\"Server: Listening...\")\n            # Receive and immediately reply, then close after 2 messages\n            for _ in range(2):\n                msg = await rep_sock.arecv()\n                print(f\"Server: Received '{msg.decode()}'\")\n                await rep_sock.asend(b\"PONG\")\n            print(\"Server: Done.\")\n\n    async def client():\n        \"\"\"Simple Request-Reply client.\"\"\"\n        await asyncio.sleep(0.1) # Give server a moment to start\n        with pynng.Req0() as req_sock:\n            req_sock.dial(addr)\n            print(\"Client: Dialed.\")\n            for i in range(2):\n                await req_sock.asend(f\"PING {i}\".encode())\n                reply = await req_sock.arecv()\n                print(f\"Client: Received '{reply.decode()}'\")\n            print(\"Client: Done.\")\n\n    await asyncio.gather(server(), client())\n\nif __name__ == \"__main__\":\n    # This example demonstrates async usage, which is common in modern pynng applications.\n    asyncio.run(main())","lang":"python","description":"This quickstart demonstrates a basic asynchronous request-reply (REQ/REP) pattern using pynng. It sets up a minimal server that listens for messages and replies, and a client that sends messages and receives replies. Both are run concurrently using asyncio."},"warnings":[{"fix":"Ensure you have a C compiler and development headers installed. On Debian/Ubuntu: `sudo apt-get install build-essential`. On Fedora: `sudo dnf groupinstall \"Development Tools\"`. On macOS: Install Xcode Command Line Tools (`xcode-select --install`).","message":"Pynng requires the nng C library. If it's not pre-installed on your system, `pip install pynng` will attempt to download and compile it from source. This requires a C compiler (e.g., GCC or Clang) and development headers to be available on your system.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For new applications, prefer `asyncio` methods (`asend`, `arecv`, `aconnect`, `aclose`). For existing sync code, ensure you're explicitly using `send`, `recv`, etc., and be mindful of blocking operations in an `asyncio` context.","message":"Asyncio support was a major addition in pynng >= 0.8.0. Code written for older synchronous versions might need significant refactoring to take advantage of `asyncio` and `await`/`async` syntax (e.g., `sock.arecv()` instead of `sock.recv()`).","severity":"breaking","affected_versions":"Prior to 0.8.0 when migrating to 0.8.0+"},{"fix":"Always use `with sock.open_context() as ctx:` for managing `nng` contexts, ensuring they are properly closed. Refer to the official `pynng` documentation for advanced context usage patterns.","message":"Improper context management (introduced in 0.9.0) can lead to resource leaks or unexpected behavior, especially in complex applications or when dealing with multiple concurrency units.","severity":"gotcha","affected_versions":"0.9.0+"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Install a C compiler and development headers. For Linux (Debian/Ubuntu): `sudo apt-get install build-essential`. For macOS: `xcode-select --install`. For Windows, consider using WSL or Visual Studio Build Tools.","cause":"The `pynng` installation failed to compile the underlying `nng` C library because a C compiler or necessary development headers were not found on the system.","error":"error: command 'gcc' failed with exit status 1"},{"fix":"If using `asyncio`, use `await sock.arecv()` and `await sock.asend()`. If explicitly using synchronous operations (less common in modern `pynng` code), ensure you are calling the non-`a` prefixed methods (`sock.recv()`, `sock.send()`).","cause":"You are likely trying to call the synchronous `recv()` method on an asynchronous socket (or vice-versa), or you've made a typo. The method names for async operations are prefixed with 'a' (e.g., `arecv`).","error":"AttributeError: 'Socket' object has no attribute 'recv'"},{"fix":"Ensure your server process is running and actively listening on the specified address and port before the client attempts to dial. Check firewall rules if the server is on a different machine or network.","cause":"The client attempted to connect to a server address, but no server was listening on that address and port, or a firewall is blocking the connection.","error":"pynng.exceptions.NNGException: nng_dial failed: connection refused"}]}