···11+"""
22+A Python client for bellairs.quest to access directories, etc.
33+"""
44+55+import asyncio
66+import socket
77+from typing import Any
88+99+import capnp # type: ignore
1010+1111+capnp.remove_import_hook()
1212+1313+cp_storage = capnp.load("schema/storage.capnp")
1414+1515+1616+class Directory:
1717+ """
1818+ Wrapper class for the directory. Many of these methods are
1919+ async, unfortunately.
2020+ """
2121+2222+ def __init__(self, addr: str, port: str, family: int):
2323+ """Create a directory using the provided address and port"""
2424+ # family should be AF_UNIX, AF_INET, or AF_INET6. Not sure that capnp
2525+ # can handle any of the others.
2626+ # TODO: Hmm should `port` be int?
2727+ # TODO: If we want SSL, need to create a ssl.context, and pass it in
2828+ # using `ssl=ctx`
2929+ self._capnp_client = capnp.TwoPartyClient(addr, port).bootstrap()
3030+ self._capnp_dir = self._capnp_client.cast_as(cp_storage.Directory)
3131+3232+ async def list(self):
3333+ result = await self._capnp_dir.list()
3434+ # Return names for now. Still need to write file
3535+ return [(e.name, File(e.file)) for e in result.entries]
3636+3737+3838+class File:
3939+ """
4040+ Wrapper class for files
4141+ """
4242+4343+ def __init__(self, cobj: Any):
4444+ # Note: cobj is of type cp_storage.File, but MyPy
4545+ # cannot deal with types defined in this way.
4646+ self._capnp_file = cobj
4747+4848+ async def size(self) -> int:
4949+ result = await self._capnp_file.size()
5050+ return result.size
5151+5252+ # FIXME: Find a better type than Any
5353+ async def read(self, offset: int = 0, len: int = 0xFFFFFFFFFFFFFFFF) -> Any:
5454+ result = await self._capnp_file.read(offset, len)
5555+ return result.data