{
"info": {
"author": "Fahrzin Hemmati",
"author_email": "fahhem@gmail.com",
"bugtrack_url": null,
"classifiers": [
"Development Status :: 2 - Pre-Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: C++",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Topic :: Software Development :: Code Generators",
"Topic :: Software Development :: Libraries",
"Topic :: System :: Networking",
"Topic :: Utilities"
],
"description": "CARA\n====\n\n|Build Status| |Coverage Status| |Codacy Badge| |Documentation Status|\n|PyPI Version| |PyPI License|\n\ncara is a Cap'n proto Alternative RPC API. `Read the\ndocs! `__\n\nReason for creation\n-------------------\n\npycapnp is a straight C++ conversion and, while that's great and all,\nit's not pythonic. It also uses capnp's RPC layer and friends, which is\nfrom scratch and isn't very mature, while there are plenty of RPC\nlayers, event loops, etc already in python and well-maintained.\n\nRequirements\n------------\n\nTo install via setup.py (or pip), a capnproto installation must be\nlocatable by pkg-config. Installed via a normal 'sudo make install'\nshould work, other situations have not been tested.\n\nUsage\n-----\n\nFirst, generate the code from your .capnp files:\n\n::\n\n capnp compile -ocara my_structs.capnp\n\nThen import them:\n\n::\n\n import my_structs_capnp\n\nExample\n~~~~~~~\n\nmy\\_structs.capnp\n\n::\n\n struct MyStruct {\n field @0 :Text;\n nested @1 :NestedStruct;\n struct NestedStruct {\n integer @0 :Int32;\n }\n }\n\nPython usage\n\n::\n\n import my_structs_capnp\n\n my_structs_capnp.MyStruct({'field': 'some text for here'})\n # -- or --\n m = my_structs_capnp.MyStruct.Create(field='some different text')\n\n # All the classes masquerade as python builtins, like dict:\n msgpack.packb(m) == b'\\x81\\x00\\xb3some different text'\n # But it's slightly different... Look at Field Shrinking below to\n # understand\n\nPseud Integration\n-----------------\n\nThere's also `pseud `__ integration.\nPseud supports tornado and gevent, but only tornado on Python 3, so\nthese examples used tornado. If you use Python 2, you're welcome to use\ngevent.\n\nThe first requirement imposed is that you call cara\\_pseud.setup\\_server\non your server and cara\\_pseud.setup\\_client on your client. Once both\nare called, you can start the server and client. For the server,\nregister an interface with the class or function you want to export. For\nthe client, wrap the client object with the interface you want to use it\nas. This API allows a server to export multiple interfaces and a client\nto use any number of them.\n\nExample\n~~~~~~~\n\nmy\\_ifaces.capnp\n\n::\n\n interface SimpleEcho {\n echo (text :Text) -> (text :Text);\n }\n\n interface BackAndForth {\n interface Callback {\n callback (callback :Callback) -> (result :Text);\n }\n callMeMaybe (callback :Callback) -> ();\n otherFunc () -> ();\n }\n\nPython usage:\n\n::\n\n from cara import cara_pseud\n from my_ifaces_capnp import SimpleEcho, BackAndForth\n\n @tornado.gen.coroutine\n def create_server():\n server = pseud.Server(...)\n server.bind(...)\n cara_pseud.setup_server(server)\n yield server.start()\n\n # A function can be used to implement an interface with a single\n # method. The name doesn't have to match either.\n @cara_pseud.register_interface(server, SimpleEcho)\n def func(text):\n return text\n\n # If an interface has multiple methods, a class is necessary. It also has\n # to implement all the methods, but its name can be anything, too.\n # It can subclass the interface or object, but if you choose the\n # interface, the register_interface call can infer it from the class\n # definition.\n @cara_pseud.register_interface(server)\n class Server(BackAndForth):\n def callMeMaybe(self, callback):\n # You can even use a lambda as an interface.\n callback(lambda: 'internal callback')\n\n def otherFunc(self):\n pass\n\n @tornado.gen.coroutine\n def create_client():\n server = pseud.Client(...)\n server.connect(...)\n cara_pseud.setup_client(server)\n yield client.start()\n\n echo_iface = SimpleEcho(client)\n result = yield echo_iface.echo('test')\n assert result == 'test'\n\n # Now let's mess with this exported interface.\n back_and_forth = BackAndForth(client)\n # This is a special combination of fortunate accidents. A method with one\n # argument that is an interface with one method can be called like a\n # decorator. Though, you need to yield it still.\n @back_and_forth.callMeMaybe\n def callback(callback=None):\n result = yield callback()\n assert result == 'internal callback'\n yield callback\n\n io_loop.add_callback(create_server)\n io_loop.add_callback(create_client)\n io_loop.start()\n\nField Shrinking\n---------------\n\n::\n\n # Notice there's no mention of 'field' in the result:\n m = my_structs_capnp.MyStruct({'field': 'some text for here'})\n msgpack.packb(m) == b'\\x81\\x00\\xb3some different text'\n # Yet it's there when we pack the object directly.\n m = {'field': 'some different text'}\n msgpack.packb(m) == b'\\x81\\xa5field\\xb3some different text'\n\nThe difference is because a cara Struct uses the ordinals of the fields\ninstead of their names. This will only be an issue when sending the\npacked bytes over to another system that isn't using cara. If you send\nit back into cara, it'll unpack the fields correctly and you can use it\nlike the original pieces.\n\n::\n\n original = my_structs_capnp.MyStruct.Create(nested={'integer': 2})\n packed = msgpack.packb(original)\n unpacked = msgpack.unpackb(packed)\n # --> {1: {0: 2}}\n result = my_structs_capnp.MyStruct(unpacked)\n # --> MyStruct({nested: NestedStruct({integer: 2})})\n\nThis allows us to serialize a struct into a much smaller bytestring,\nespecially since 0-127 becomes a single byte in msgpack. As long as your\ncapnp schema changes are sufficiently backwards-compatible, you can\ndeserialize and lookup the field numbers to get the appropriate type.\n\n.. |Build Status| image:: https://img.shields.io/travis/chainreactionmfg/cara/master.svg\n :target: https://travis-ci.org/chainreactionmfg/cara\n.. |Coverage Status| image:: https://img.shields.io/coveralls/chainreactionmfg/cara/master.svg\n :target: https://coveralls.io/r/chainreactionmfg/cara\n.. |Codacy Badge| image:: https://img.shields.io/codacy/3cc5a370c923435e92b9ce1a7dbbbafe.svg\n :target: https://www.codacy.com/public/fahhem/cara\n.. |Documentation Status| image:: https://readthedocs.org/projects/cara/badge/?version=latest&style=flat\n :target: https://readthedocs.org/projects/cara/?badge=latest\n.. |PyPI Version| image:: https://img.shields.io/pypi/v/cara.svg\n :target: https://pypi.python.org/pypi/cara\n.. |PyPI License| image:: https://img.shields.io/pypi/l/cara.svg\n :target: https://pypi.python.org/pypi/cara",
"description_content_type": null,
"docs_url": null,
"download_url": null,
"downloads": {
"last_day": -1,
"last_month": -1,
"last_week": -1
},
"home_page": "https://github.com/chainreactionmfg/cara",
"keywords": "cara pseud capnp network rpc schema",
"license": "Apache 2.0",
"maintainer": null,
"maintainer_email": null,
"name": "cara",
"package_url": "https://pypi.org/project/cara/",
"platform": "UNKNOWN",
"project_url": "https://pypi.org/project/cara/",
"project_urls": {
"Homepage": "https://github.com/chainreactionmfg/cara"
},
"release_url": "https://pypi.org/project/cara/0.10.3/",
"requires_dist": null,
"requires_python": null,
"summary": "cara is a Cap'n proto Alternative RPC API.",
"version": "0.10.3"
},
"last_serial": 1505874,
"releases": {
"0.10.0": [
{
"comment_text": "",
"digests": {
"md5": "1f1fcef48fe85f20a7c7602cd2367d60",
"sha256": "e91fe090411ba690608552915b23335364a38857531fc8ed7f68f86a2fef5da5"
},
"downloads": -1,
"filename": "cara-0.10.0.tar.gz",
"has_sig": false,
"md5_digest": "1f1fcef48fe85f20a7c7602cd2367d60",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 53349,
"upload_time": "2015-03-03T09:09:33",
"url": "https://files.pythonhosted.org/packages/81/4e/74594dfc32d6902be993b99a03ace8f4a7b199f1d47970f112da8f94acc9/cara-0.10.0.tar.gz"
}
],
"0.10.2": [
{
"comment_text": "",
"digests": {
"md5": "7ea609a398f6a1b9d860c1f9c1da8607",
"sha256": "af6b6e47b1164e31da5c510956f72fabd7735672aad938b91cb05038c2a13ada"
},
"downloads": -1,
"filename": "cara-0.10.2.tar.gz",
"has_sig": false,
"md5_digest": "7ea609a398f6a1b9d860c1f9c1da8607",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 53357,
"upload_time": "2015-03-03T10:11:45",
"url": "https://files.pythonhosted.org/packages/d0/38/b7d3bacd2211a142cb711a3902e856b59fdfd4bedfd5a4699fc6915841a2/cara-0.10.2.tar.gz"
}
],
"0.10.3": [
{
"comment_text": "",
"digests": {
"md5": "a0b13f1b0c8c6248d6ba0d9e6b5c08d7",
"sha256": "a2a8fa6c27af2725381b8417d466042d6030a0b884bb7d6cc147b58fad6e7686"
},
"downloads": -1,
"filename": "cara-0.10.3.tar.gz",
"has_sig": false,
"md5_digest": "a0b13f1b0c8c6248d6ba0d9e6b5c08d7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 53430,
"upload_time": "2015-04-15T07:09:02",
"url": "https://files.pythonhosted.org/packages/fc/79/8118e63bc79969ceb1a27360dd21eed7ee528706e11fec6de2c7b1422cb5/cara-0.10.3.tar.gz"
}
],
"0.8.1": [
{
"comment_text": "",
"digests": {
"md5": "ada33619f3dabbe16a0c1d33b825fa22",
"sha256": "7176b1a6d760ae6c58e4482b329c0224d7f963a9e768c303eb2ab722ef690bff"
},
"downloads": -1,
"filename": "cara-0.8.1.tar.gz",
"has_sig": false,
"md5_digest": "ada33619f3dabbe16a0c1d33b825fa22",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 51095,
"upload_time": "2015-02-18T16:10:48",
"url": "https://files.pythonhosted.org/packages/9b/46/19fc00a477920b1780321b1ce10edd196ef1d01f93f106ad7e59d0c4c22b/cara-0.8.1.tar.gz"
}
],
"0.9.0": [
{
"comment_text": "",
"digests": {
"md5": "c2e3cdade803cd00aea4f25093ea37d7",
"sha256": "143620707770bc93e99fe654911051a1aefe87df17b1b59f468c06bc42a51dbd"
},
"downloads": -1,
"filename": "cara-0.9.0.tar.gz",
"has_sig": false,
"md5_digest": "c2e3cdade803cd00aea4f25093ea37d7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 52450,
"upload_time": "2015-02-24T21:31:52",
"url": "https://files.pythonhosted.org/packages/d8/5d/ebc7fcb180f5731fc10bd336c04b43f65eb45c6d3afeb69314a4cee85bc9/cara-0.9.0.tar.gz"
}
],
"0.9.1": [
{
"comment_text": "",
"digests": {
"md5": "f2d20793dd6b742bcb6257ff0596d994",
"sha256": "0a28c55e0813f47a3d68a19b3fbee0d930d460ff1003fa4df2363f17ec9b29b8"
},
"downloads": -1,
"filename": "cara-0.9.1.tar.gz",
"has_sig": false,
"md5_digest": "f2d20793dd6b742bcb6257ff0596d994",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 52559,
"upload_time": "2015-02-24T22:45:31",
"url": "https://files.pythonhosted.org/packages/e6/ae/d060fc33051891bc39d17a8872c1828a7fb87c6c1b0f29b520d0522a9f2a/cara-0.9.1.tar.gz"
}
]
},
"urls": [
{
"comment_text": "",
"digests": {
"md5": "a0b13f1b0c8c6248d6ba0d9e6b5c08d7",
"sha256": "a2a8fa6c27af2725381b8417d466042d6030a0b884bb7d6cc147b58fad6e7686"
},
"downloads": -1,
"filename": "cara-0.10.3.tar.gz",
"has_sig": false,
"md5_digest": "a0b13f1b0c8c6248d6ba0d9e6b5c08d7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 53430,
"upload_time": "2015-04-15T07:09:02",
"url": "https://files.pythonhosted.org/packages/fc/79/8118e63bc79969ceb1a27360dd21eed7ee528706e11fec6de2c7b1422cb5/cara-0.10.3.tar.gz"
}
]
}