Package: py-choria-external
py-mco-agentOverviewpy-choria-externalimplements the Choria External communications' protocol so that External Choria functions can be
written in the Python language.InstallationThis library is typically pulled in as a dependency by other packages and is not useful on its own.pip install py-choria-externalThis library requires a version of Choria with external agent support (0.12.1+)Related projectsFor real-world usages of this library, see also:py-mco-agentImplementsChoria External Agentpy-choria-discoveryImplementsChoria External DiscoveryImplementing new Choria External functionality using this libraryTo implement support for a new Choria External function of type "Example"
create a python package with the following directory layoutchoria_example/
├──schemas/
│  ├── io.choria.choria.example.v1.external_request.json
│  └── io.choria.choria.example.v1.external_reply.json
├── __init__.py
├── example.py
└── protocol.pySchemasThese are copies of the relevantChoria Schema files.protocol.pyThe classes in this file implement the message handling. TheRequestclass is populated with the
schema-validated data from an incoming RPC request. TheReplyclass encapsulates the response which
is validated against the reply schema before being sent back.importjsonfromchoria_external.protocolimportProtocolMessage,Reply@ProtocolMessage.register_protocol()classExampleRequest(ProtocolMessage):""" """_protocol='io.choria.choria.example.v1.external_request'@staticmethoddefcreate_reply():returnExampleReply()classExampleReply(Reply):""" Describes the response to an Example Choria External requestHandles serialisation of the response object"""_protocol='io.choria.choria.example.v1.external_reply'def__init__(self,*args,**kwargs):super().__init__(*args,**kwargs)# The following instance variables contain the data that will be returned# in the reply, as defined by the reply schemaself.statuscode=0self.data={}defto_json(self):""" Serialises this reply object into JSON format to be sent back to ChoriaThe return value of this method is validated against the reply schema and mustbe well formed for the reply to be sent back correctly. Malformed responses willresult in an error being presented back to the client."""returnjson.dumps({'data':self.data,'statuscode':self.statuscode,})deffail(self):""" Marks the reply as failed.How that looks depends on the schema in use. Typically this sets an `error`field to a non-empty string, or sets a statuscode field to a non-zero number"""self.statuscode=1defsuccessful(self):""" Exposes whether this request was successful or not"""returnself.statuscode==0example.pyThis file defined the base class for any concrete implementations of the Example external function.
In the simplest case, this might be an empty class. Seepy-mco-agentfor a more complex example.# Ensure the Protocol Messages are loaded and registeredimportchoria_example.protocolfromchoria_external.baseimportChoriaExternalclassExample(ChoriaExternal):""" Base class for implementations of the Example Choria External function"""defexample(self):""" Implement the example actionThis method should be overridden by subclasses"""passdefexecute(self):self.example()Concrete ImplementationThis is an example concrete implementation. This script is what choria itself would be configured to execute.fromchoria_external.dispatcherimportdispatchfromchoria_example.exampleimportExampleclassSimpleExample(Example):defexample(self):self.reply.data={"hello":"world"}if__name__=='__main__':dispatch(SimpleExample)