Skip to content

Latest commit

 

History

History
96 lines (75 loc) · 3.17 KB

README.md

File metadata and controls

96 lines (75 loc) · 3.17 KB

aioredis-rpc

ci coverage pypi downloads versions license

A RPC interface using aioredis and pydantic.

Usage

pip install aioredis-rpc

pydantic is used to model complex objects which are transparently serialized and packed into messages using msgpack.

# Define Pydantic models
class FileData(BaseModel):
  filename: str
  data: bytes

Define a class using the @endpoint decorator to specify which methods will be accessible via rpc.

from redisrpc import endpoint

# Define an RPC class
class Dropbox:
  files: Dict[str, FileData]
  max_files: int

  def __init__(self, max_files: int = 1000):
    self.files = dict()
    self.max_files = max_files

  @endpoint
  async def upload_file(self, file: FileData) -> int:
    if len(self.files) >= self.max_files:
      # Errors are propagated to the client-side
      raise Exception('too many files')
    self.files[file.name] = file
    return len(file.data)

  @endpoint
  def get_file_names(self) -> List[str]:
    return list(self.files.keys())

  @endpoint
  async def download_file(self, name: str) -> FileData:
    return self.files[name]

Use the create_server function to make an instance of your server-side rpc class. The server instance will be assigned an rpc attribute to access server functions like connect and disconnect. Once connect is called methods decorated with @endpoint will be invoked automatically by remote calls from the client.

NOTE: The RpcProvider.connect method is non-blocking.

server = create_server(Dropbox, max_files=2)
# Returns once connected to redis
await server.rpc.connect(dsn="redis://localhost")
# Wait forever
while True:
  await asyncio.sleep(1)

The create_client function create a faux instance of the rpc class with only the methods decorated by @endpoint present. When these methods are called by the client the function arguments are serialized and published to redis.

NOTE: If there are no subscribers to the redis channel then the client will throw a RpcNotConnectedError.

client = create_client(Dropbox)
await client.rpc.connect(dsn="redis://localhost")

Now that both ends are connected the @endpoint decorated methods may be called like they are accessing the actual class passed to create_client.

file1 = FileData(name='file1', data=b'1234')
size = await client.upload_file(file1)