A cython wrapping of the C++ Cap'n Proto library
Project description
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
Python Versions
Python 2.6/2.7 are supported as well as Python 3.2+. PyPy 2.1+ is also 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
In order to build binary packages from this source code, you must specify the --disable-cython option:
Building a dumb binary distribution:
python setup.py bdist_dumb --disable-cython
Building a Python wheel distributiion:
python setup.py bdist_wheel --disable-cython
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.
Changelog
v0.5.6 (2015-04-13)
Fix a serious bug in TwoPartyServer that was preventing it from working when passed a string address.
Fix bugs that were exposed by defining KJDEBUG (thanks @davidcarne for finding this)
v0.5.5 (2015-03-06)
Update bundled C++ libcapnp to v0.5.1.2 security release
v0.5.4 (2015-03-02)
Update bundled C++ libcapnp to v0.5.1.1 security release
Add bootstrap RPC methods
Fix possible segfault when importing multiple schemas
v0.5.3 (2015-02-23)
Fix possible crash due to bad destructor ordering in MessageReader (by @JohnEmhoff)
Default to no longer using cython
v0.5.2 (2015-02-20)
Add read_multiple_bytes/read_multiple_bytes_packed methods
Added Python 3.4 to the travis build matrix
Bump version for bundled C++ libcapnp to v0.5.1
v0.5.1 (2014-12-27)
Remove installation dependency on cython. We now have no dependencies since libcapnp will automatically build as well.
v0.5.0 (2014-12-15)
Timer class capnp.getTimer()
pycapnp is now thread-safe and allows an event loop to be run in each thread
You must destroy and re-create the event loop to get this functionality (see test_threads.py)
Inheritance now works correctly for interfaces (previously inherited methods were inaccessible from pycapnp)
Add ability to import modules with dashes or spaces. Use underscores in place of them
from_bytes with builder=True is no longer zero copy. It never worked correctly, and is much safer now
Add num_first_segment_words argument wherever message creation can occur
Allow restoring a null objectId by passing None to restore
Support ordered dictionary in to_dict
Add ListSchema class and schemas for native types under capnp.types which completes all the Schemas needed to be wrapped. See test_schema.py for examples using it
Add automatic build of C++ libcapnp if it’s not detected on the system. Also add flags –force-bundled-libcapnp and –force-system-libcapnp respectively
v0.4.6 (2014-9-10)
Fix build for new 0.21 release of Cython. 0.21 is now the minimum supported version of Cython.
v0.4.5 (2014-6-26)
Fix to_dict not converting enums to strings
v0.4.4 (2014-04-25)
Fix compilation problem with gcc 4.8
v0.4.3 (2014-02-18)
Fix problem with uninitialized unions in _from_dict
Add accesible version numbers for C++ libcapnp
v0.4.2 (2014-02-13)
Remove onDrained since it was removed upstream
Replace usage of strings as enum type with custom _DynamicEnum class.
Also change Struct.which() method to be a property Struct.which and return an enum type (_DynamicEnumField, which behaves much like _DynamicEnum).
TwoPartyServer.run_forever() now will handle more than 1 simulataneous connection.
Change exception wrapper to detect and raise AttributeError for field lookup exceptions (Fixes problem in Python3.x __dir__)
Allow setting of fields with python dicts.
0.4.1 (2013-12-18)
Remove python 3.2 from travis tests. Python 3.2 still should work fine, but it’s more trouble than it’s worth to write unicode tests that work in both it and Python2.
Fix problems with null characters in Text/Data fields. Fixes #19
0.4.0 (2013-12-12)
Initial working version of RPC
Add get_root_as_any to _MessageReader
Add capnp.pxd for public declarations of cython classes
Fix problems compiling with gcc4.7
v0.3.18 (2013-11-05)
Change naming of ReaderOption parameters to be pep8 compliant
v0.3.17 (2013-11-05)
Add ReaderOptions to read/read_packed/from_bytes
v0.3.16 (2013-10-28)
Add defaults flag to capnp-json. Also remove ‘which’ field
Add capnp-json serializer script. Also fix bugs in from_dict
Fix build for clang/python3. Also remove -fpermissive
Add as_builder method to Struct Reader
Add warning when writing the same message more than once
First working version of capability interfaces
Wrap InterfaceSchema
Fix setting string fields to support all types of strings
Fix changed API for DynamicObject/ObjectPointer
v0.3.15 (2013-09-19)
Add not having installed the C++ libcapnp library to ‘Common Problems’
Add shortstr function for use in capnp_test_pycapnp.py
Add test script for testing with https://github.com/kaos/capnp_test
Add handling of DynamicObject
Fix lists of lists or dicts for from_dict
v0.3.14 (2013-09-04)
Fix problem with to_dict
v0.3.13 (2013-09-04)
Add DynamicStructBuilder.tobytes() and .from_bytes()
Change == on StructSchema to return cbool
Add Builder and Reader ABCs for each struct type
v0.3.12 (2013-09-03)
Fix handling of empty path ‘’ in load_module
Add from_dict
Fix bug in exception handling for which(). Also standardize exceptions.
Change import hook to require modules to end in ‘_capnp’
Add import monkey patch function.
Change naming for functions to conform to PEP 8. Also deprecate old read/write API
Update preferred method for reading/writing messages from files
v0.3.11 (2013-09-01)
Forgot to change project name in setup.py
v0.3.10 (2013-09-01)
Change all references to old project name (change from capnpc-python-cpp to pycapnp)
Change DynamicValue.Reader lists to be returned as _DynamicListReader
Unify setters for DynamicList and DynamicStruct
Add shortcuts for reading from / writing to files. In Python, it doesn’t make much sense to force people to muck around with MessageReaders and MessageBuilders since everything is landing on the heap anyway. Instead, let’s make it easy: MyType.read[Packed]From(file) reads a file and returns a MyType reader. MyType.newMessage() returns a MyType builder representing the root of a new message. You can call this builder’s write[Packed]To(file) method to write it to a file.
Store Builders by value rather than allocate them separately on the heap (matches treatment of Readers). v0.3 fixes the bug that made this not work.
Wrap MessageBuilder::setRoot().
Add tests based on TestAllTypes from the C++ test.capnp. Fix problems uncovered in capnp.pyx.
Implement str and repr for struct and list builders. str uses prettyPrint while repr shows the type name and the low-whitespace stringification. Also implement repr for StructSchema, just because why not?
v0.3.9 (2013-08-30)
Change load to use a global SchemaParser. Make structs settable as field
Add docstrings for new functions and _DynamicResizableListBuilder
v0.3.8 (2013-08-29)
Add initial tests
Add _capnp for original Cython module. Meant for testing.
Lowercase schema so it conforms to member naming conventions
Expose _StructSchema’s raw node
Add some useful _StructSchema, reader, and builder methods
Add full orphan functionality. Also, allow special orphan lists
Finish up adding docstrings to all public classes/methods
v0.3.7 (2013-08-26)
Add a ton of docstrings and add to official docs
Add DynamicOrphan
v0.3.6 (2013-08-26)
Add intersphinx for linking to python docs
Add C++ library version check
v0.3.5 (2013-08-25)
Add handling of constants in schemas
Fix new error with DynamicValue.Builder no longer being copyable
v0.3.4 (2013-08-22)
Fix Void namespace change
Updated capnp schema to conform with new union rules
v0.3.3 (2013-08-22)
Fix for the removal of DynamicUnion from the C++ API
v0.3.2 (2013-08-21)
Add MANIFEST.in to include README
v0.3.1 (2013-08-21)
Update docs with lines about upgrading setuptools
0.3.0 (2013-08-21)
Initial commit of docs
Add querying unnamed enums to structs
0.2.1 (2013-08-13)
Fix enum interface change for benchmark
Random formatting cleanup
Allow import paths in the schema loader
Add travis CI
0.2.0 (2013-08-12)
Initial working version
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file pycapnp-0.5.6.tar.gz
.
File metadata
- Download URL: pycapnp-0.5.6.tar.gz
- Upload date:
- Size: 428.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5ad2a4bdfd33723b9de44b58cf85e50c944824076074c0361934351c5d814e15 |
|
MD5 | 6f636c91e0291bd0b410c3f7b8076b76 |
|
BLAKE2b-256 | fa58f1717d6c669054a4631cdd6ccd48dc2eb9686199d2f9c6a62a5e73925ac1 |