Cap'n Proto serialization/RPC system - Python bindings
Find a file
2019-02-01 15:11:53 -08:00
benchmark Fix benchamrks 2016-08-31 14:03:19 -07:00
buildutils Update bundled capnp to 0.6.1 2017-12-06 10:49:09 +02:00
capnp Support long messages in read_multiple_bytes. 2019-01-28 17:04:34 +00:00
docs Update segment (de)serialization documentation. 2016-06-24 13:28:35 -07:00
examples Fix problems with TwoPartyServer 2015-04-13 14:14:40 -07:00
scripts Merge branch 'feature/v0.4' into develop 2013-11-13 22:30:31 -08:00
test Add some edge case tests for read_multiple_bytes 2019-01-31 01:02:11 -08:00
.gitignore Ignoring IntelliJ folder. 2015-02-03 08:30:20 -08:00
.travis.yml Removing Python 3.7 from this PR 2018-11-18 16:27:09 -05:00
CHANGELOG.md Fix minor typo in Changelog 2019-01-31 01:30:07 -08:00
DEPLOY.md Add deploy notes about tags 2019-02-01 15:11:53 -08:00
LICENSE Change all references to old project name 2013-09-01 01:15:31 -07:00
MANIFEST.in Include the changelog in the manifest 2016-03-08 11:27:01 -08:00
README.md Replacing end-of-life Python versions with live versions 2018-11-18 10:01:10 -05:00
requirements.txt Pin Cython to v0.21.2 until upstream bug is fixed 2015-02-20 17:21:00 -08:00
setup.py Bump version to v0.6.4 and update changelog 2019-01-31 01:10:15 -08:00
tox.ini Removing Python 3.7 from this PR 2018-11-18 16:27:09 -05:00

pycapnp

More thorough docs are available at http://jparyani.github.io/pycapnp/.

Requirements

pycapnp's distribution has no requirements beyond a C++11 compatible compiler. GCC 4.8+ or Clang 3.3+ should work fine.

pycapnp has additional development dependencies, including cython and py.test. See requirements.txt for them all.

Building and installation

Install with pip install pycapnp. You can set the CC environment variable to control which compiler is used, ie CC=gcc-4.8 pip install pycapnp.

Or you can clone the repo like so:

git clone https://github.com/jparyani/pycapnp.git
pip install --install-option '--force-cython' ./pycapnp

Note: for OSX, if using clang from Xcode 5, you may need to set CFLAGS like so:

CFLAGS='-stdlib=libc++' pip install pycapnp

If you wish to install using the latest upstream C++ Cap'n Proto:

pip install --install-option "--libcapnp-url" --install-option "https://github.com/sandstorm-io/capnproto/archive/master.tar.gz" --install-option "--force-bundled-libcapnp" .

Python Versions

Python 2.7, Python 3.4+, and PyPy 2.1+ are supported.

One oddity to note is that Text type fields will be treated as byte strings under Python 2, and unicode strings under Python 3. Data fields will always be treated as byte strings.

Development

This project uses git-flow. Essentially, just make sure you do your changes in the develop branch. You can run the tests by installing pytest with pip install pytest, and then run py.test from the test directory.

Binary Packages

Building a dumb binary distribution:

python setup.py bdist_dumb

Building a Python wheel distributiion:

python setup.py bdist_wheel

If it fails with an error like clang: error: no such file or directory: 'capnp/lib/capnp.cpp', then you need to cythonize fist. This can be done with:

python setup.py build --force-cython

Documentation/Example

There is some basic documentation here.

The examples directory has one example that shows off pycapnp quite nicely. Here it is, reproduced:

from __future__ import print_function
import os
import capnp

import addressbook_capnp

def writeAddressBook(file):
    addresses = addressbook_capnp.AddressBook.new_message()
    people = addresses.init('people', 2)

    alice = people[0]
    alice.id = 123
    alice.name = 'Alice'
    alice.email = 'alice@example.com'
    alicePhones = alice.init('phones', 1)
    alicePhones[0].number = "555-1212"
    alicePhones[0].type = 'mobile'
    alice.employment.school = "MIT"

    bob = people[1]
    bob.id = 456
    bob.name = 'Bob'
    bob.email = 'bob@example.com'
    bobPhones = bob.init('phones', 2)
    bobPhones[0].number = "555-4567"
    bobPhones[0].type = 'home'
    bobPhones[1].number = "555-7654"
    bobPhones[1].type = 'work'
    bob.employment.unemployed = None

    addresses.write(file)


def printAddressBook(file):
    addresses = addressbook_capnp.AddressBook.read(file)

    for person in addresses.people:
        print(person.name, ':', person.email)
        for phone in person.phones:
            print(phone.type, ':', phone.number)

        which = person.employment.which()
        print(which)

        if which == 'unemployed':
            print('unemployed')
        elif which == 'employer':
            print('employer:', person.employment.employer)
        elif which == 'school':
            print('student at:', person.employment.school)
        elif which == 'selfEmployed':
            print('self employed')
        print()


if __name__ == '__main__':
    f = open('example', 'w')
    writeAddressBook(f)

    f = open('example', 'r')
    printAddressBook(f)

Also, pycapnp has gained RPC features that include pipelining and a promise style API. Refer to the calculator example in the examples directory for a much better demonstration:

import capnp
import socket

import test_capability_capnp


class Server(test_capability_capnp.TestInterface.Server):

    def __init__(self, val=1):
        self.val = val

    def foo(self, i, j, **kwargs):
        return str(i * 5 + self.val)


def server(write_end):
    server = capnp.TwoPartyServer(write_end, bootstrap=Server(100))


def client(read_end):
    client = capnp.TwoPartyClient(read_end)

    cap = client.bootstrap()
    cap = cap.cast_as(test_capability_capnp.TestInterface)

    remote = cap.foo(i=5)
    response = remote.wait()

    assert response.x == '125'


if __name__ == '__main__':
    read_end, write_end = socket.socketpair(socket.AF_UNIX)
    # This is a toy example using socketpair.
    # In real situations, you can use any socket.

    server(write_end)
    client(read_end)

Common Problems

If you get an error on installation like:

...
gcc-4.8: error: capnp/capnp.c: No such file or directory

gcc-4.8: fatal error: no input files

Then you have too old a version of setuptools. Run pip install -U setuptools then try again.

Build Status