{"id":6046,"library":"pycapnp","title":"pycapnp: Cap'n Proto Python Bindings","description":"pycapnp is a Python wrapper for the C++ implementation of the Cap'n Proto data interchange format and RPC system. It provides insanely fast serialization and deserialization, often outperforming Protocol Buffers. The library is actively maintained, with regular releases bringing performance improvements, new features, and compatibility updates.","status":"active","version":"2.2.2","language":"en","source_language":"en","source_url":"https://github.com/capnproto/pycapnp","tags":["serialization","RPC","Cap'n Proto","performance","asyncio","data interchange"],"install":[{"cmd":"pip install pycapnp","lang":"bash","label":"Install pycapnp"},{"cmd":"CC=gcc-8.2 pip install pycapnp","lang":"bash","label":"Specify C++ compiler"}],"dependencies":[{"reason":"pycapnp is a Cython wrapper around the C++ library; it can bundle and build Cap'n Proto or link to a system-wide installation.","package":"C++ Cap'n Proto library","optional":false},{"reason":"Required to compile the C++ Cap'n Proto library, either bundled or system-installed.","package":"C++14 supported compiler (e.g., GCC 6.1+, Clang 6+, Visual Studio 2017+)","optional":false},{"reason":"Required if pycapnp needs to bundle and build the C++ Cap'n Proto library.","package":"cmake","optional":true},{"reason":"Required for compiling the Cython extensions.","package":"Python development headers","optional":false}],"imports":[{"symbol":"capnp","correct":"import capnp"}],"quickstart":{"code":"import capnp\nimport os\n\n# Define a Cap'n Proto schema dynamically for demonstration\n# In a real application, this would be loaded from a .capnp file\n# e.g., addressbook = capnp.load('addressbook.capnp')\n\nSCHEMA_PATH = 'addressbook.capnp'\n\naddressbook_schema_content = '''\n@0xd411d7353f406691;\n\nstruct Person {\n  id @0 :UInt32;\n  name @1 :Text;\n  email @2 :Text;\n  phones @3 :List(PhoneNumber);\n\n  struct PhoneNumber {\n    number @0 :Text;\n    type @1 :Type;\n    enum Type {\n      mobile @0;\n      home @1;\n      work @2;\n    }\n  }\n\n  employment @4 :union {\n    unemployed @5 :Void;\n    employer @6 :Text;\n    school @7 :Text;\n    selfEmployed @8 :Void;\n  }\n}\n\nstruct AddressBook {\n  people @0 :List(Person);\n}\n'''\n\n# Write the schema to a temporary file\nwith open(SCHEMA_PATH, 'w') as f:\n    f.write(addressbook_schema_content)\n\ntry:\n    # Load the Cap'n Proto schema\n    addressbook = capnp.load(SCHEMA_PATH)\n\n    # 1. Build a message\n    with capnp.alloc_builder() as msg_builder:\n        addresses = msg_builder.init_root(addressbook.AddressBook)\n        people = addresses.init('people', 2)\n\n        alice = people[0]\n        alice.id = 123\n        alice.name = 'Alice'\n        alice.email = 'alice@example.com'\n        alice_phones = alice.init('phones', 1)\n        alice_phones[0].number = '555-1212'\n        alice_phones[0].type = 'mobile'\n        alice.employment.employer = 'Google'\n\n        bob = people[1]\n        bob.id = 456\n        bob.name = 'Bob'\n        bob.email = 'bob@example.com'\n        bob_phones = bob.init('phones', 2)\n        bob_phones[0].number = '555-4567'\n        bob_phones[0].type = 'home'\n        bob_phones[1].number = '555-7654'\n        bob_phones[1].type = 'work'\n        bob.employment.unemployed = None\n\n        # Serialize the message to bytes\n        serialized_bytes = msg_builder.to_bytes_packed()\n        print(f\"Serialized message size: {len(serialized_bytes)} bytes\")\n\n        # 2. Read a message\n        # Using capnp.alloc_reader() as a context manager is important for memory safety\n        with capnp.alloc_reader(serialized_bytes) as msg_reader:\n            read_addresses = msg_reader.get_root(addressbook.AddressBook)\n\n            for person in read_addresses.people:\n                print(f\"\\nPerson ID: {person.id}\")\n                print(f\"Name: {person.name}\")\n                print(f\"Email: {person.email}\")\n\n                print(\"Phones:\")\n                for phone in person.phones:\n                    print(f\"  - {phone.number} ({phone.type})\")\n\n                which_employment = person.employment.which()\n                if which_employment == 'employer':\n                    print(f\"Employment: Employer - {person.employment.employer}\")\n                elif which_employment == 'unemployed':\n                    print(\"Employment: Unemployed\")\n                else:\n                    print(f\"Employment: {which_employment}\")\n\nfinally:\n    # Clean up the temporary schema file\n    if os.path.exists(SCHEMA_PATH):\n        os.remove(SCHEMA_PATH)\n","lang":"python","description":"This quickstart demonstrates how to define a Cap'n Proto schema (dynamically for brevity), build a message by initializing a root object and its fields, and then serialize and deserialize it. It highlights the use of `capnp.load()` for schemas, initializing structs and lists, and safely reading messages using `capnp.alloc_builder()` and `capnp.alloc_reader()` context managers."},"warnings":[{"fix":"Migrate all RPC implementations and calls to use Python's `asyncio` event loop. Refer to the updated RPC documentation and examples.","message":"Starting with pycapnp v2.0.0, the use of `asyncio` is mandatory for all RPC calls, and the synchronous RPC mode has been removed. Existing synchronous RPC code will break.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Upgrade your Python environment to Python 3.8 or newer.","message":"pycapnp v2.0.0 and later versions have dropped support for Python 3.7.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Ensure you have a C++14 compatible compiler (GCC 6.1+, Clang 6+, MSVC 2017+) and Python development headers. If facing issues, consider pre-installing the C++ Cap'n Proto library (version 1.0+) or explicitly controlling the bundling process during installation (e.g., `pip install . -C force-bundled-libcapnp=True`).","message":"Installation of pycapnp requires a C++ Cap'n Proto library and a compatible C++14 compiler. While `pip install pycapnp` can often bundle and build the C++ library, issues may arise if the build environment is not correctly set up (e.g., missing development headers, incorrect compiler versions, or 32-bit Linux `fPIC` requirements).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always use `with capnp.alloc_builder() as builder:` or `with capnp.alloc_reader(data) as reader:` patterns when interacting with Cap'n Proto messages.","message":"All `capnp` code that involves I/O operations should be wrapped within a `capnp.alloc_builder()` or `capnp.alloc_reader()` context manager to prevent potential segmentation faults and ensure proper resource management.","severity":"gotcha","affected_versions":"All versions, critical for >=2.0.0"},{"fix":"For current versions (>=2.0.0) running Python 3.8+, 'Text' fields are unicode strings. Ensure proper encoding/decoding if interfacing with older systems or different language bindings.","message":"When working with older versions (pre-Python 3.8, though pycapnp v2+ requires 3.8+), 'Text' type fields were treated as byte strings under Python 2 and unicode strings under Python 3. 'Data' fields consistently return byte strings across all Python versions. For modern `pycapnp` versions, 'Text' fields are always unicode strings.","severity":"gotcha","affected_versions":"<2.0.0 for Python 2/3 behavioral difference; informational for >=2.0.0"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z"}