Skip to main content

Asynchronous RPC via UDP

Project description

RPCUDP : RPC over UDP in Python

Build Status

RPC over UDP may seem like a silly idea, but things like the DHT Kademlia require it. This project is specifically designed for asynchronous Python 3 code to accept and send remote proceedure calls.

Because of the use of UDP, you will not always know whether or not a procedure call was successfully received. This isn't considered an exception state in the library, though you will know if a response isn't received by the server in a configurable amount of time.

Installation

pip install rpcudp

Usage

This assumes you have a working familiarity with asyncio.

First, let's make a server that accepts a remote procedure call and spin it up.

import asyncio
from rpcudp.protocol import RPCProtocol


class RPCServer(RPCProtocol):
    # Any methods starting with "rpc_" are available to clients.
    def rpc_sayhi(self, sender, name):
        # This could return a Deferred as well. sender is (ip,port)
        return "Hello %s you live at %s:%i" % (name, sender[0], sender[1])

# start a server on UDP port 1234
loop = asyncio.get_event_loop()
listen = loop.create_datagram_endpoint(RPCServer, local_addr=('127.0.0.1', 1234))
transport, protocol = loop.run_until_complete(listen)
loop.run_forever()

Now, let's make a client script. Note that we do need to specify a port for the client as well, since it needs to listen for responses to RPC calls on a UDP port.

import asyncio
from rpcudp.protocol import RPCProtocol


@asyncio.coroutine
def sayhi(protocol, address):
    # result will be a tuple - first arg is a boolean indicating whether a response
    # was received, and the second argument is the response if one was received.
    result = yield from protocol.sayhi(address, "Snake Plissken")
    print(result[1] if result[0] else "No response received.")


# Start local UDP server to be able to handle responses
loop = asyncio.get_event_loop()
listen = loop.create_datagram_endpoint(RPCProtocol, local_addr=('127.0.0.1', 4567))
transport, protocol = loop.run_until_complete(listen)

# Call remote UDP server to say hi
func = sayhi(protocol, ('127.0.0.1', 1234))
loop.run_until_complete(func)
loop.run_forever()

You can run this example in the examples folder (client.py and server.py).

Logging

This library uses the standard Python logging library. To see debut output printed to STDOUT, for instance, use:

import logging

log = logging.getLogger('rpcudp')
log.setLevel(logging.DEBUG)
log.addHandler(logging.StreamHandler())

Running Tests

To run tests:

pip install -r dev-requirements.txt
python -m unittest

Implementation Details

The protocol is designed to be as small and fast as possible. Python objects are serialized using MsgPack. All calls must fit within 8K (generally small enough to fit in one datagram packet).

Compatibility

With version 2.0 compatibility is broken with previous versions. In version 2.0 the method name when making a remote call is always packed as a unicode string. In previous versions, the type of string that method name was depended on the Python version. In order to make instances running on Python 2 (only versions before 3.0 worked with Python 2) and Python 3 compatible with each other the method name is now encoded as a unicode string before being packed, which ensures that u-msgpack-python will always pack the it the same way. See u-msgpack-python#behaviour-notes for more information.

If you intend to have instances running on both Python 2 and Python 3 communicating with each other make sure that all strings in the arguments you send are unicode encoded as well to ensure compatibility.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rpcudp-4.0.0.tar.gz (5.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rpcudp-4.0.0-py3-none-any.whl (6.8 kB view details)

Uploaded Python 3

File details

Details for the file rpcudp-4.0.0.tar.gz.

File metadata

  • Download URL: rpcudp-4.0.0.tar.gz
  • Upload date:
  • Size: 5.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

File hashes

Hashes for rpcudp-4.0.0.tar.gz
Algorithm Hash digest
SHA256 2960cb91f5e4c9dec43b4a6a96857d5474edbfc00abd2b63a6d29fc9761c326c
MD5 078b098f9a803bd9ebc9c893e500b077
BLAKE2b-256 cfc977e1d5d353a0ee96f1375bf82dc5fbf6c26d64aa43e922196a3a2da7b4a0

See more details on using hashes here.

File details

Details for the file rpcudp-4.0.0-py3-none-any.whl.

File metadata

  • Download URL: rpcudp-4.0.0-py3-none-any.whl
  • Upload date:
  • Size: 6.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

File hashes

Hashes for rpcudp-4.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bffdd5c87b660821134c62169f405b6640275fa0e9d6f053f3ec640b364b7925
MD5 16454bfaf8ed20d45b4e1873694bfc10
BLAKE2b-256 41b99e817b28f245a7ca76e46fcf3080bb1890f2e86db17daf32ae0d57946083

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page