Pythonic bi-directional RPC API built on top of ØMQ.

ticosax ticosax Last update: Jun 10, 2022

pseud

Continues IntegrationCoverage StatusDocumentation Status

Pythonic bidirectional-rpc API built on top of ØMQ with pluggableencryption, authentication and heartbeating support.

Features

  1. ØMQ transport layer.
  2. All native python types supported (msgpack).
  3. First citizen exceptions.
  4. Bi-bidirectional (server can initiate calls to connected clients).
  5. Encryption based on CURVE.
  6. Pluggable Authentication.
  7. Pluggable Heartbeating.
  8. Pluggable Remote Call Routing.
  9. Built-in proxy support. A server can delegate the work to another one.
  10. SyncClient (using zmq.REQ) to use within non event based processes.(Heartbeating, Authentication and job execution are not supported withthe SyncClient.)

Installation

$ pip install pseud

Execution

The Server

from pseud import Serverserver = Server('service')server.bind('tcp://127.0.0.1:5555')@server.register_rpcdef hello(name):    return 'Hello {0}'.format(name)await server.start()  # this will block forever

The Client

from pseud import Clientclient = Client('service', io_loop=loop)client.connect('tcp://127.0.0.1:5555')# Assume we are inside a coroutineasync with client:    response = await client.hello('Charly')    assert response == 'Hello Charly'

The SyncClient

# to use within a non-asynchronous process or in a command interpreterfrom pseud import SyncClientclient = SyncClient()client.connect('tcp://127.0.0.1:5555')assert client.hello('Charly') == 'Hello Charly'

The Server send a command to the client

It is important to note that the server needs to know whichpeers are connected to it.This is why the security_plugin trusted_peer comes handy.It will register all peer id and be able to route messages to each of them.

from pseud import Serverserver = Server('service', security_plugin='trusted_peer')server.bind('tcp://127.0.0.1:5555')@server.register_rpcdef hello(name):    return 'Hello {0}'.format(name)await server.start()  # this will block forever

The client needs to send its identity to the server. This is why plainsecurity plugin is used. The server will not check the password, he will justtake into consideration the user_id to perform the routing.

from pseud import Clientclient = Client('service',                security_plugin='plain',                user_id='alice',                password='')client.connect('tcp://127.0.0.1:5555')# Action that the client will perform when# requested by the server.@client.register_rpc(name='draw.me.a.sheep')def sheep():    return 'beeeh'

Back on server side, we can send to it any commands the client is able to do.

# assume we are inside a coroutinesheep = await server.send_to('alice').draw.me.a.sheep()assert sheep == 'beeeh'

Documentation

Pseud on Readthedocs

Subscribe to our newsletter