lewis.core.control_server

This module contains classes to expose objects via a JSON-RPC over ZMQ server. Lewis uses this infrastructure in Simulation.

See also

Client classes for the service defined in this module can be found in control_client.

Members

ControlServer

This server opens a ZMQ REP-socket at the given host and port when start_server is called.

ExposedObject

ExposedObject is a class that makes it easy to expose an object via the JSONRPCResponseManager from the json-rpc package, where it can serve as a dispatcher.

ExposedObjectCollection

This class helps expose a number of objects (plain or RPCObject) by exposing the methods of each object as

class lewis.core.control_server.ControlServer(object_map, connection_string)[source]

Bases: object

This server opens a ZMQ REP-socket at the given host and port when start_server is called.

The server constructs an ExposedObjectCollection from the supplied name: object-dictionary and uses that as a handler for JSON-RPC requests. If it is an instance of ExposedObject, that is used directly.

Each time process is called, the server tries to get request data and responds to that. If there is no data, the method does nothing.

Please note that this RPC-service comes without any security, authentication, etc. Only use it to expose objects on a trusted network and be aware that anyone on that network can access the exposed objects without any restrictions.

Parameters:
  • object_map – Dictionary with name: object-pairs to construct an ExposedObjectCollection or ExposedObject

  • connection_string – String with host:port pair for binding control server.

property exposed_object

The exposed object. This is a read only property.

property is_running

This property is True if the server is running.

process(blocking=False) None[source]

Each time this method is called, the socket tries to retrieve data and passes it to the JSONRPCResponseManager, which in turn passes the RPC to the ExposedObjectCollection.

In case no data are available, the method does nothing. This behavior is required for Lewis where everything is running in one thread. The central loop can call process at some point to process remote calls, so the RPC-server does not introduce its own infinite processing loop.

If the server has not been started yet (via start_server()), a RuntimeError is raised.

Parameters:

blocking – If True, this function will block until it has received data or a timeout is triggered. Default is False to preserve behavior of prior versions.

start_server() None[source]

Binds the server to the configured host and port and starts listening.

class lewis.core.control_server.ExposedObject(obj, members=None, exclude=None, exclude_inherited=False, lock=None)[source]

Bases: object

ExposedObject is a class that makes it easy to expose an object via the JSONRPCResponseManager from the json-rpc package, where it can serve as a dispatcher. For this purpose it exposes a read-only dict-like interface.

The basic problem solved by this wrapper is that plain data members of an object are not really captured well by the RPC-approach, where a client performs function calls on a remote machine and gets the result back.

The supplied object is inspected using dir(object) and all entries that do not start with a _ are exposed in a way that depends on whether the corresponding member is a method or a property (either in the Python-sense or the general OO-sense). Methods are stored directly, and stored in an internal dict where the method name is the key and the callable method object is the value. For properties, a getter- and a setter function are generated, which are then stored in the same dict. The names of these methods for a property called a are a:get and a:set. The separator has been chosen to be colon because it can’t be part of a valid Python identifier.

If the second argument is not empty, it is interpreted to be the list of members to expose and only those are actually exposed. This can be used to explicitly expose members of an object that start with an underscore. If all but one or two members should be exposed, it’s also possible to use the exclude-argument to explicitly exclude a few members. Both parameters can be used in combination, the exclude-list takes precedence.

In certain situations it is desirable to acquire a lock before accessing the exposed object, for example when multiple threads are accessing it on the server side. For this purpose, the lock-parameter can be used. If it is not None, the exposed methods are wrapped in a function that acquires the lock before accessing obj, and releases it afterwards.

Parameters:
  • obj – The object to expose.

  • members – This list of methods will be exposed. (defaults to all public members)

  • exclude – Members in this list will not be exposed.

  • exclude_inherited – Should inherited members be excluded? (defaults to False)

  • lockthreading.Lock that is used when accessing obj.

get_api()[source]

This method returns the class name and a list of exposed methods. It is exposed to RPC-clients by an instance of ExposedObjectCollection.

Returns:

A dictionary describing the exposed API (consisting of a class name and methods).

class lewis.core.control_server.ExposedObjectCollection(named_objects)[source]

Bases: ExposedObject

This class helps expose a number of objects (plain or RPCObject) by exposing the methods of each object as

name.method

Furthermore it exposes each object’s API as a method with the following name:

name: api

A list of exposed objects can be obtained by calling the following method from the client:

:objects
Parameters:

named_objects – Dictionary of of name: object pairs.

add_object(obj, name) None[source]

Adds the supplied object to the collection under the supplied name. If the name is already in use, a RuntimeError is raised. If the object is not an instance of ExposedObject, the method automatically constructs one.

Parameters:
  • obj – Object to add to the collection.

  • name – Name of the exposed object.

get_objects()[source]

Returns the names of the exposed objects.

remove_object(name) None[source]

Remove the object exposed under that name. If no object is registered under the supplied name, a RuntimeError is raised.

Parameters:

name – Name of object to be removed.