'pycapnp: Reading and Writing a List without custom capnp file

I have read through the pycapnp quickstart and docs, and I see no mention for how to read and write basic list objects (like a list of floats).

In particular, I am aware that if I write a custom type in a capnp file, then I can read an object of that type using something like

addressbook_capnp.Person.from_bytes(encoded_message)

What I would like to know is the syntax for reading a list of floats like this. I imagine that it would look something like

capnp.List.Float64.from_bytes(encoded_message)

But I simply can't find the correct syntax. Furthermore, since Capn Proto does not export aliases from the .capnp file, I cannot just define a list of floats there (or so it seems).

Can somebody please tell me the correct syntax for reading, writing, and creating lists of basic objects in pycapnp?


EDIT:

For example, in C++ I can create a list object (without a custom type) like this:

::capnp::MallocMessageBuilder message; 
auto capnp_point_cloud = message.initRoot<::capnp::List<Val>>(num_axes);
for (size_t i = 0; i < num_axes; ++i) { 
    capnp_point_cloud.set(i, array[i]);
}


Solution 1:[1]

I've read through the documentation and it appears to be quite easy to work with capnp lists in python.

First of all, you need to have a .capnp file containing a definition for a class with a list variable:

#floatbook.capnp
@0xbde7cca9517a2373;

struct FloatBook {
  floats @0 :List(Float64);
}

To write and then read a binary file with data from my .capnp schema, I've written the following Python script:

import capnp

# Load capnp schema manually from file
capnp.remove_import_hook()
floatbook_capnp = capnp.load('floatbook.capnp')

# Create a new FloatBook object from imported capnp schema
floatbook = floatbook_capnp.FloatBook.new_message()

# Initialize a new list inside the FloatBook object and set its values
floats = floatbook.init('floats', 2)
floats[0] = 1.5
floats[1] = 2.5

# Write the FloatBook object to a binary file
f = open('example.bin', 'w+b')
floatbook.write(f)

# Read the FloatBook object back from the created binary file
f = open('example.bin', 'rb')
floatbook = floatbook_capnp.FloatBook.read(f)

# Print every float inside the read FloatBook object
print(type(floatbook.floats))
for float in floatbook.floats:
    print(float)

Here's the contents of my PowerShell console after I run this script:

PS C:\Users\anon> & test.py
<class 'capnp.lib.capnp._DynamicListReader'>
1.5
2.5

Edit 1:

Instead of writing and reading a file, it's possible to write and read a byte string instead:

serialized = floatbook.to_bytes()
floatbook = floatbook_capnp.FloatBook.from_bytes(serialized)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1