Skip to content

Commit 4ff63a8

Browse files
xncz8hivokroskinskijp
authored
Add fin-python-library page to docs (#127)
Co-authored-by: kroskinskiis <[email protected]> Co-authored-by: jp <[email protected]>
1 parent 6b413ec commit 4ff63a8

File tree

1 file changed

+244
-0
lines changed

1 file changed

+244
-0
lines changed
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
---
2+
title: Fin Python Library
3+
description: >
4+
Documentation of the Python Fin library
5+
categories: [extensions, architecture]
6+
tags: [fin, python]
7+
weight: 2
8+
date: 2024-04-10
9+
---
10+
11+
For the documentation about the Fin protocol we refer to documention page of [SOARCA Fin Protocol](https://cossas.github.io/SOARCA/docs/soarca-extensions/fin-protocol/).
12+
13+
## Quick Start
14+
15+
To include the SOARCA Fin library, you can use the following command to install it via pip:
16+
17+
```bash
18+
pip install soarca-fin-library
19+
```
20+
21+
### Example
22+
An example on how to use the library is given below.
23+
For more examples and the source code, we will refer to the Github page of the [SOARCA-Fin-python-library](https://github.com/COSSAS/SOARCA-FIN-python-library), where we provide `/examples` folder.
24+
25+
```python
26+
import os
27+
from dotenv import load_dotenv
28+
29+
from soarca_fin_python_library.soarca_fin import SoarcaFin
30+
from soarca_fin_python_library.models.agent_structure import AgentStructure
31+
from soarca_fin_python_library.models.external_reference import ExternalReference
32+
from soarca_fin_python_library.models.step_structure import StepStructure
33+
from soarca_fin_python_library.models.capability_structure import CapabilityStructure
34+
from soarca_fin_python_library.enums.workflow_step_enum import WorkFlowStepEnum
35+
from soarca_fin_python_library.models.command import Command
36+
from soarca_fin_python_library.models.result_structure import ResultStructure
37+
38+
from soarca_fin_python_library.models.variable import Variable
39+
from soarca_fin_python_library.enums.variable_type_enum import VariableTypeEnum
40+
41+
42+
def capability_pong_callback(command: Command) -> ResultStructure:
43+
print("Received ping, returning pong!")
44+
45+
result = Variable(
46+
type=VariableTypeEnum.string,
47+
name="pong_output",
48+
description="If ping, return pong",
49+
value="pong",
50+
constant=True,
51+
external=False)
52+
53+
context = command.command.context
54+
55+
return ResultStructure(
56+
state="success", context=context, variables={"result": result})
57+
58+
59+
def main(mqtt_broker: str, mqtt_port: int, username: str, password: str) -> None:
60+
61+
finId = "soarca-fin--pingpong-f877bb3a-bb37-429e-8ece-2d4286cf326d"
62+
agentName = "soarca-fin-pong-f896bb3b-bb37-429e-8ece-2d4286cf326d"
63+
externalReferenceName = "external-reference-example-name"
64+
capabilityId = "mod-pong--e896aa3b-bb37-429e-8ece-2d4286cf326d"
65+
66+
# Create AgentStructure
67+
agent = AgentStructure(
68+
name=agentName)
69+
70+
# Create ExternalReference
71+
external_reference = ExternalReference(name=externalReferenceName)
72+
73+
# Create StepStructure
74+
step_structure = StepStructure(
75+
name="step_name",
76+
description="step description",
77+
external_references=[external_reference],
78+
command="pong",
79+
target=agentName)
80+
81+
# Create CapabilityStructure
82+
capability_structure = CapabilityStructure(
83+
capability_id=capabilityId,
84+
type=WorkFlowStepEnum.action,
85+
name="Ping Pong capability",
86+
version="0.0.1",
87+
step={
88+
"test": step_structure},
89+
agent={
90+
"testagent": agent})
91+
92+
# Create Soarca fin
93+
fin = SoarcaFin(finId)
94+
# Set config for MQTT Server
95+
fin.set_config_MQTT_server(mqtt_broker, mqtt_port, username, password)
96+
# Register Capabilities
97+
fin.create_fin_capability(capability_structure, capability_pong_callback)
98+
# Start the fin
99+
fin.start_fin()
100+
101+
102+
if __name__ == "__main__":
103+
load_dotenv()
104+
MQTT_BROKER = os.getenv("MQTT_BROKER", "localhost")
105+
MQTT_PORT = int(os.getenv("MQTT_PORT", "1883"))
106+
USERNAME = os.getenv("MQTT_USERNAME", "soarca")
107+
PASSWD = os.getenv("MQTT_PASSWD", "password")
108+
109+
main(MQTT_BROKER, MQTT_PORT, USERNAME, PASSWD)
110+
111+
```
112+
113+
Below we have provided an example env file. Note that this changes according to your setup.
114+
115+
```
116+
MQTT_BROKER = "localhost"
117+
MQTT_PORT = "1883"
118+
MQTT_USERNAME = "soarca"
119+
MQTT_PASSWD = "password"
120+
```
121+
122+
Env file can be exported by running:
123+
```bash
124+
export $(cat .env | grep -v "#" | xargs)
125+
```
126+
127+
## Architecture
128+
The main object of the application is the `SoarcaFin` object, which is responsible for configuring and creating and controlling the capabilities.
129+
The SoarcaFin creates `MQTTClient`s for each capability registered, plus one for registering, unregistering and controlling the fi itself.
130+
`MQTTClient`s each have their own connection to the MQTT Broker and own `Parser` and `Executor` objects.
131+
The `Parser` object parsers the raw MQTT messages and tries to convert them to one of the objects in `src/models`.
132+
The `Executor` runs in their own thread and handles the actual execution of the messages.
133+
The `Executor` polls a thread-safe queue for new messages and performs IO operations, such as sending messages to the MQTT broker and calling capability callbacks.
134+
135+
### Setup SOARCA Capabilities
136+
137+
138+
To register a fin to SOARCA, first create a `SoarcaFin` object and pass the `fin_id` in the constructor. The SOARCA `fin_id` must be in the format of: `sourca-fin-<capability>-<uuid4>`.
139+
Call `set_config_MQTT_server()` to set the required configurations for the fin to connect to the MQTT broker.
140+
For each capability to be registered, call `create_fin_capability()`. The capability callback funtion should return an object of type `ResultStructure`.
141+
When all capabilities are initialized, call `start_fin()` for the SOARCA Fin to connect to the MQTT broker and register itself to SOARCA.
142+
143+
An example is given in this project in the file [`examples/pong_example.py`]
144+
145+
### Class Overview
146+
```plantuml
147+
interface IParser {
148+
Message parse_on_message()
149+
}
150+
151+
interface IMQTTClient {
152+
void on_connect()
153+
void on_message()
154+
}
155+
156+
interface ISoarcaFin {
157+
void set_config_MQTTServer()
158+
void set_fin_capabilities()
159+
void start_fin()
160+
}
161+
162+
interface IExecutor {
163+
void queue_message()
164+
}
165+
166+
167+
class SoarcaFin
168+
class MQTTClient
169+
class Parser
170+
class Executor
171+
172+
ISoarcaFin <|.. SoarcaFin
173+
IMQTTClient <|.. MQTTClient
174+
IParser <|.. Parser
175+
IExecutor <|.. Executor
176+
177+
IMQTTClient <- SoarcaFin
178+
MQTTClient -> IExecutor
179+
IParser <-MQTTClient
180+
```
181+
182+
### Sequence Diagrams
183+
#### Command
184+
```plantuml
185+
Soarca -> "MQTTClient (Capability 1)" : Command Message [Capability ID Topic]
186+
187+
"MQTTClient (Capability 1)" -> Parser : parse_on_message(message)
188+
"MQTTClient (Capability 1)" <-- Parser : Message.Command
189+
190+
"MQTTClient (Capability 1)" -> "Executor (Capability 1)" : Command message
191+
Soarca <-- "Executor (Capability 1)" : Ack
192+
193+
"Executor (Capability 1)" -> "Capability Callback" : Command
194+
"Executor (Capability 1)" <-- "Capability Callback" : Result
195+
196+
197+
Soarca <- "Executor (Capability 1)" : Result
198+
Soarca --> "MQTTClient (Capability 1)" : Ack
199+
200+
"MQTTClient (Capability 1)" -> Parser : parse_on_message(message)
201+
"MQTTClient (Capability 1)" <-- Parser : Message.Ack
202+
203+
"MQTTClient (Capability 1)" -> "Executor (Capability 1)" : Ack message
204+
```
205+
206+
#### Register
207+
```plantuml
208+
Soarca -> Soarca : Create Soarca Topic
209+
210+
Library -> SoarcaFin : Set MQTT Server config
211+
212+
Library -> SoarcaFin : Set Capability1
213+
SoarcaFin -> "MQTTClient (Capability 1)" : Create capability
214+
215+
Library -> SoarcaFin : Set Capability2
216+
SoarcaFin -> "MQTTClient (Capability 2)" : Create capability
217+
218+
219+
Library -> SoarcaFin : Start Fin
220+
221+
222+
SoarcaFin -> "MQTTClient (Capability 1)" : Start capability
223+
"MQTTClient (Capability 1)" -> "MQTTClient (Capability 1)" : Register Capability Topic
224+
SoarcaFin -> "MQTTClient (Capability 2)" : Start capability
225+
"MQTTClient (Capability 2)" -> "MQTTClient (Capability 2)" : Register Capability Topic
226+
227+
SoarcaFin -> "MQTTClient (Fin)" : Register Fin
228+
"MQTTClient (Fin)" -> "MQTTClient (Fin)" : Register SoarcaFin Topic
229+
230+
"MQTTClient (Fin)" -> "Executor (Fin)" : Send Register Message
231+
232+
Soarca <- "Executor (Fin)" : Message.Register [Soarca Topic]
233+
234+
Soarca --> "MQTTClient (Fin)" : Message.Ack [Fin ID Topic]
235+
236+
"MQTTClient (Fin)" -> "Parser (Fin)" : parse_on_message(ack)
237+
"MQTTClient (Fin)" <-- "Parser (Fin)" : Message.Ack
238+
239+
"MQTTClient (Fin)" -> "Executor (Fin)" : Message.Ack
240+
```
241+
242+
## Bugs or Contributing
243+
Want to contribute to this project? It is possible to contribute [here](https://github.com/COSSAS/SOARCA-FIN-python-library).
244+
Have you found a bug or want to request a feature? Please create an issue [here](https://github.com/COSSAS/SOARCA-FIN-python-library/issues).

0 commit comments

Comments
 (0)