Skip to main content

RPC proxy framework

Project description

Axon

Axon is a Python RPC-proxy framework that enables developers to host services on edge devices and access them over local networks or the Internet. Axon allows developers to deploy services from the edge, utilizing any available devices on hand, rather than using expensive cloud computing and without opening a port on their network. Moreover, calls to services deployed with Axon are made through developer-friendly RPC proxies that match the interface of the variables being served. Axon can expose services quickly and easily, requiring only a few extra lines of code on top of a service’s core logic.

Installation

pip install axon-ECRG

QuickStart

RPC Decorator

Developers may deploy services by passing Python variables or functions into Axon. The simplest way to expose code to distributed access with Axon is with the rpc decorator:

import axon

@axon.worker.rpc()
def print_msg(msg):
	print(msg)

axon.worker.init()

This function may then be accessed from another machine using a stub object created with the IP address of the machine and the rpc endpoint. Each function in the worker script with the rpc decorator is represented with an attribute on this stub object, since the function print_msg was passed into the rpc decorator, the stub object created from that worker has a callable print_msg attribute. Calling this function on the stub will transmit any parameters to the worker, which will execute the function and transmit the result back to client.

import axon

rpc_stub = axon.client.get_stub("localhost/rpc")
await rpc_stub.print_msg("Hello World!")

Service Function

Axon can be used to expose variables to distributed access with the service function. In the following example worker script, a list is exposed to access from remote machines.

import axon

l = [1,2,3,4,5]
axon.worker.service(l, "list_service")

axon.worker.init()

Clients may create stubs linked to exposed variables using stub objects created with the IP address of the worker machine and an endpoint matching the string passed in with the object. In this example, a stub can be created from the list object by using the list_service endpoint.

import axon

list_stub = axon.client.get_stub("localhost/list_service")
await list_stub.pop() # returns 5
await list_stub[1] # returns 2

Note that the stub object created from the list service has all the attributes of the list function. The .pop() function call in the client example will trigger the execution of the .pop() function on the original list object in the worker script, removing the last element, 5, and transmitting it back to the client as the return value. This also applies for dunder methods like __get_item__, and so normal list indexing works on the stub object by transmitting the index to worker, which transmits back the corresponding list element. Stubs are meant to be code-compatable replacements for the object they represent, where code execution happens on a remote machine instead of locally.

A global stub can be made for a worker by simply using no endpoint. This stub will have attributes that are themselves stubs connected to each service and rpc exposed on that worker.

import axon

stub = axon.client.get_stub("localhost")

await stub.rpc.print_msg("Hello World!")

await stub.list_service.pop() # returns 5
await stub.list_service[1] # returns 2

Concurrency

By default, axon RPC requests return an AsyncResultHandle that allows for concurrent code execution during a request with asyncio. The result of the RPC invocation is obtained by calling using the 'await' keyword on the result handle. Another for option when asyncio is impractical is to call .join():

rpc_stub = axon.client.get_stub("localhost/rpcs")
rpc_stub.print_msg("Hello World!").join()

list_stub = axon.client.get_stub("localhost/list_service")
list_stub.pop().join() # returns 5
list_stub[1].join() # returns 2

When syncronous behavior is desired, developers may pass in a stub_type option to make syncronous calls:

rpc_stub = axon.client.get_stub("localhost/rpcs", stub_type=axon.stubs.SyncStub)
rpc_stub.print_msg("Hello World!")

list_stub = axon.client.get_stub("localhost/list_service", stub_type=axon.stubs.SyncStub)
list_stub.pop() # returns 5
list_stub[1] # returns 2

Torch Module Example

There is a strong case for Axon services to be used to invoke computationally expensive funtions on remote machines in distributed computing enviroments. An example of this would be to host a torch module representing a neural network on a worker machine with a strong GPU, that then runs inferences for remote clients. In that case, the worker script could look like the following:

import axon
import torch
F = torch.nn.functional

class ConvNet(torch.nn.Module):

    def __init__(self):
        super(ConvNet, self).__init__()

        self.conv1 = torch.nn.Conv2d(1, 6, (3, 3))
        self.conv2 = torch.nn.Conv2d(6, 16, (3, 3))
        
        self.fc1 = torch.nn.Linear(400, 200)
        self.fc2 = torch.nn.Linear(200, 100)
        self.fc3 = torch.nn.Linear(100, 10)

    def forward(self, x):
        
        x = self.conv1(x)
        x = F.relu(x)
        x = F.max_pool2d(x, (2, 2))

        x = F.max_pool2d(F.relu(self.conv2(x)), (2, 2))
        x = x.view(-1, 400)
        
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = F.softmax(self.fc3(x), dim=1)

        return x

net = ConvNet()

axon.worker.register_ServiceNode(net, 'conv_serv', depth=1)

print('serving!')
axon.worker.init()

And a client that accesses this service:

import torch
import axon

x = torch.randn([32, 1, 28, 28])
net = axon.client.get_ServiceStub('localhost/conv_serv', stub_type=axon.stubs.SyncStub)
y = net(x)

Edge Hosting Capability

Axon allows developers to host services on local devices while exposing them to access from anywhere in the world. Normally, local networks block incoming TCP connection requests, keeping user devices safe from the threats of the public internet. Anyone wishing to offer worldwide access to a service on a local device would need to open a port on their router; a significant security consideration. Axon workers may take service requests through a pre-established connection to a trusted third party on the internet, known as a reflector. The reflector would then take requests from clients on the worker's behalf, and pass them down to the worker through this connection.

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

axon_ecrg-0.2.4.tar.gz (21.6 kB view details)

Uploaded Source

Built Distribution

axon_ECRG-0.2.4-py3-none-any.whl (27.4 kB view details)

Uploaded Python 3

File details

Details for the file axon_ecrg-0.2.4.tar.gz.

File metadata

  • Download URL: axon_ecrg-0.2.4.tar.gz
  • Upload date:
  • Size: 21.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.3

File hashes

Hashes for axon_ecrg-0.2.4.tar.gz
Algorithm Hash digest
SHA256 4fd49d868bebd16e52e55e22b937ac7adc42ac0283df24dab858cd547232f878
MD5 3576a8a251a14c41939bf800b8fa294c
BLAKE2b-256 92cc7322957162bff73607e5c961b8f7b7edbe597480e80f65357ebce807d86b

See more details on using hashes here.

File details

Details for the file axon_ECRG-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: axon_ECRG-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 27.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.3

File hashes

Hashes for axon_ECRG-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 b121d310e25da3ae271dfa7e0e7b9526df2a9b92ea4e94f5da6d3b432986c67e
MD5 eb39df4fc02660cb53f6ce4ee25c1e39
BLAKE2b-256 e526eba36e3c3f53c2a8ec103b0ea61fdc22a5354c2c9bc0fa0267917654d955

See more details on using hashes here.

Supported by

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