Connection provides an interface for the agent to connect with entities in the outside world. Connections wrap SDKs or APIs and provide interfaces to networks, ledgers and other services. As such, a connection is concerned with I/O bound and continuously connected operations. Where necessary, a connection is responsible for translating between the framework specific protocol (an
Envelope with its contained
Message) and the external service or third-party protocol (e.g.
HTTP). Hence, there are two roles for connections: wrapper and transport connection. The transport connection is responsible to delivering AEA envelopes.
The messages constructed or received by a connection are eventually processed by one or several skills which deal with handling and generating messages related to a specific business objective.
AEA can interact with multiple connections at the same time via the
Multiplexer. Connections are passive in terms of multiplexer interactions (its methods are called by the Multiplexer), but they can run their own asynchronous or threaded tasks.
Developing your connection
The easiest way to get started developing your own connection is by using the scaffold command:
aea scaffold connection my_new_connection
This will scaffold a connection package called
my_new_connection with three files:
connection.pycontaining the scaffolded connection class
connection.yamlcontaining the scaffolded configuration file
As a developer you have the choice between implementing a sync or asynchronous interface. The scaffolded
connection.py file contains two classes: the
MyScaffoldAsyncConnection inherited from the
Connection base class and the
MyScaffoldSyncConnection inherited from the
BaseSyncConnection. Remove the unused class.
Primary methods to develop - asynchronous connection interface
The developer needs to implement four public coroutines:
connectcoroutine implements the setup logic required to be performed for the connection when it is initially launched. The
connectcoroutine is called by the AEA framework once when the agent is being started.
disconnectcoroutine implements the teardown logic required to be performed for the connection when it is eventually stopped. The
disconnectcoroutine is called by the AEA framework once when the agent is being stopped.
sendcoroutine is called by the AEA framework each time the
Multiplexerhandles an outgoing envelope specified to be handled by this connection. The
sendcoroutine must implement the processing of the envelope leaving the agent.
receivecoroutine is continuously called by the AEA framework. It either returns
Noneor an envelope. The
receivecoroutine must implement the logic of data being received by the agent, and if necessary, its translation into a relevant protocol.
The framework provides a demo
stub connection which implements an I/O reader and writer to send and receive messages between the agent and a local file. To gain inspiration and become familiar with the structure of connection packages, you may find it useful to check out
valory/http_client:0.23.0 connections. The latter two connections are for external clients to connect with an agent, and for the agent to connect with external servers, respectively.
Primary methods to develop - sync connection interface
BaseSyncConnection uses executors to execute synchronous code from the asynchronous context of the
Multiplexer in executors/threads, which are limited by the amount of configured workers.
The asynchronous methods
send are converted to callbacks which the developer implements:
All of these methods will be executed in the executor pool.
Every method can create a message by putting it into the thread/asynchronous friendly queue that is consumed by the
receive coroutine has no direct equivalent. Instead, the developer implements a
main method which runs synchronously in the background.
Every connection must have a configuration file in
connection.yaml, containing meta-information about the connection as well as all the required configuration details. For more details, have a look here.
connection.yaml file contains a number of fields that must be edited by the developer of the connection:
connectionsspecifies the list of other connection this connection depends on
protocolsspecifies the list of protocols this connection depends on
class_nameneeds to match the name of the connection class in
configcan contain arbitrary configuration information which is made available in the constructor of the connection as keyword arguments (
excluded_protocolslists the protocols which cannot be used in this connection
restricted_to_protocolslists the protocols which this connection is restricted to be used by
dependencieslists any Python dependencies of the connection package
is_abstractspecifies whether this connection is only used as an abstract base class
cert_requestslists certification requests of the connection (see proof of representation for details)